Blame SOURCES/0001-Use-atomic-reference-counting-for-GSource.patch

2ca4f1
From 2bad3cb3bf8f0cc3f45057061f9a538ecf7742b6 Mon Sep 17 00:00:00 2001
2ca4f1
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
2ca4f1
Date: Thu, 14 Feb 2019 17:46:33 +0200
2ca4f1
Subject: [PATCH 1/5] Use atomic reference counting for GSource
2ca4f1
2ca4f1
If attached to a context already it would use a mutex instead but at
2ca4f1
least before that the reference counting is not thread-safe currently.
2ca4f1
---
2ca4f1
 glib/gmain.c | 50 +++++++++++++++-----------------------------------
2ca4f1
 1 file changed, 15 insertions(+), 35 deletions(-)
2ca4f1
2ca4f1
diff --git a/glib/gmain.c b/glib/gmain.c
2ca4f1
index 26e68823d..5b91c3117 100644
2ca4f1
--- a/glib/gmain.c
2ca4f1
+++ b/glib/gmain.c
2ca4f1
@@ -374,15 +374,6 @@ typedef struct _GSourceIter
2ca4f1
 #define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
2ca4f1
 #define SOURCE_BLOCKED(source) (((source)->flags & G_SOURCE_BLOCKED) != 0)
2ca4f1
 
2ca4f1
-#define SOURCE_UNREF(source, context)                       \
2ca4f1
-   G_STMT_START {                                           \
2ca4f1
-    if ((source)->ref_count > 1)                            \
2ca4f1
-      (source)->ref_count--;                                \
2ca4f1
-    else                                                    \
2ca4f1
-      g_source_unref_internal ((source), (context), TRUE);  \
2ca4f1
-   } G_STMT_END
2ca4f1
-
2ca4f1
-
2ca4f1
 /* Forward declarations */
2ca4f1
 
2ca4f1
 static void g_source_unref_internal             (GSource      *source,
2ca4f1
@@ -977,10 +968,10 @@ g_source_iter_next (GSourceIter *iter, GSource **source)
2ca4f1
    */
2ca4f1
 
2ca4f1
   if (iter->source && iter->may_modify)
2ca4f1
-    SOURCE_UNREF (iter->source, iter->context);
2ca4f1
+    g_source_unref_internal (iter->source, iter->context, TRUE);
2ca4f1
   iter->source = next_source;
2ca4f1
   if (iter->source && iter->may_modify)
2ca4f1
-    iter->source->ref_count++;
2ca4f1
+    g_source_ref (iter->source);
2ca4f1
 
2ca4f1
   *source = iter->source;
2ca4f1
   return *source != NULL;
2ca4f1
@@ -994,7 +985,7 @@ g_source_iter_clear (GSourceIter *iter)
2ca4f1
 {
2ca4f1
   if (iter->source && iter->may_modify)
2ca4f1
     {
2ca4f1
-      SOURCE_UNREF (iter->source, iter->context);
2ca4f1
+      g_source_unref_internal (iter->source, iter->context, TRUE);
2ca4f1
       iter->source = NULL;
2ca4f1
     }
2ca4f1
 }
2ca4f1
@@ -1135,7 +1126,7 @@ g_source_attach_unlocked (GSource      *source,
2ca4f1
 
2ca4f1
   source->context = context;
2ca4f1
   source->source_id = id;
2ca4f1
-  source->ref_count++;
2ca4f1
+  g_source_ref (source);
2ca4f1
 
2ca4f1
   g_hash_table_insert (context->sources, GUINT_TO_POINTER (id), source);
2ca4f1
 
2ca4f1
@@ -1675,7 +1666,7 @@ g_source_set_funcs (GSource     *source,
2ca4f1
 {
2ca4f1
   g_return_if_fail (source != NULL);
2ca4f1
   g_return_if_fail (source->context == NULL);
2ca4f1
-  g_return_if_fail (source->ref_count > 0);
2ca4f1
+  g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
2ca4f1
   g_return_if_fail (funcs != NULL);
2ca4f1
 
2ca4f1
   source->source_funcs = funcs;
2ca4f1
@@ -2050,19 +2041,9 @@ g_source_set_name_by_id (guint           tag,
2ca4f1
 GSource *
2ca4f1
 g_source_ref (GSource *source)
2ca4f1
 {
2ca4f1
-  GMainContext *context;
2ca4f1
-  
2ca4f1
   g_return_val_if_fail (source != NULL, NULL);
2ca4f1
 
2ca4f1
-  context = source->context;
2ca4f1
-
2ca4f1
-  if (context)
2ca4f1
-    LOCK_CONTEXT (context);
2ca4f1
-
2ca4f1
-  source->ref_count++;
2ca4f1
-
2ca4f1
-  if (context)
2ca4f1
-    UNLOCK_CONTEXT (context);
2ca4f1
+  g_atomic_int_inc (&source->ref_count);
2ca4f1
 
2ca4f1
   return source;
2ca4f1
 }
2ca4f1
@@ -2078,12 +2059,11 @@ g_source_unref_internal (GSource      *source,
2ca4f1
   GSourceCallbackFuncs *old_cb_funcs = NULL;
2ca4f1
 
2ca4f1
   g_return_if_fail (source != NULL);
2ca4f1
-  
2ca4f1
+
2ca4f1
   if (!have_lock && context)
2ca4f1
     LOCK_CONTEXT (context);
2ca4f1
 
2ca4f1
-  source->ref_count--;
2ca4f1
-  if (source->ref_count == 0)
2ca4f1
+  if (g_atomic_int_dec_and_test (&source->ref_count))
2ca4f1
     {
2ca4f1
       TRACE (GLIB_SOURCE_BEFORE_FREE (source, context,
2ca4f1
                                       source->source_funcs->finalize));
2ca4f1
@@ -2107,20 +2087,20 @@ g_source_unref_internal (GSource      *source,
2ca4f1
 	{
2ca4f1
           /* Temporarily increase the ref count again so that GSource methods
2ca4f1
            * can be called from finalize(). */
2ca4f1
-          source->ref_count++;
2ca4f1
+          g_atomic_int_inc (&source->ref_count);
2ca4f1
 	  if (context)
2ca4f1
 	    UNLOCK_CONTEXT (context);
2ca4f1
 	  source->source_funcs->finalize (source);
2ca4f1
 	  if (context)
2ca4f1
 	    LOCK_CONTEXT (context);
2ca4f1
-          source->ref_count--;
2ca4f1
+          g_atomic_int_add (&source->ref_count, -1);
2ca4f1
 	}
2ca4f1
 
2ca4f1
       if (old_cb_funcs)
2ca4f1
         {
2ca4f1
           /* Temporarily increase the ref count again so that GSource methods
2ca4f1
            * can be called from callback_funcs.unref(). */
2ca4f1
-          source->ref_count++;
2ca4f1
+          g_atomic_int_inc (&source->ref_count);
2ca4f1
           if (context)
2ca4f1
             UNLOCK_CONTEXT (context);
2ca4f1
 
2ca4f1
@@ -2128,7 +2108,7 @@ g_source_unref_internal (GSource      *source,
2ca4f1
 
2ca4f1
           if (context)
2ca4f1
             LOCK_CONTEXT (context);
2ca4f1
-          source->ref_count--;
2ca4f1
+          g_atomic_int_add (&source->ref_count, -1);
2ca4f1
         }
2ca4f1
 
2ca4f1
       g_free (source->name);
2ca4f1
@@ -3201,7 +3181,7 @@ g_main_dispatch (GMainContext *context)
2ca4f1
 	    }
2ca4f1
 	}
2ca4f1
       
2ca4f1
-      SOURCE_UNREF (source, context);
2ca4f1
+      g_source_unref_internal (source, context, TRUE);
2ca4f1
     }
2ca4f1
 
2ca4f1
   g_ptr_array_set_size (context->pending_dispatches, 0);
2ca4f1
@@ -3440,7 +3420,7 @@ g_main_context_prepare (GMainContext *context,
2ca4f1
   for (i = 0; i < context->pending_dispatches->len; i++)
2ca4f1
     {
2ca4f1
       if (context->pending_dispatches->pdata[i])
2ca4f1
-	SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context);
2ca4f1
+        g_source_unref_internal ((GSource *)context->pending_dispatches->pdata[i], context, TRUE);
2ca4f1
     }
2ca4f1
   g_ptr_array_set_size (context->pending_dispatches, 0);
2ca4f1
   
2ca4f1
@@ -3788,7 +3768,7 @@ g_main_context_check (GMainContext *context,
2ca4f1
 
2ca4f1
       if (source->flags & G_SOURCE_READY)
2ca4f1
 	{
2ca4f1
-	  source->ref_count++;
2ca4f1
+          g_source_ref (source);
2ca4f1
 	  g_ptr_array_add (context->pending_dispatches, source);
2ca4f1
 
2ca4f1
 	  n_ready++;
2ca4f1
-- 
2ca4f1
2.31.1
2ca4f1