@@ -33,7 +33,7 @@ G_DEFINE_INTERFACE(FlBinaryMessenger, fl_binary_messenger, G_TYPE_OBJECT)
3333struct _FlBinaryMessengerImpl {
3434 GObject parent_instance;
3535
36- FlEngine* engine;
36+ GWeakRef engine;
3737
3838 // PlatformMessageHandler keyed by channel name.
3939 GHashTable* platform_message_handlers;
@@ -81,7 +81,9 @@ static void fl_binary_messenger_response_handle_impl_dispose(GObject* object) {
8181 FlBinaryMessengerResponseHandleImpl* self =
8282 FL_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL (object);
8383
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 ) {
8587 g_critical (" FlBinaryMessengerResponseHandle was not responded to" );
8688 }
8789
@@ -144,7 +146,6 @@ static void platform_message_handler_free(gpointer data) {
144146static void engine_weak_notify_cb (gpointer user_data,
145147 GObject* where_the_object_was) {
146148 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (user_data);
147- self->engine = nullptr ;
148149
149150 // Disconnect any handlers.
150151 // Take the reference in case a handler tries to modify this table.
@@ -180,11 +181,15 @@ static gboolean fl_binary_messenger_platform_message_cb(
180181static void fl_binary_messenger_impl_dispose (GObject* object) {
181182 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (object);
182183
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+ }
186189 }
187190
191+ g_weak_ref_clear (&self->engine );
192+
188193 g_clear_pointer (&self->platform_message_handlers , g_hash_table_unref);
189194
190195 G_OBJECT_CLASS (fl_binary_messenger_impl_parent_class)->dispose (object);
@@ -199,7 +204,8 @@ static void set_message_handler_on_channel(
199204 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
200205
201206 // 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 ) {
203209 if (handler != nullptr ) {
204210 g_warning (
205211 " Attempted to set message handler on an FlBinaryMessenger without an "
@@ -220,6 +226,12 @@ static void set_message_handler_on_channel(
220226 }
221227}
222228
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.
223235static gboolean send_response (FlBinaryMessenger* messenger,
224236 FlBinaryMessengerResponseHandle* response_handle_,
225237 GBytes* response,
@@ -233,21 +245,27 @@ static gboolean send_response(FlBinaryMessenger* messenger,
233245 g_return_val_if_fail (response_handle->messenger == self, FALSE );
234246 g_return_val_if_fail (response_handle->response_handle != nullptr , FALSE );
235247
236- if (self->engine == nullptr ) {
248+ FlEngine* engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
249+ if (engine == nullptr ) {
237250 return TRUE ;
238251 }
239252
253+ gboolean result = false ;
240254 if (response_handle->response_handle == nullptr ) {
241255 g_set_error (
242256 error, FL_BINARY_MESSENGER_ERROR,
243257 FL_BINARY_MESSENGER_ERROR_ALREADY_RESPONDED,
244258 " 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 ;
246264 }
247265
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) ;
251269
252270 return result;
253271}
@@ -267,12 +285,13 @@ static void send_on_channel(FlBinaryMessenger* messenger,
267285 gpointer user_data) {
268286 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
269287
270- if (self->engine == nullptr ) {
288+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
289+ if (engine == nullptr ) {
271290 return ;
272291 }
273292
274293 fl_engine_send_platform_message (
275- self-> engine , channel, message, cancellable,
294+ engine, channel, message, cancellable,
276295 callback != nullptr ? platform_message_ready_cb : nullptr ,
277296 callback != nullptr ? g_task_new (self, cancellable, callback, user_data)
278297 : nullptr );
@@ -287,11 +306,12 @@ static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
287306 g_autoptr (GTask) task = G_TASK (result);
288307 GAsyncResult* r = G_ASYNC_RESULT (g_task_propagate_pointer (task, nullptr ));
289308
290- if (self->engine == nullptr ) {
309+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
310+ if (engine == nullptr ) {
291311 return nullptr ;
292312 }
293313
294- return fl_engine_send_platform_message_finish (self-> engine , r, error);
314+ return fl_engine_send_platform_message_finish (engine, r, error);
295315}
296316
297317static void fl_binary_messenger_impl_class_init (
@@ -321,7 +341,7 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
321341 // Added to stop compiler complaining about an unused function.
322342 FL_IS_BINARY_MESSENGER_IMPL (self);
323343
324- self->engine = engine;
344+ g_weak_ref_init (& self->engine , G_OBJECT ( engine)) ;
325345 g_object_weak_ref (G_OBJECT (engine), engine_weak_notify_cb, self);
326346
327347 fl_engine_set_platform_message_handler (
@@ -343,6 +363,7 @@ G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
343363 self, channel, handler, user_data, destroy_notify);
344364}
345365
366+ // Note: This function can be called from any thread.
346367G_MODULE_EXPORT gboolean fl_binary_messenger_send_response (
347368 FlBinaryMessenger* self,
348369 FlBinaryMessengerResponseHandle* response_handle,
0 commit comments