----- Original Message ----- > 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; Why take a gpointer user_data and not signal_data instead? I find the name "run_in_idle" a bit wrong, I would rather name it signal_idle_add or something like that. > + > + 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 > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel