@@ -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
@@ -141,19 +143,6 @@ static void platform_message_handler_free(gpointer data) {
141143 g_free (self);
142144}
143145
144- static void engine_weak_notify_cb (gpointer user_data,
145- GObject* where_the_object_was) {
146- FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (user_data);
147- self->engine = nullptr ;
148-
149- // Disconnect any handlers.
150- // Take the reference in case a handler tries to modify this table.
151- g_autoptr (GHashTable) handlers = self->platform_message_handlers ;
152- self->platform_message_handlers = g_hash_table_new_full (
153- g_str_hash, g_str_equal, g_free, platform_message_handler_free);
154- g_hash_table_remove_all (handlers);
155- }
156-
157146static gboolean fl_binary_messenger_platform_message_cb (
158147 FlEngine* engine,
159148 const gchar* channel,
@@ -179,11 +168,7 @@ static gboolean fl_binary_messenger_platform_message_cb(
179168
180169static void fl_binary_messenger_impl_dispose (GObject* object) {
181170 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (object);
182-
183- if (self->engine != nullptr ) {
184- g_object_weak_unref (G_OBJECT (self->engine ), engine_weak_notify_cb, self);
185- self->engine = nullptr ;
186- }
171+ g_weak_ref_clear (&self->engine );
187172
188173 g_clear_pointer (&self->platform_message_handlers , g_hash_table_unref);
189174
@@ -199,7 +184,8 @@ static void set_message_handler_on_channel(
199184 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
200185
201186 // Don't set handlers if engine already gone.
202- if (self->engine == nullptr ) {
187+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
188+ if (engine == nullptr ) {
203189 if (handler != nullptr ) {
204190 g_warning (
205191 " Attempted to set message handler on an FlBinaryMessenger without an "
@@ -220,6 +206,12 @@ static void set_message_handler_on_channel(
220206 }
221207}
222208
209+ gboolean do_unref (gpointer value) {
210+ g_object_unref (value);
211+ return G_SOURCE_REMOVE;
212+ }
213+
214+ // Note: This function can be called from any thread.
223215static gboolean send_response (FlBinaryMessenger* messenger,
224216 FlBinaryMessengerResponseHandle* response_handle_,
225217 GBytes* response,
@@ -233,21 +225,27 @@ static gboolean send_response(FlBinaryMessenger* messenger,
233225 g_return_val_if_fail (response_handle->messenger == self, FALSE );
234226 g_return_val_if_fail (response_handle->response_handle != nullptr , FALSE );
235227
236- if (self->engine == nullptr ) {
228+ FlEngine* engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
229+ if (engine == nullptr ) {
237230 return TRUE ;
238231 }
239232
233+ gboolean result = false ;
240234 if (response_handle->response_handle == nullptr ) {
241235 g_set_error (
242236 error, FL_BINARY_MESSENGER_ERROR,
243237 FL_BINARY_MESSENGER_ERROR_ALREADY_RESPONDED,
244238 " Attempted to respond to a message that is already responded to" );
245- return FALSE ;
239+ result = FALSE ;
240+ } else {
241+ result = fl_engine_send_platform_message_response (
242+ engine, response_handle->response_handle , response, error);
243+ response_handle->response_handle = nullptr ;
246244 }
247245
248- gboolean result = fl_engine_send_platform_message_response (
249- self-> engine , response_handle-> response_handle , response, error);
250- response_handle-> response_handle = nullptr ;
246+ // This guarantees that the dispose method for the engine is executed
247+ // on the platform thread in the rare chance this is the last ref.
248+ g_idle_add (do_unref, engine) ;
251249
252250 return result;
253251}
@@ -267,12 +265,13 @@ static void send_on_channel(FlBinaryMessenger* messenger,
267265 gpointer user_data) {
268266 FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
269267
270- if (self->engine == nullptr ) {
268+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
269+ if (engine == nullptr ) {
271270 return ;
272271 }
273272
274273 fl_engine_send_platform_message (
275- self-> engine , channel, message, cancellable,
274+ engine, channel, message, cancellable,
276275 callback != nullptr ? platform_message_ready_cb : nullptr ,
277276 callback != nullptr ? g_task_new (self, cancellable, callback, user_data)
278277 : nullptr );
@@ -287,11 +286,12 @@ static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
287286 g_autoptr (GTask) task = G_TASK (result);
288287 GAsyncResult* r = G_ASYNC_RESULT (g_task_propagate_pointer (task, nullptr ));
289288
290- if (self->engine == nullptr ) {
289+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
290+ if (engine == nullptr ) {
291291 return nullptr ;
292292 }
293293
294- return fl_engine_send_platform_message_finish (self-> engine , r, error);
294+ return fl_engine_send_platform_message_finish (engine, r, error);
295295}
296296
297297static void fl_binary_messenger_impl_class_init (
@@ -321,8 +321,7 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
321321 // Added to stop compiler complaining about an unused function.
322322 FL_IS_BINARY_MESSENGER_IMPL (self);
323323
324- self->engine = engine;
325- g_object_weak_ref (G_OBJECT (engine), engine_weak_notify_cb, self);
324+ g_weak_ref_init (&self->engine , G_OBJECT (engine));
326325
327326 fl_engine_set_platform_message_handler (
328327 engine, fl_binary_messenger_platform_message_cb, self, NULL );
@@ -343,6 +342,7 @@ G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
343342 self, channel, handler, user_data, destroy_notify);
344343}
345344
345+ // Note: This function can be called from any thread.
346346G_MODULE_EXPORT gboolean fl_binary_messenger_send_response (
347347 FlBinaryMessenger* self,
348348 FlBinaryMessengerResponseHandle* response_handle,
0 commit comments