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

Christophe Fergeau cfergeau at redhat.com
Mon Feb 23 02:55:46 PST 2015


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



More information about the Spice-devel mailing list