@@ -33,7 +33,7 @@ G_DEFINE_INTERFACE(FlBinaryMessenger, fl_binary_messenger, G_TYPE_OBJECT)
33
33
struct _FlBinaryMessengerImpl {
34
34
GObject parent_instance;
35
35
36
- FlEngine* engine;
36
+ GWeakRef engine;
37
37
38
38
// PlatformMessageHandler keyed by channel name.
39
39
GHashTable* platform_message_handlers;
@@ -81,7 +81,9 @@ static void fl_binary_messenger_response_handle_impl_dispose(GObject* object) {
81
81
FlBinaryMessengerResponseHandleImpl* self =
82
82
FL_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL (object);
83
83
84
- if (self->response_handle != nullptr && self->messenger ->engine != nullptr ) {
84
+ g_autoptr (FlEngine) engine =
85
+ FL_ENGINE (g_weak_ref_get (&self->messenger ->engine ));
86
+ if (self->response_handle != nullptr && engine != nullptr ) {
85
87
g_critical (" FlBinaryMessengerResponseHandle was not responded to" );
86
88
}
87
89
@@ -144,7 +146,6 @@ static void platform_message_handler_free(gpointer data) {
144
146
static void engine_weak_notify_cb (gpointer user_data,
145
147
GObject* where_the_object_was) {
146
148
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (user_data);
147
- self->engine = nullptr ;
148
149
149
150
// Disconnect any handlers.
150
151
// Take the reference in case a handler tries to modify this table.
@@ -180,11 +181,15 @@ static gboolean fl_binary_messenger_platform_message_cb(
180
181
static void fl_binary_messenger_impl_dispose (GObject* object) {
181
182
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (object);
182
183
183
- if (self->engine != nullptr ) {
184
- g_object_weak_unref (G_OBJECT (self->engine ), engine_weak_notify_cb, self);
185
- self->engine = nullptr ;
184
+ {
185
+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
186
+ if (engine) {
187
+ g_object_weak_unref (G_OBJECT (engine), engine_weak_notify_cb, self);
188
+ }
186
189
}
187
190
191
+ g_weak_ref_clear (&self->engine );
192
+
188
193
g_clear_pointer (&self->platform_message_handlers , g_hash_table_unref);
189
194
190
195
G_OBJECT_CLASS (fl_binary_messenger_impl_parent_class)->dispose (object);
@@ -199,7 +204,8 @@ static void set_message_handler_on_channel(
199
204
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
200
205
201
206
// Don't set handlers if engine already gone.
202
- if (self->engine == nullptr ) {
207
+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
208
+ if (engine == nullptr ) {
203
209
if (handler != nullptr ) {
204
210
g_warning (
205
211
" Attempted to set message handler on an FlBinaryMessenger without an "
@@ -220,6 +226,12 @@ static void set_message_handler_on_channel(
220
226
}
221
227
}
222
228
229
+ static gboolean do_unref (gpointer value) {
230
+ g_object_unref (value);
231
+ return G_SOURCE_REMOVE;
232
+ }
233
+
234
+ // Note: This function can be called from any thread.
223
235
static gboolean send_response (FlBinaryMessenger* messenger,
224
236
FlBinaryMessengerResponseHandle* response_handle_,
225
237
GBytes* response,
@@ -233,21 +245,27 @@ static gboolean send_response(FlBinaryMessenger* messenger,
233
245
g_return_val_if_fail (response_handle->messenger == self, FALSE );
234
246
g_return_val_if_fail (response_handle->response_handle != nullptr , FALSE );
235
247
236
- if (self->engine == nullptr ) {
248
+ FlEngine* engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
249
+ if (engine == nullptr ) {
237
250
return TRUE ;
238
251
}
239
252
253
+ gboolean result = false ;
240
254
if (response_handle->response_handle == nullptr ) {
241
255
g_set_error (
242
256
error, FL_BINARY_MESSENGER_ERROR,
243
257
FL_BINARY_MESSENGER_ERROR_ALREADY_RESPONDED,
244
258
" Attempted to respond to a message that is already responded to" );
245
- return FALSE ;
259
+ result = FALSE ;
260
+ } else {
261
+ result = fl_engine_send_platform_message_response (
262
+ engine, response_handle->response_handle , response, error);
263
+ response_handle->response_handle = nullptr ;
246
264
}
247
265
248
- gboolean result = fl_engine_send_platform_message_response (
249
- self-> engine , response_handle-> response_handle , response, error);
250
- response_handle-> response_handle = nullptr ;
266
+ // This guarantees that the dispose method for the engine is executed
267
+ // on the platform thread in the rare chance this is the last ref.
268
+ g_idle_add (do_unref, engine) ;
251
269
252
270
return result;
253
271
}
@@ -267,12 +285,13 @@ static void send_on_channel(FlBinaryMessenger* messenger,
267
285
gpointer user_data) {
268
286
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
269
287
270
- if (self->engine == nullptr ) {
288
+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
289
+ if (engine == nullptr ) {
271
290
return ;
272
291
}
273
292
274
293
fl_engine_send_platform_message (
275
- self-> engine , channel, message, cancellable,
294
+ engine, channel, message, cancellable,
276
295
callback != nullptr ? platform_message_ready_cb : nullptr ,
277
296
callback != nullptr ? g_task_new (self, cancellable, callback, user_data)
278
297
: nullptr );
@@ -287,11 +306,12 @@ static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
287
306
g_autoptr (GTask) task = G_TASK (result);
288
307
GAsyncResult* r = G_ASYNC_RESULT (g_task_propagate_pointer (task, nullptr ));
289
308
290
- if (self->engine == nullptr ) {
309
+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
310
+ if (engine == nullptr ) {
291
311
return nullptr ;
292
312
}
293
313
294
- return fl_engine_send_platform_message_finish (self-> engine , r, error);
314
+ return fl_engine_send_platform_message_finish (engine, r, error);
295
315
}
296
316
297
317
static void fl_binary_messenger_impl_class_init (
@@ -321,7 +341,7 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
321
341
// Added to stop compiler complaining about an unused function.
322
342
FL_IS_BINARY_MESSENGER_IMPL (self);
323
343
324
- self->engine = engine;
344
+ g_weak_ref_init (& self->engine , G_OBJECT ( engine)) ;
325
345
g_object_weak_ref (G_OBJECT (engine), engine_weak_notify_cb, self);
326
346
327
347
fl_engine_set_platform_message_handler (
@@ -343,6 +363,7 @@ G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
343
363
self, channel, handler, user_data, destroy_notify);
344
364
}
345
365
366
+ // Note: This function can be called from any thread.
346
367
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response (
347
368
FlBinaryMessenger* self,
348
369
FlBinaryMessengerResponseHandle* response_handle,
0 commit comments