@@ -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
@@ -141,19 +143,6 @@ static void platform_message_handler_free(gpointer data) {
141
143
g_free (self);
142
144
}
143
145
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
-
157
146
static gboolean fl_binary_messenger_platform_message_cb (
158
147
FlEngine* engine,
159
148
const gchar* channel,
@@ -179,11 +168,7 @@ static gboolean fl_binary_messenger_platform_message_cb(
179
168
180
169
static void fl_binary_messenger_impl_dispose (GObject* object) {
181
170
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 );
187
172
188
173
g_clear_pointer (&self->platform_message_handlers , g_hash_table_unref);
189
174
@@ -199,7 +184,8 @@ static void set_message_handler_on_channel(
199
184
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
200
185
201
186
// 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 ) {
203
189
if (handler != nullptr ) {
204
190
g_warning (
205
191
" Attempted to set message handler on an FlBinaryMessenger without an "
@@ -220,6 +206,12 @@ static void set_message_handler_on_channel(
220
206
}
221
207
}
222
208
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.
223
215
static gboolean send_response (FlBinaryMessenger* messenger,
224
216
FlBinaryMessengerResponseHandle* response_handle_,
225
217
GBytes* response,
@@ -233,21 +225,27 @@ static gboolean send_response(FlBinaryMessenger* messenger,
233
225
g_return_val_if_fail (response_handle->messenger == self, FALSE );
234
226
g_return_val_if_fail (response_handle->response_handle != nullptr , FALSE );
235
227
236
- if (self->engine == nullptr ) {
228
+ FlEngine* engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
229
+ if (engine == nullptr ) {
237
230
return TRUE ;
238
231
}
239
232
233
+ gboolean result = false ;
240
234
if (response_handle->response_handle == nullptr ) {
241
235
g_set_error (
242
236
error, FL_BINARY_MESSENGER_ERROR,
243
237
FL_BINARY_MESSENGER_ERROR_ALREADY_RESPONDED,
244
238
" 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 ;
246
244
}
247
245
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) ;
251
249
252
250
return result;
253
251
}
@@ -267,12 +265,13 @@ static void send_on_channel(FlBinaryMessenger* messenger,
267
265
gpointer user_data) {
268
266
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL (messenger);
269
267
270
- if (self->engine == nullptr ) {
268
+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
269
+ if (engine == nullptr ) {
271
270
return ;
272
271
}
273
272
274
273
fl_engine_send_platform_message (
275
- self-> engine , channel, message, cancellable,
274
+ engine, channel, message, cancellable,
276
275
callback != nullptr ? platform_message_ready_cb : nullptr ,
277
276
callback != nullptr ? g_task_new (self, cancellable, callback, user_data)
278
277
: nullptr );
@@ -287,11 +286,12 @@ static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
287
286
g_autoptr (GTask) task = G_TASK (result);
288
287
GAsyncResult* r = G_ASYNC_RESULT (g_task_propagate_pointer (task, nullptr ));
289
288
290
- if (self->engine == nullptr ) {
289
+ g_autoptr (FlEngine) engine = FL_ENGINE (g_weak_ref_get (&self->engine ));
290
+ if (engine == nullptr ) {
291
291
return nullptr ;
292
292
}
293
293
294
- return fl_engine_send_platform_message_finish (self-> engine , r, error);
294
+ return fl_engine_send_platform_message_finish (engine, r, error);
295
295
}
296
296
297
297
static void fl_binary_messenger_impl_class_init (
@@ -321,8 +321,7 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
321
321
// Added to stop compiler complaining about an unused function.
322
322
FL_IS_BINARY_MESSENGER_IMPL (self);
323
323
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));
326
325
327
326
fl_engine_set_platform_message_handler (
328
327
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(
343
342
self, channel, handler, user_data, destroy_notify);
344
343
}
345
344
345
+ // Note: This function can be called from any thread.
346
346
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response (
347
347
FlBinaryMessenger* self,
348
348
FlBinaryMessengerResponseHandle* response_handle,
0 commit comments