[Spice-devel] [spice-gtk 1/3] gio-coroutine: Factor common code

Marc-André Lureau mlureau at redhat.com
Mon Feb 23 03:19:46 PST 2015



----- 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list