@@ -106,6 +106,10 @@ struct AOTDataDeleter {
106
106
};
107
107
108
108
using UniqueAotDataPtr = std::unique_ptr<_FlutterEngineAOTData, AOTDataDeleter>;
109
+ // / Maintains one ref on the FlutterDesktopMessenger's internal reference count.
110
+ using FlutterDesktopMessengerReferenceOwner =
111
+ std::unique_ptr<FlutterDesktopMessenger,
112
+ decltype (&FlutterDesktopMessengerRelease)>;
109
113
110
114
// Struct for storing state of a Flutter engine instance.
111
115
struct FlutterDesktopEngineState {
@@ -116,7 +120,8 @@ struct FlutterDesktopEngineState {
116
120
std::unique_ptr<flutter::EventLoop> event_loop;
117
121
118
122
// The plugin messenger handle given to API clients.
119
- std::unique_ptr<FlutterDesktopMessenger> messenger;
123
+ FlutterDesktopMessengerReferenceOwner messenger = {
124
+ nullptr , [](FlutterDesktopMessengerRef ref) {}};
120
125
121
126
// Message dispatch manager for messages from the Flutter engine.
122
127
std::unique_ptr<flutter::IncomingMessageDispatcher> message_dispatcher;
@@ -149,10 +154,75 @@ struct FlutterDesktopPluginRegistrar {
149
154
150
155
// State associated with the messenger used to communicate with the engine.
151
156
struct FlutterDesktopMessenger {
157
+ FlutterDesktopMessenger () = default ;
158
+
159
+ // / Increments the reference count.
160
+ // /
161
+ // / Thread-safe.
162
+ void AddRef () { ref_count_.fetch_add (1 ); }
163
+
164
+ // / Decrements the reference count and deletes the object if the count has
165
+ // / gone to zero.
166
+ // /
167
+ // / Thread-safe.
168
+ void Release () {
169
+ int32_t old_count = ref_count_.fetch_sub (1 );
170
+ if (old_count <= 1 ) {
171
+ delete this ;
172
+ }
173
+ }
174
+
175
+ // / Getter for the engine field.
176
+ FlutterDesktopEngineState* GetEngine () const { return engine_; }
177
+
178
+ // / Setter for the engine field.
179
+ // / Thread-safe.
180
+ void SetEngine (FlutterDesktopEngineState* engine) {
181
+ std::scoped_lock lock (mutex_);
182
+ engine_ = engine;
183
+ }
184
+
185
+ // / Returns the mutex associated with the |FlutterDesktopMessenger|.
186
+ // /
187
+ // / This mutex is used to synchronize reading or writing state inside the
188
+ // / |FlutterDesktopMessenger| (ie |engine_|).
189
+ std::mutex& GetMutex () { return mutex_; }
190
+
191
+ FlutterDesktopMessenger (const FlutterDesktopMessenger& value) = delete ;
192
+ FlutterDesktopMessenger& operator =(const FlutterDesktopMessenger& value) =
193
+ delete ;
194
+
195
+ private:
152
196
// The engine that backs this messenger.
153
- FlutterDesktopEngineState* engine;
197
+ FlutterDesktopEngineState* engine_;
198
+ std::atomic<int32_t > ref_count_ = 0 ;
199
+ std::mutex mutex_;
154
200
};
155
201
202
+ FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef (
203
+ FlutterDesktopMessengerRef messenger) {
204
+ messenger->AddRef ();
205
+ return messenger;
206
+ }
207
+
208
+ void FlutterDesktopMessengerRelease (FlutterDesktopMessengerRef messenger) {
209
+ messenger->Release ();
210
+ }
211
+
212
+ bool FlutterDesktopMessengerIsAvailable (FlutterDesktopMessengerRef messenger) {
213
+ return messenger->GetEngine () != nullptr ;
214
+ }
215
+
216
+ FlutterDesktopMessengerRef FlutterDesktopMessengerLock (
217
+ FlutterDesktopMessengerRef messenger) {
218
+ messenger->GetMutex ().lock ();
219
+ return messenger;
220
+ }
221
+
222
+ void FlutterDesktopMessengerUnlock (FlutterDesktopMessengerRef messenger) {
223
+ messenger->GetMutex ().unlock ();
224
+ }
225
+
156
226
// Retrieves state bag for the window in question from the GLFWWindow.
157
227
static FlutterDesktopWindowControllerState* GetWindowController (
158
228
GLFWwindow* window) {
@@ -743,8 +813,10 @@ static void SetUpLocales(FlutterDesktopEngineState* state) {
743
813
static void SetUpCommonEngineState (FlutterDesktopEngineState* state,
744
814
GLFWwindow* window) {
745
815
// Messaging.
746
- state->messenger = std::make_unique<FlutterDesktopMessenger>();
747
- state->messenger ->engine = state;
816
+ state->messenger = FlutterDesktopMessengerReferenceOwner (
817
+ FlutterDesktopMessengerAddRef (new FlutterDesktopMessenger ()),
818
+ &FlutterDesktopMessengerRelease);
819
+ state->messenger ->SetEngine (state);
748
820
state->message_dispatcher =
749
821
std::make_unique<flutter::IncomingMessageDispatcher>(
750
822
state->messenger .get ());
@@ -846,6 +918,7 @@ FlutterDesktopWindowControllerRef FlutterDesktopCreateWindow(
846
918
}
847
919
848
920
void FlutterDesktopDestroyWindow (FlutterDesktopWindowControllerRef controller) {
921
+ controller->engine ->messenger ->SetEngine (nullptr );
849
922
FlutterDesktopPluginRegistrarRef registrar =
850
923
controller->engine ->plugin_registrar .get ();
851
924
if (registrar->destruction_handler ) {
@@ -1045,7 +1118,8 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
1045
1118
FlutterPlatformMessageResponseHandle* response_handle = nullptr ;
1046
1119
if (reply != nullptr && user_data != nullptr ) {
1047
1120
FlutterEngineResult result = FlutterPlatformMessageCreateResponseHandle (
1048
- messenger->engine ->flutter_engine , reply, user_data, &response_handle);
1121
+ messenger->GetEngine ()->flutter_engine , reply, user_data,
1122
+ &response_handle);
1049
1123
if (result != kSuccess ) {
1050
1124
std::cout << " Failed to create response handle\n " ;
1051
1125
return false ;
@@ -1061,11 +1135,11 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
1061
1135
};
1062
1136
1063
1137
FlutterEngineResult message_result = FlutterEngineSendPlatformMessage (
1064
- messenger->engine ->flutter_engine , &platform_message);
1138
+ messenger->GetEngine () ->flutter_engine , &platform_message);
1065
1139
1066
1140
if (response_handle != nullptr ) {
1067
1141
FlutterPlatformMessageReleaseResponseHandle (
1068
- messenger->engine ->flutter_engine , response_handle);
1142
+ messenger->GetEngine () ->flutter_engine , response_handle);
1069
1143
}
1070
1144
1071
1145
return message_result == kSuccess ;
@@ -1084,16 +1158,16 @@ void FlutterDesktopMessengerSendResponse(
1084
1158
const FlutterDesktopMessageResponseHandle* handle,
1085
1159
const uint8_t * data,
1086
1160
size_t data_length) {
1087
- FlutterEngineSendPlatformMessageResponse (messenger-> engine -> flutter_engine ,
1088
- handle, data, data_length);
1161
+ FlutterEngineSendPlatformMessageResponse (
1162
+ messenger-> GetEngine ()-> flutter_engine , handle, data, data_length);
1089
1163
}
1090
1164
1091
1165
void FlutterDesktopMessengerSetCallback (FlutterDesktopMessengerRef messenger,
1092
1166
const char * channel,
1093
1167
FlutterDesktopMessageCallback callback,
1094
1168
void * user_data) {
1095
- messenger->engine ->message_dispatcher ->SetMessageCallback (channel, callback,
1096
- user_data);
1169
+ messenger->GetEngine () ->message_dispatcher ->SetMessageCallback (
1170
+ channel, callback, user_data);
1097
1171
}
1098
1172
1099
1173
FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar (
0 commit comments