[glib/glib-2-38] gmain: make g_source_add_child_source() thread safe



commit 1a0ad835daa645103f38d9f02024941bb2103fd5
Author: Ognyan Tonchev <ognyan axis com>
Date:   Tue Oct 29 16:39:38 2013 +0100

    gmain: make g_source_add_child_source() thread safe
    
    g_source_add_child_source() releases the context lock before attaching
    child_source to context. And this causes trouble if parent source is
    blocked and g_main_dispatch() manages to lock the context mutex and call
    unblock_source() before child_source gets attached to context.
    To fix this we call g_source_attach_unlocked() before releasing the
    context mutex.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711064

 glib/gmain.c |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 738e69c..ed7a9e8 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -1110,7 +1110,8 @@ assign_source_id_unlocked (GMainContext   *context,
 
 static guint
 g_source_attach_unlocked (GSource      *source,
-                         GMainContext *context)
+                          GMainContext *context,
+                          gboolean      do_wakeup)
 {
   GSList *tmp_list;
 
@@ -1135,10 +1136,16 @@ g_source_attach_unlocked (GSource      *source,
   tmp_list = source->priv->child_sources;
   while (tmp_list)
     {
-      g_source_attach_unlocked (tmp_list->data, context);
+      g_source_attach_unlocked (tmp_list->data, context, FALSE);
       tmp_list = tmp_list->next;
     }
 
+  /* If another thread has acquired the context, wake it up since it
+   * might be in poll() right now.
+   */
+  if (do_wakeup && context->owner && context->owner != G_THREAD_SELF)
+    g_wakeup_signal (context->wakeup);
+
   return source->source_id;
 }
 
@@ -1167,13 +1174,7 @@ g_source_attach (GSource      *source,
 
   LOCK_CONTEXT (context);
 
-  result = g_source_attach_unlocked (source, context);
-
-  /* If another thread has acquired the context, wake it up since it
-   * might be in poll() right now.
-   */
-  if (context->owner && context->owner != G_THREAD_SELF)
-    g_wakeup_signal (context->wakeup);
+  result = g_source_attach_unlocked (source, context, TRUE);
 
   UNLOCK_CONTEXT (context);
 
@@ -1432,8 +1433,8 @@ g_source_add_child_source (GSource *source,
 
   if (context)
     {
+      g_source_attach_unlocked (child_source, context, TRUE);
       UNLOCK_CONTEXT (context);
-      g_source_attach (child_source, context);
     }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]