[glib/mcatanzaro/glib-2-56-rhel8: 36/45] Use atomic reference counting for GSource




commit 3d6f4b6b608f8a0e5e6b20c228b4f6a8924e6801
Author: Sebastian Dröge <sebastian centricular com>
Date:   Thu Feb 14 17:46:33 2019 +0200

    Use atomic reference counting for GSource
    
    If attached to a context already it would use a mutex instead but at
    least before that the reference counting is not thread-safe currently.

 glib/gmain.c | 50 +++++++++++++++-----------------------------------
 1 file changed, 15 insertions(+), 35 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 26e68823d..5b91c3117 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -374,15 +374,6 @@ typedef struct _GSourceIter
 #define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
 #define SOURCE_BLOCKED(source) (((source)->flags & G_SOURCE_BLOCKED) != 0)
 
-#define SOURCE_UNREF(source, context)                       \
-   G_STMT_START {                                           \
-    if ((source)->ref_count > 1)                            \
-      (source)->ref_count--;                                \
-    else                                                    \
-      g_source_unref_internal ((source), (context), TRUE);  \
-   } G_STMT_END
-
-
 /* Forward declarations */
 
 static void g_source_unref_internal             (GSource      *source,
@@ -977,10 +968,10 @@ g_source_iter_next (GSourceIter *iter, GSource **source)
    */
 
   if (iter->source && iter->may_modify)
-    SOURCE_UNREF (iter->source, iter->context);
+    g_source_unref_internal (iter->source, iter->context, TRUE);
   iter->source = next_source;
   if (iter->source && iter->may_modify)
-    iter->source->ref_count++;
+    g_source_ref (iter->source);
 
   *source = iter->source;
   return *source != NULL;
@@ -994,7 +985,7 @@ g_source_iter_clear (GSourceIter *iter)
 {
   if (iter->source && iter->may_modify)
     {
-      SOURCE_UNREF (iter->source, iter->context);
+      g_source_unref_internal (iter->source, iter->context, TRUE);
       iter->source = NULL;
     }
 }
@@ -1135,7 +1126,7 @@ g_source_attach_unlocked (GSource      *source,
 
   source->context = context;
   source->source_id = id;
-  source->ref_count++;
+  g_source_ref (source);
 
   g_hash_table_insert (context->sources, GUINT_TO_POINTER (id), source);
 
@@ -1675,7 +1666,7 @@ g_source_set_funcs (GSource     *source,
 {
   g_return_if_fail (source != NULL);
   g_return_if_fail (source->context == NULL);
-  g_return_if_fail (source->ref_count > 0);
+  g_return_if_fail (g_atomic_int_get (&source->ref_count) > 0);
   g_return_if_fail (funcs != NULL);
 
   source->source_funcs = funcs;
@@ -2050,19 +2041,9 @@ g_source_set_name_by_id (guint           tag,
 GSource *
 g_source_ref (GSource *source)
 {
-  GMainContext *context;
-  
   g_return_val_if_fail (source != NULL, NULL);
 
-  context = source->context;
-
-  if (context)
-    LOCK_CONTEXT (context);
-
-  source->ref_count++;
-
-  if (context)
-    UNLOCK_CONTEXT (context);
+  g_atomic_int_inc (&source->ref_count);
 
   return source;
 }
@@ -2078,12 +2059,11 @@ g_source_unref_internal (GSource      *source,
   GSourceCallbackFuncs *old_cb_funcs = NULL;
 
   g_return_if_fail (source != NULL);
-  
+
   if (!have_lock && context)
     LOCK_CONTEXT (context);
 
-  source->ref_count--;
-  if (source->ref_count == 0)
+  if (g_atomic_int_dec_and_test (&source->ref_count))
     {
       TRACE (GLIB_SOURCE_BEFORE_FREE (source, context,
                                       source->source_funcs->finalize));
@@ -2107,20 +2087,20 @@ g_source_unref_internal (GSource      *source,
        {
           /* Temporarily increase the ref count again so that GSource methods
            * can be called from finalize(). */
-          source->ref_count++;
+          g_atomic_int_inc (&source->ref_count);
          if (context)
            UNLOCK_CONTEXT (context);
          source->source_funcs->finalize (source);
          if (context)
            LOCK_CONTEXT (context);
-          source->ref_count--;
+          g_atomic_int_add (&source->ref_count, -1);
        }
 
       if (old_cb_funcs)
         {
           /* Temporarily increase the ref count again so that GSource methods
            * can be called from callback_funcs.unref(). */
-          source->ref_count++;
+          g_atomic_int_inc (&source->ref_count);
           if (context)
             UNLOCK_CONTEXT (context);
 
@@ -2128,7 +2108,7 @@ g_source_unref_internal (GSource      *source,
 
           if (context)
             LOCK_CONTEXT (context);
-          source->ref_count--;
+          g_atomic_int_add (&source->ref_count, -1);
         }
 
       g_free (source->name);
@@ -3201,7 +3181,7 @@ g_main_dispatch (GMainContext *context)
            }
        }
       
-      SOURCE_UNREF (source, context);
+      g_source_unref_internal (source, context, TRUE);
     }
 
   g_ptr_array_set_size (context->pending_dispatches, 0);
@@ -3440,7 +3420,7 @@ g_main_context_prepare (GMainContext *context,
   for (i = 0; i < context->pending_dispatches->len; i++)
     {
       if (context->pending_dispatches->pdata[i])
-       SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context);
+        g_source_unref_internal ((GSource *)context->pending_dispatches->pdata[i], context, TRUE);
     }
   g_ptr_array_set_size (context->pending_dispatches, 0);
   
@@ -3788,7 +3768,7 @@ g_main_context_check (GMainContext *context,
 
       if (source->flags & G_SOURCE_READY)
        {
-         source->ref_count++;
+          g_source_ref (source);
          g_ptr_array_add (context->pending_dispatches, source);
 
          n_ready++;


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