Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 225ca5f

Browse files
committed
Implemented threadsafe platform channel replies on windows
1 parent 04fa86e commit 225ca5f

File tree

8 files changed

+143
-11
lines changed

8 files changed

+143
-11
lines changed

shell/platform/common/client_wrapper/core_implementations.cc

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,30 @@ void ForwardToHandler(FlutterDesktopMessengerRef messenger,
3636
const FlutterDesktopMessage* message,
3737
void* user_data) {
3838
auto* response_handle = message->response_handle;
39-
BinaryReply reply_handler = [messenger, response_handle](
39+
auto messenger_ptr = std::shared_ptr<FlutterDesktopMessenger>(
40+
FlutterDesktopMessengerAddRef(messenger),
41+
&FlutterDesktopMessengerRelease);
42+
BinaryReply reply_handler = [messenger_ptr, response_handle](
4043
const uint8_t* reply,
4144
size_t reply_size) mutable {
45+
auto lock = std::unique_ptr<FlutterDesktopMessenger,
46+
decltype(&FlutterDesktopMessengerUnlock)>(
47+
FlutterDesktopMessengerLock(messenger_ptr.get()),
48+
&FlutterDesktopMessengerUnlock);
49+
if (!FlutterDesktopMessengerIsAvailable(messenger_ptr.get())) {
50+
std::cerr << "Error: Responding to platform channel after the engine has"
51+
"been deleted."
52+
<< std::endl;
53+
return;
54+
}
4255
if (!response_handle) {
4356
std::cerr << "Error: Response can be set only once. Ignoring "
4457
"duplicate response."
4558
<< std::endl;
4659
return;
4760
}
48-
FlutterDesktopMessengerSendResponse(messenger, response_handle, reply,
49-
reply_size);
61+
FlutterDesktopMessengerSendResponse(messenger_ptr.get(), response_handle,
62+
reply, reply_size);
5063
// The engine frees the response handle once
5164
// FlutterDesktopSendMessageResponse is called.
5265
response_handle = nullptr;

shell/platform/common/client_wrapper/testing/stub_flutter_api.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "flutter/shell/platform/common/client_wrapper/testing/stub_flutter_api.h"
66

7+
#include <cassert>
8+
79
static flutter::testing::StubFlutterApi* s_stub_implementation;
810

911
namespace flutter {
@@ -93,6 +95,31 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
9395
}
9496
}
9597

98+
FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef(
99+
FlutterDesktopMessengerRef messenger) {
100+
assert(false); // not implemented
101+
return nullptr;
102+
}
103+
104+
void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger) {
105+
assert(false); // not implemented
106+
}
107+
108+
bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger) {
109+
assert(false); // not implemented
110+
return false;
111+
}
112+
113+
FlutterDesktopMessengerRef FlutterDesktopMessengerLock(
114+
FlutterDesktopMessengerRef messenger) {
115+
assert(false); // not implemented
116+
return nullptr;
117+
}
118+
119+
void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger) {
120+
assert(false); // not implemented
121+
}
122+
96123
FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar(
97124
FlutterDesktopPluginRegistrarRef registrar) {
98125
return reinterpret_cast<FlutterDesktopTextureRegistrarRef>(1);

shell/platform/common/public/flutter_messenger.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
66
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
77

8+
#include <stdbool.h>
89
#include <stddef.h>
910
#include <stdint.h>
1011

@@ -87,6 +88,21 @@ FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback(
8788
FlutterDesktopMessageCallback callback,
8889
void* user_data);
8990

91+
FLUTTER_EXPORT FlutterDesktopMessengerRef
92+
FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger);
93+
94+
FLUTTER_EXPORT void FlutterDesktopMessengerRelease(
95+
FlutterDesktopMessengerRef messenger);
96+
97+
FLUTTER_EXPORT bool FlutterDesktopMessengerIsAvailable(
98+
FlutterDesktopMessengerRef messenger);
99+
100+
FLUTTER_EXPORT FlutterDesktopMessengerRef
101+
FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger);
102+
103+
FLUTTER_EXPORT void FlutterDesktopMessengerUnlock(
104+
FlutterDesktopMessengerRef messenger);
105+
90106
#if defined(__cplusplus)
91107
} // extern "C"
92108
#endif

shell/platform/glfw/flutter_glfw.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,31 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
10961096
user_data);
10971097
}
10981098

1099+
FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef(
1100+
FlutterDesktopMessengerRef messenger) {
1101+
assert(false); // not implemented
1102+
return nullptr;
1103+
}
1104+
1105+
void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger) {
1106+
assert(false); // not implemented
1107+
}
1108+
1109+
bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger) {
1110+
assert(false); // not implemented
1111+
return false;
1112+
}
1113+
1114+
FlutterDesktopMessengerRef FlutterDesktopMessengerLock(
1115+
FlutterDesktopMessengerRef messenger) {
1116+
assert(false); // not implemented
1117+
return nullptr;
1118+
}
1119+
1120+
void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger) {
1121+
assert(false); // not implemented
1122+
}
1123+
10991124
FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar(
11001125
FlutterDesktopPluginRegistrarRef registrar) {
11011126
std::cerr << "GLFW Texture support is not implemented yet." << std::endl;

shell/platform/windows/flutter_windows.cc

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
262262
const size_t message_size,
263263
const FlutterDesktopBinaryReply reply,
264264
void* user_data) {
265-
return messenger->engine->SendPlatformMessage(channel, message, message_size,
266-
reply, user_data);
265+
return messenger->GetEngine()->SendPlatformMessage(
266+
channel, message, message_size, reply, user_data);
267267
}
268268

269269
bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger,
@@ -279,15 +279,39 @@ void FlutterDesktopMessengerSendResponse(
279279
const FlutterDesktopMessageResponseHandle* handle,
280280
const uint8_t* data,
281281
size_t data_length) {
282-
messenger->engine->SendPlatformMessageResponse(handle, data, data_length);
282+
messenger->GetEngine()->SendPlatformMessageResponse(handle, data,
283+
data_length);
283284
}
284285

285286
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
286287
const char* channel,
287288
FlutterDesktopMessageCallback callback,
288289
void* user_data) {
289-
messenger->engine->message_dispatcher()->SetMessageCallback(channel, callback,
290-
user_data);
290+
messenger->GetEngine()->message_dispatcher()->SetMessageCallback(
291+
channel, callback, user_data);
292+
}
293+
294+
FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef(
295+
FlutterDesktopMessengerRef messenger) {
296+
return messenger->AddRef();
297+
}
298+
299+
void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger) {
300+
messenger->Release();
301+
}
302+
303+
bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger) {
304+
return messenger->GetEngine() != nullptr;
305+
}
306+
307+
FlutterDesktopMessengerRef FlutterDesktopMessengerLock(
308+
FlutterDesktopMessengerRef messenger) {
309+
messenger->GetMutex().lock();
310+
return messenger;
311+
}
312+
313+
void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger) {
314+
messenger->GetMutex().unlock();
291315
}
292316

293317
FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar(

shell/platform/windows/flutter_windows_engine.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,9 @@ FlutterWindowsEngine::FlutterWindowsEngine(
175175
});
176176

177177
// Set up the legacy structs backing the API handles.
178-
messenger_ = std::make_unique<FlutterDesktopMessenger>();
179-
messenger_->engine = this;
178+
messenger_ =
179+
fml::RefPtr<FlutterDesktopMessenger>(new FlutterDesktopMessenger());
180+
messenger_->SetEngine(this);
180181
plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
181182
plugin_registrar_->engine = this;
182183

@@ -198,6 +199,7 @@ FlutterWindowsEngine::FlutterWindowsEngine(
198199
}
199200

200201
FlutterWindowsEngine::~FlutterWindowsEngine() {
202+
messenger_->SetEngine(nullptr);
201203
Stop();
202204
}
203205

shell/platform/windows/flutter_windows_engine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class FlutterWindowsEngine {
271271
std::unique_ptr<TaskRunner> task_runner_;
272272

273273
// The plugin messenger handle given to API clients.
274-
std::unique_ptr<FlutterDesktopMessenger> messenger_;
274+
fml::RefPtr<FlutterDesktopMessenger> messenger_;
275275

276276
// A wrapper around messenger_ for interacting with client_wrapper-level APIs.
277277
std::unique_ptr<BinaryMessengerImpl> messenger_wrapper_;

shell/platform/windows/window_state.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOW_STATE_H_
66
#define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOW_STATE_H_
77

8+
#include <mutex>
9+
810
#include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h"
911
#include "flutter/shell/platform/common/incoming_message_dispatcher.h"
1012
#include "flutter/shell/platform/embedder/embedder.h"
@@ -36,8 +38,31 @@ struct FlutterDesktopPluginRegistrar {
3638
// Wrapper to distinguish the messenger ref from the engine ref given out
3739
// in the C API.
3840
struct FlutterDesktopMessenger {
41+
public:
42+
FlutterDesktopMessenger() = default;
43+
flutter::FlutterWindowsEngine* GetEngine() const { return engine; }
44+
void SetEngine(flutter::FlutterWindowsEngine* arg_engine) {
45+
std::scoped_lock lock(mutex_);
46+
engine = arg_engine;
47+
}
48+
FlutterDesktopMessenger* AddRef() {
49+
ref_count_.fetch_add(1);
50+
return this;
51+
}
52+
void Release() {
53+
int32_t old_count = ref_count_.fetch_sub(1);
54+
if (old_count <= 1) {
55+
delete this;
56+
}
57+
}
58+
std::mutex& GetMutex() { return mutex_; }
59+
60+
private:
61+
FML_DISALLOW_COPY_AND_ASSIGN(FlutterDesktopMessenger);
3962
// The engine that owns this state object.
4063
flutter::FlutterWindowsEngine* engine = nullptr;
64+
std::mutex mutex_;
65+
std::atomic<int32_t> ref_count_ = 0;
4166
};
4267

4368
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOW_STATE_H_

0 commit comments

Comments
 (0)