This commit adds a run_in_idle() helper which contains the common code to queue signal emission/notification in an idle when g_coroutine_signal_emit()/g_coroutine_object_notify() are run from coroutine context. --- gtk/gio-coroutine.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/gtk/gio-coroutine.c b/gtk/gio-coroutine.c index c866e15..1458d05 100644 --- a/gtk/gio-coroutine.c +++ b/gtk/gio-coroutine.c @@ -206,6 +206,24 @@ static gboolean emit_main_context(gpointer opaque) return FALSE; } +static void +run_in_idle(GSourceFunc idle_callback, gpointer user_data) +{ + struct signal_data *data = (struct signal_data *)user_data; + + g_object_ref(data->instance); + g_idle_add(idle_callback, data); + /* This switches to the system coroutine context, lets + * the idle function run to dispatch the signal, and + * finally returns once complete. ie this is synchronous + * from the POV of the coroutine despite there being + * an idle function involved + */ + coroutine_yield(NULL); + g_warn_if_fail(data->notified); + g_object_unref(data->instance); +} + void g_coroutine_signal_emit(gpointer instance, guint signal_id, GQuark detail, ...) @@ -222,11 +240,7 @@ g_coroutine_signal_emit(gpointer instance, guint signal_id, if (coroutine_self_is_main()) { g_signal_emit_valist(instance, signal_id, detail, data.var_args); } else { - g_object_ref(instance); - g_idle_add(emit_main_context, &data); - coroutine_yield(NULL); - g_warn_if_fail(data.notified); - g_object_unref(instance); + run_in_idle(emit_main_context, &data); } va_end (data.var_args); @@ -249,27 +263,15 @@ static gboolean notify_main_context(gpointer opaque) void g_coroutine_object_notify(GObject *object, const gchar *property_name) { - struct signal_data data; + struct signal_data data = { + .instance = object, + .propname = (gpointer)property_name, + .caller = coroutine_self(), + }; if (coroutine_self_is_main()) { g_object_notify(object, property_name); } else { - - data.instance = g_object_ref(object); - data.caller = coroutine_self(); - data.propname = (gpointer)property_name; - data.notified = FALSE; - - g_idle_add(notify_main_context, &data); - - /* This switches to the system coroutine context, lets - * the idle function run to dispatch the signal, and - * finally returns once complete. ie this is synchronous - * from the POV of the coroutine despite there being - * an idle function involved - */ - coroutine_yield(NULL); - g_warn_if_fail(data.notified); - g_object_unref(object); + run_in_idle(notify_main_context, &data); } } -- 2.1.0 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel