Skip to content

Commit

Permalink
Made responses to platform methods threadsafe in linux
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkeaa committed Nov 16, 2022
1 parent 35ecb2b commit 723b3ff
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 29 deletions.
48 changes: 19 additions & 29 deletions shell/platform/linux/fl_binary_messenger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ G_DEFINE_INTERFACE(FlBinaryMessenger, fl_binary_messenger, G_TYPE_OBJECT)
struct _FlBinaryMessengerImpl {
GObject parent_instance;

FlEngine* engine;
GWeakRef engine;

// PlatformMessageHandler keyed by channel name.
GHashTable* platform_message_handlers;
Expand Down Expand Up @@ -81,7 +81,9 @@ static void fl_binary_messenger_response_handle_impl_dispose(GObject* object) {
FlBinaryMessengerResponseHandleImpl* self =
FL_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL(object);

if (self->response_handle != nullptr && self->messenger->engine != nullptr) {
g_autoptr(FlEngine) engine =
FL_ENGINE(g_weak_ref_get(&self->messenger->engine));
if (self->response_handle != nullptr && engine != nullptr) {
g_critical("FlBinaryMessengerResponseHandle was not responded to");
}

Expand Down Expand Up @@ -141,19 +143,6 @@ static void platform_message_handler_free(gpointer data) {
g_free(self);
}

static void engine_weak_notify_cb(gpointer user_data,
GObject* where_the_object_was) {
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(user_data);
self->engine = nullptr;

// Disconnect any handlers.
// Take the reference in case a handler tries to modify this table.
g_autoptr(GHashTable) handlers = self->platform_message_handlers;
self->platform_message_handlers = g_hash_table_new_full(
g_str_hash, g_str_equal, g_free, platform_message_handler_free);
g_hash_table_remove_all(handlers);
}

static gboolean fl_binary_messenger_platform_message_cb(
FlEngine* engine,
const gchar* channel,
Expand All @@ -179,11 +168,7 @@ static gboolean fl_binary_messenger_platform_message_cb(

static void fl_binary_messenger_impl_dispose(GObject* object) {
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(object);

if (self->engine != nullptr) {
g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self);
self->engine = nullptr;
}
g_weak_ref_clear(&self->engine);

g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref);

Expand All @@ -199,7 +184,8 @@ static void set_message_handler_on_channel(
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);

// Don't set handlers if engine already gone.
if (self->engine == nullptr) {
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
if (engine == nullptr) {
if (handler != nullptr) {
g_warning(
"Attempted to set message handler on an FlBinaryMessenger without an "
Expand All @@ -220,6 +206,7 @@ static void set_message_handler_on_channel(
}
}

// Note: This function can be called from any thread.
static gboolean send_response(FlBinaryMessenger* messenger,
FlBinaryMessengerResponseHandle* response_handle_,
GBytes* response,
Expand All @@ -233,7 +220,8 @@ static gboolean send_response(FlBinaryMessenger* messenger,
g_return_val_if_fail(response_handle->messenger == self, FALSE);
g_return_val_if_fail(response_handle->response_handle != nullptr, FALSE);

if (self->engine == nullptr) {
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
if (engine == nullptr) {
return TRUE;
}

Expand All @@ -246,7 +234,7 @@ static gboolean send_response(FlBinaryMessenger* messenger,
}

gboolean result = fl_engine_send_platform_message_response(
self->engine, response_handle->response_handle, response, error);
engine, response_handle->response_handle, response, error);
response_handle->response_handle = nullptr;

return result;
Expand All @@ -267,12 +255,13 @@ static void send_on_channel(FlBinaryMessenger* messenger,
gpointer user_data) {
FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);

if (self->engine == nullptr) {
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
if (engine == nullptr) {
return;
}

fl_engine_send_platform_message(
self->engine, channel, message, cancellable,
engine, channel, message, cancellable,
callback != nullptr ? platform_message_ready_cb : nullptr,
callback != nullptr ? g_task_new(self, cancellable, callback, user_data)
: nullptr);
Expand All @@ -287,11 +276,12 @@ static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
g_autoptr(GTask) task = G_TASK(result);
GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr));

if (self->engine == nullptr) {
g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
if (engine == nullptr) {
return nullptr;
}

return fl_engine_send_platform_message_finish(self->engine, r, error);
return fl_engine_send_platform_message_finish(engine, r, error);
}

static void fl_binary_messenger_impl_class_init(
Expand Down Expand Up @@ -321,8 +311,7 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
// Added to stop compiler complaining about an unused function.
FL_IS_BINARY_MESSENGER_IMPL(self);

self->engine = engine;
g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self);
g_weak_ref_init(&self->engine, G_OBJECT(engine));

fl_engine_set_platform_message_handler(
engine, fl_binary_messenger_platform_message_cb, self, NULL);
Expand All @@ -343,6 +332,7 @@ G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
self, channel, handler, user_data, destroy_notify);
}

// Note: This function can be called from any thread.
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(
FlBinaryMessenger* self,
FlBinaryMessengerResponseHandle* response_handle,
Expand Down
1 change: 1 addition & 0 deletions shell/platform/linux/fl_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ void fl_engine_set_on_pre_engine_restart_handler(
self->on_pre_engine_restart_handler_destroy_notify = destroy_notify;
}

// Note: This function can be called from any thread.
gboolean fl_engine_send_platform_message_response(
FlEngine* self,
const FlutterPlatformMessageResponseHandle* handle,
Expand Down

0 comments on commit 723b3ff

Please sign in to comment.