reverted notify_mutex introduction, since this prevents parallelized
authorTim Janik <timj@gtk.org>
Sat, 30 Jul 2005 19:46:11 +0000 (19:46 +0000)
committerTim Janik <timj@src.gnome.org>
Sat, 30 Jul 2005 19:46:11 +0000 (19:46 +0000)
Sat Jul 30 21:10:26 2005  Tim Janik  <timj@gtk.org>

        * gobject.c: reverted notify_mutex introduction, since this prevents
        parallelized setting of object properties on different objects, and
        serves no apparent purpose (to me at least).
        g_object_real_dispose(): removed non-atomic reference count
        modifications.
        g_object_unref(): make sure the closures array is destroyed when
        destroying signal handlers.

        * gparam.c: cosmetic changes.

        * gsignal.c: comment fixup. allow 16bit blocking count.

        * gsignal.c: reverted GClosure related changes.

        * gclosure.c: reverted premature commit of atomic reference
        counting attempt.

gobject/ChangeLog
gobject/gclosure.c
gobject/gobject.c
gobject/gparam.c
gobject/gsignal.c

index 4ccef9c..f1d048f 100644 (file)
@@ -1,3 +1,22 @@
+Sat Jul 30 21:10:26 2005  Tim Janik  <timj@gtk.org>
+
+       * gobject.c: reverted notify_mutex introduction, since this prevents
+       parallelized setting of object properties on different objects, and
+       serves no apparent purpose (to me at least).
+       g_object_real_dispose(): removed non-atomic reference count 
+       modifications.
+       g_object_unref(): make sure the closures array is destroyed when
+       destroying signal handlers.
+
+       * gparam.c: cosmetic changes.
+
+       * gsignal.c: comment fixup. allow 16bit blocking count.
+
+       * gsignal.c: reverted GClosure related changes.
+
+       * gclosure.c: reverted premature commit of atomic reference
+       counting attempt.
+
 2005-07-21  Matthias Clasen  <mclasen@redhat.com>
 
        * === Released 2.7.4 ===
index 04e2d26..2323384 100644 (file)
 #define        CLOSURE_N_NOTIFIERS(cl)         (CLOSURE_N_MFUNCS (cl) + \
                                          (cl)->n_fnotifiers + \
                                          (cl)->n_inotifiers)
-
-/* union of first int we need to make atomic */
-typedef union {
-  GClosure bits;
-  gint atomic;
-} GAtomicClosureBits;
-
-#define BITS_AS_INT(b) (((GAtomicClosureBits*)(b))->atomic)
-
-#define CLOSURE_READ_BITS(cl,bits)     (BITS_AS_INT(bits) = g_atomic_int_get ((gint*)(cl)))
-#define CLOSURE_READ_BITS2(cl,old,new) (BITS_AS_INT(old) = CLOSURE_READ_BITS (cl, new))
-#define CLOSURE_SWAP_BITS(cl,old,new)  (g_atomic_int_compare_and_exchange ((gint*)(cl),        \
-                                               BITS_AS_INT(old),BITS_AS_INT(new)))
-
-#define CLOSURE_REF(closure)                                                   \
-G_STMT_START {                                                                 \
-  GClosure old, new;                                                           \
-  do {                                                                         \
-    CLOSURE_READ_BITS2 (closure, &old, &new);                                  \
-    new.ref_count++;                                                           \
-  }                                                                            \
-  while (!CLOSURE_SWAP_BITS (closure, &old, &new));                            \
-} G_STMT_END
-
-
-#define CLOSURE_UNREF(closure, is_zero)                                        \
-G_STMT_START {                                                                 \
-  GClosure old, new;                                                           \
-  do {                                                                         \
-    CLOSURE_READ_BITS2 (closure, &old, &new);                                  \
-    if (old.ref_count == 1)    /* last unref, invalidate first */              \
-      g_closure_invalidate ((closure));                                                \
-    new.ref_count--;                                                           \
-    is_zero = (new.ref_count == 0);                                            \
-  }                                                                            \
-  while (!CLOSURE_SWAP_BITS (closure, &old, &new));                            \
-} G_STMT_END
-
 enum {
   FNOTIFY,
   INOTIFY,
@@ -114,8 +76,6 @@ static inline void
 closure_invoke_notifiers (GClosure *closure,
                          guint     notify_type)
 {
-  GClosure bits, new;
-
   /* notifier layout:
    *     meta_marshal  n_guards    n_guards     n_fnotif.  n_inotifiers
    * ->[[meta_marshal][pre_guards][post_guards][fnotifiers][inotifiers]]
@@ -139,12 +99,11 @@ closure_invoke_notifiers (GClosure *closure,
       GClosureNotifyData *ndata;
       guint i, offs;
     case FNOTIFY:
-      CLOSURE_READ_BITS (closure, &bits);
-      while (bits.n_fnotifiers)
+      while (closure->n_fnotifiers)
        {
-         register guint n = --bits.n_fnotifiers;
+         register guint n = --closure->n_fnotifiers;
 
-         ndata = closure->notifiers + CLOSURE_N_MFUNCS (&bits) + n;
+         ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + n;
          closure->marshal = (GClosureMarshal) ndata->notify;
          closure->data = ndata->data;
          ndata->notify (ndata->data, closure);
@@ -153,34 +112,23 @@ closure_invoke_notifiers (GClosure *closure,
       closure->data = NULL;
       break;
     case INOTIFY:
-      do {
-        CLOSURE_READ_BITS2 (closure, &bits, &new);
-        new.in_inotify = TRUE;
-      }
-      while (!CLOSURE_SWAP_BITS (closure, &bits,  &new));
-
-      while (bits.n_inotifiers)
+      closure->in_inotify = TRUE;
+      while (closure->n_inotifiers)
        {
-          register guint n = --bits.n_inotifiers;
+          register guint n = --closure->n_inotifiers;
 
-         ndata = closure->notifiers + CLOSURE_N_MFUNCS (&bits) + bits.n_fnotifiers + n;
+         ndata = closure->notifiers + CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + n;
          closure->marshal = (GClosureMarshal) ndata->notify;
          closure->data = ndata->data;
          ndata->notify (ndata->data, closure);
        }
       closure->marshal = NULL;
       closure->data = NULL;
-      do {
-        CLOSURE_READ_BITS2 (closure, &bits, &new);
-        new.n_inotifiers = 0;
-        new.in_inotify = FALSE;
-      }
-      while (!CLOSURE_SWAP_BITS (closure, &bits, &new));
+      closure->in_inotify = FALSE;
       break;
     case PRE_NOTIFY:
-      CLOSURE_READ_BITS (closure, &bits);
-      i = bits.n_guards;
-      offs = bits.meta_marshal;
+      i = closure->n_guards;
+      offs = closure->meta_marshal;
       while (i--)
        {
          ndata = closure->notifiers + offs + i;
@@ -188,9 +136,8 @@ closure_invoke_notifiers (GClosure *closure,
        }
       break;
     case POST_NOTIFY:
-      CLOSURE_READ_BITS (closure, &bits);
-      i = bits.n_guards;
-      offs = bits.meta_marshal + i;
+      i = closure->n_guards;
+      offs = closure->meta_marshal + i;
       while (i--)
        {
          ndata = closure->notifiers + offs + i;
@@ -205,48 +152,29 @@ g_closure_set_meta_marshal (GClosure       *closure,
                            gpointer        marshal_data,
                            GClosureMarshal meta_marshal)
 {
-  GClosureNotifyData *old_notifiers, *new_notifiers;
+  GClosureNotifyData *notifiers;
   guint n;
-  GClosure old, new;
 
   g_return_if_fail (closure != NULL);
   g_return_if_fail (meta_marshal != NULL);
-
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  g_return_if_fail (old.is_invalid == FALSE);
-  g_return_if_fail (old.in_marshal == FALSE);
-  g_return_if_fail (old.meta_marshal == 0);
-
-  n = CLOSURE_N_NOTIFIERS (&old);
-
-  old_notifiers = closure->notifiers;
-  new_notifiers = g_renew (GClosureNotifyData, NULL, n + 1);
-  if (old_notifiers)
+  g_return_if_fail (closure->is_invalid == FALSE);
+  g_return_if_fail (closure->in_marshal == FALSE);
+  g_return_if_fail (closure->meta_marshal == 0);
+
+  n = CLOSURE_N_NOTIFIERS (closure);
+  notifiers = closure->notifiers;
+  closure->notifiers = g_renew (GClosureNotifyData, NULL, CLOSURE_N_NOTIFIERS (closure) + 1);
+  if (notifiers)
     {
       /* usually the meta marshal will be setup right after creation, so the
        * g_memmove() should be rare-case scenario
        */
-      g_memmove (new_notifiers + 1, old_notifiers, n * sizeof (old_notifiers[0]));
+      g_memmove (closure->notifiers + 1, notifiers, CLOSURE_N_NOTIFIERS (closure) * sizeof (notifiers[0]));
+      g_free (notifiers);
     }
-  new_notifiers[0].data = marshal_data;
-  new_notifiers[0].notify = (GClosureNotify) meta_marshal;
-
-  new.meta_marshal = 1;
-
-  /* this cannot be made atomic, as soon as we switch on the meta_marshal
-   * bit, another thread could use the notifier while we have not yet
-   * copied it. the safest is to install the new_notifiers first and then
-   * switch on the meta_marshal flag. */
-  closure->notifiers = new_notifiers;
-
-  if (!CLOSURE_SWAP_BITS (closure, &old, &new)) {
-    g_free (new_notifiers);
-    goto retry;
-  }
-
-  g_free (old_notifiers);
+  closure->notifiers[0].data = marshal_data;
+  closure->notifiers[0].notify = (GClosureNotify) meta_marshal;
+  closure->meta_marshal = 1;
 }
 
 void
@@ -257,56 +185,40 @@ g_closure_add_marshal_guards (GClosure      *closure,
                              GClosureNotify post_marshal_notify)
 {
   guint i;
-  GClosure old, new;
-  GClosureNotifyData *old_notifiers, *new_notifiers;
 
   g_return_if_fail (closure != NULL);
   g_return_if_fail (pre_marshal_notify != NULL);
   g_return_if_fail (post_marshal_notify != NULL);
-
-retry:
-  CLOSURE_READ_BITS2 (closure,  &old,  &new);
-
-  g_return_if_fail (old.is_invalid == FALSE);
-  g_return_if_fail (old.in_marshal == FALSE);
-  g_return_if_fail (old.n_guards < CLOSURE_MAX_N_GUARDS);
-
-  old_notifiers = closure->notifiers;
-  new_notifiers = g_renew (GClosureNotifyData, old_notifiers, CLOSURE_N_NOTIFIERS (&old) + 2);
-  if (old.n_inotifiers)
-    new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                       old.n_fnotifiers +
-                       old.n_inotifiers + 1)] = new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                                                                         old.n_fnotifiers + 0)];
-  if (old.n_inotifiers > 1)
-    new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                       old.n_fnotifiers +
-                       old.n_inotifiers)] = new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                                                                     old.n_fnotifiers + 1)];
-  if (old.n_fnotifiers)
-    new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                       old.n_fnotifiers + 1)] = new_notifiers[CLOSURE_N_MFUNCS (&old) + 0];
-  if (old.n_fnotifiers > 1)
-    new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                       old.n_fnotifiers)] = new_notifiers[CLOSURE_N_MFUNCS (&old) + 1];
-  if (old.n_guards)
-    new_notifiers[(old.meta_marshal +
-                       old.n_guards +
-                       old.n_guards + 1)] = new_notifiers[old.meta_marshal + old.n_guards];
-  i = old.n_guards;
-
-  new.n_guards = i+1;
-
-  new_notifiers[old.meta_marshal + i].data = pre_marshal_data;
-  new_notifiers[old.meta_marshal + i].notify = pre_marshal_notify;
-  new_notifiers[old.meta_marshal + i + 1].data = post_marshal_data;
-  new_notifiers[old.meta_marshal + i + 1].notify = post_marshal_notify;
-
-  /* not really atomic */
-  closure->notifiers = new_notifiers;
-
-  if (!CLOSURE_SWAP_BITS (closure, &old, &new))
-    goto retry;
+  g_return_if_fail (closure->is_invalid == FALSE);
+  g_return_if_fail (closure->in_marshal == FALSE);
+  g_return_if_fail (closure->n_guards < CLOSURE_MAX_N_GUARDS);
+
+  closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 2);
+  if (closure->n_inotifiers)
+    closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                       closure->n_fnotifiers +
+                       closure->n_inotifiers + 1)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                                                                         closure->n_fnotifiers + 0)];
+  if (closure->n_inotifiers > 1)
+    closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                       closure->n_fnotifiers +
+                       closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                                                                     closure->n_fnotifiers + 1)];
+  if (closure->n_fnotifiers)
+    closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                       closure->n_fnotifiers + 1)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 0];
+  if (closure->n_fnotifiers > 1)
+    closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                       closure->n_fnotifiers)] = closure->notifiers[CLOSURE_N_MFUNCS (closure) + 1];
+  if (closure->n_guards)
+    closure->notifiers[(closure->meta_marshal +
+                       closure->n_guards +
+                       closure->n_guards + 1)] = closure->notifiers[closure->meta_marshal + closure->n_guards];
+  i = closure->n_guards++;
+  closure->notifiers[closure->meta_marshal + i].data = pre_marshal_data;
+  closure->notifiers[closure->meta_marshal + i].notify = pre_marshal_notify;
+  closure->notifiers[closure->meta_marshal + i + 1].data = post_marshal_data;
+  closure->notifiers[closure->meta_marshal + i + 1].notify = post_marshal_notify;
 }
 
 void
@@ -315,35 +227,20 @@ g_closure_add_finalize_notifier (GClosure      *closure,
                                 GClosureNotify notify_func)
 {
   guint i;
-  GClosure old, new;
-  GClosureNotifyData *old_notifiers, *new_notifiers;
 
   g_return_if_fail (closure != NULL);
   g_return_if_fail (notify_func != NULL);
-
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  g_return_if_fail (old.n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS);
-
-  old_notifiers = closure->notifiers;
-  new_notifiers = g_renew (GClosureNotifyData, old_notifiers, CLOSURE_N_NOTIFIERS (&old) + 1);
-  if (old.n_inotifiers)
-    new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                       old.n_fnotifiers +
-                       old.n_inotifiers)] = new_notifiers[(CLOSURE_N_MFUNCS (&old) +
-                                                                     old.n_fnotifiers + 0)];
-  i = CLOSURE_N_MFUNCS (&old) + old.n_fnotifiers;
-  new.n_fnotifiers++;
-
-  new_notifiers[i].data = notify_data;
-  new_notifiers[i].notify = notify_func;
-
-  /* not really atomic */
-  closure->notifiers = new_notifiers;
-
-  while (!CLOSURE_SWAP_BITS (closure, &old, &new))
-    goto retry;
+  g_return_if_fail (closure->n_fnotifiers < CLOSURE_MAX_N_FNOTIFIERS);
+
+  closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1);
+  if (closure->n_inotifiers)
+    closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                       closure->n_fnotifiers +
+                       closure->n_inotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                                                                     closure->n_fnotifiers + 0)];
+  i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers++;
+  closure->notifiers[i].data = notify_data;
+  closure->notifiers[i].notify = notify_func;
 }
 
 void
@@ -352,31 +249,16 @@ g_closure_add_invalidate_notifier (GClosure      *closure,
                                   GClosureNotify notify_func)
 {
   guint i;
-  GClosure old, new;
-  GClosureNotifyData *old_notifiers, *new_notifiers;
 
   g_return_if_fail (closure != NULL);
   g_return_if_fail (notify_func != NULL);
+  g_return_if_fail (closure->is_invalid == FALSE);
+  g_return_if_fail (closure->n_inotifiers < CLOSURE_MAX_N_INOTIFIERS);
 
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  g_return_if_fail (old.is_invalid == FALSE);
-  g_return_if_fail (old.n_inotifiers < CLOSURE_MAX_N_INOTIFIERS);
-
-  old_notifiers = closure->notifiers;
-  new_notifiers = g_renew (GClosureNotifyData, old_notifiers, CLOSURE_N_NOTIFIERS (&old) + 1);
-  i = CLOSURE_N_MFUNCS (&old) + old.n_fnotifiers + old.n_inotifiers;
-  new.n_inotifiers++;
-
-  new_notifiers[i].data = notify_data;
-  new_notifiers[i].notify = notify_func;
-
-  /* not really atomic */
-  closure->notifiers = new_notifiers;
-
-  while (!CLOSURE_SWAP_BITS (closure, &old, &new))
-    goto retry;
+  closure->notifiers = g_renew (GClosureNotifyData, closure->notifiers, CLOSURE_N_NOTIFIERS (closure) + 1);
+  i = CLOSURE_N_MFUNCS (closure) + closure->n_fnotifiers + closure->n_inotifiers++;
+  closure->notifiers[i].data = notify_data;
+  closure->notifiers[i].notify = notify_func;
 }
 
 static inline gboolean
@@ -385,19 +267,12 @@ closure_try_remove_inotify (GClosure       *closure,
                            GClosureNotify notify_func)
 {
   GClosureNotifyData *ndata, *nlast;
-  GClosure old, new;
-
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
 
-  nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (&old) - 1;
-  for (ndata = nlast + 1 - old.n_inotifiers; ndata <= nlast; ndata++)
+  nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - 1;
+  for (ndata = nlast + 1 - closure->n_inotifiers; ndata <= nlast; ndata++)
     if (ndata->notify == notify_func && ndata->data == notify_data)
       {
-       new.n_inotifiers -= 1;
-       if (!CLOSURE_SWAP_BITS (closure, &old, &new))
-          goto retry;
-       
+       closure->n_inotifiers -= 1;
        if (ndata < nlast)
          *ndata = *nlast;
 
@@ -412,27 +287,19 @@ closure_try_remove_fnotify (GClosure       *closure,
                            GClosureNotify notify_func)
 {
   GClosureNotifyData *ndata, *nlast;
-  GClosure old, new;
 
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (&old) - old.n_inotifiers - 1;
-  for (ndata = nlast + 1 - old.n_fnotifiers; ndata <= nlast; ndata++)
+  nlast = closure->notifiers + CLOSURE_N_NOTIFIERS (closure) - closure->n_inotifiers - 1;
+  for (ndata = nlast + 1 - closure->n_fnotifiers; ndata <= nlast; ndata++)
     if (ndata->notify == notify_func && ndata->data == notify_data)
       {
-       new.n_fnotifiers -= 1;
-       if (!CLOSURE_SWAP_BITS (closure, &old, &new))
-          goto retry;
-       
+       closure->n_fnotifiers -= 1;
        if (ndata < nlast)
          *ndata = *nlast;
-
-       if (new.n_inotifiers)
-         closure->notifiers[(CLOSURE_N_MFUNCS (&new) +
-                             new.n_fnotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (&new) +
-                                                                           new.n_fnotifiers +
-                                                                           new.n_inotifiers)];
+       if (closure->n_inotifiers)
+         closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                             closure->n_fnotifiers)] = closure->notifiers[(CLOSURE_N_MFUNCS (closure) +
+                                                                           closure->n_fnotifiers +
+                                                                           closure->n_inotifiers)];
        return TRUE;
       }
   return FALSE;
@@ -445,7 +312,7 @@ g_closure_ref (GClosure *closure)
   g_return_val_if_fail (closure->ref_count > 0, NULL);
   g_return_val_if_fail (closure->ref_count < CLOSURE_MAX_REF_COUNT, NULL);
 
-  CLOSURE_REF (closure);
+  closure->ref_count += 1;
 
   return closure;
 }
@@ -453,21 +320,12 @@ g_closure_ref (GClosure *closure)
 void
 g_closure_invalidate (GClosure *closure)
 {
-  GClosure old, new;
-
   g_return_if_fail (closure != NULL);
 
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  if (!old.is_invalid)
+  if (!closure->is_invalid)
     {
-      new.ref_count++;
-      new.is_invalid = TRUE;
-
-      if (!CLOSURE_SWAP_BITS (closure, &old, &new))
-       goto retry;
-
+      closure->ref_count += 1; /* preserve floating flag */
+      closure->is_invalid = TRUE;
       closure_invoke_notifiers (closure, INOTIFY);
       g_closure_unref (closure);
     }
@@ -476,14 +334,15 @@ retry:
 void
 g_closure_unref (GClosure *closure)
 {
-  gboolean is_zero;
-
   g_return_if_fail (closure != NULL);
   g_return_if_fail (closure->ref_count > 0);
 
-  CLOSURE_UNREF (closure, is_zero);
+  if (closure->ref_count == 1) /* last unref, invalidate first */
+    g_closure_invalidate (closure);
 
-  if (G_UNLIKELY (is_zero))
+  closure->ref_count -= 1;
+
+  if (closure->ref_count == 0)
     {
       closure_invoke_notifiers (closure, FNOTIFY);
       g_free (closure->notifiers);
@@ -494,8 +353,6 @@ g_closure_unref (GClosure *closure)
 void
 g_closure_sink (GClosure *closure)
 {
-  GClosure old, new;
-
   g_return_if_fail (closure != NULL);
   g_return_if_fail (closure->ref_count > 0);
 
@@ -504,17 +361,13 @@ g_closure_sink (GClosure *closure)
    * is unowned. with invoking g_closure_sink() code may
    * indicate that it takes over that intiial ref_count.
    */
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  if (old.floating)
+  if (closure->floating)
     {
-      new.floating = FALSE;
-
-      if (!CLOSURE_SWAP_BITS (closure, &old, &new))
-       goto retry;
-
-      g_closure_unref (closure);
+      closure->floating = FALSE;
+      if (closure->ref_count > 1)
+       closure->ref_count -= 1;
+      else
+       g_closure_unref (closure);
     }
 }
 
@@ -523,14 +376,10 @@ g_closure_remove_invalidate_notifier (GClosure      *closure,
                                      gpointer       notify_data,
                                      GClosureNotify notify_func)
 {
-  GClosure bits;
-
   g_return_if_fail (closure != NULL);
   g_return_if_fail (notify_func != NULL);
 
-  CLOSURE_READ_BITS (closure, &bits);
-
-  if (bits.is_invalid && bits.in_inotify && /* account removal of notify_func() while its called */
+  if (closure->is_invalid && closure->in_inotify && /* account removal of notify_func() while its called */
       ((gpointer) closure->marshal) == ((gpointer) notify_func) && closure->data == notify_data)
     closure->marshal = NULL;
   else if (!closure_try_remove_inotify (closure, notify_data, notify_func))
@@ -543,14 +392,10 @@ g_closure_remove_finalize_notifier (GClosure      *closure,
                                    gpointer       notify_data,
                                    GClosureNotify notify_func)
 {
-  GClosure bits;
-       
   g_return_if_fail (closure != NULL);
   g_return_if_fail (notify_func != NULL);
 
-  CLOSURE_READ_BITS (closure, &bits);
-
-  if (bits.is_invalid && !bits.in_inotify && /* account removal of notify_func() while its called */
+  if (closure->is_invalid && !closure->in_inotify && /* account removal of notify_func() while its called */
       ((gpointer) closure->marshal) == ((gpointer) notify_func) && closure->data == notify_data)
     closure->marshal = NULL;
   else if (!closure_try_remove_fnotify (closure, notify_data, notify_func))
@@ -565,29 +410,19 @@ g_closure_invoke (GClosure       *closure,
                  const GValue   *param_values,
                  gpointer        invocation_hint)
 {
-  GClosure old, new;
-
   g_return_if_fail (closure != NULL);
 
-retry:
-  CLOSURE_READ_BITS2 (closure, &old, &new);
-
-  if (!old.is_invalid)
-   {
+  if (!closure->is_invalid)
+    {
       GClosureMarshal marshal;
       gpointer marshal_data;
-      gboolean in_marshal = old.in_marshal;
-      gboolean meta_marshal = old.meta_marshal;
-
-      g_return_if_fail (closure->marshal || meta_marshal);
+      gboolean in_marshal = closure->in_marshal;
 
-      new.ref_count++;
-      new.in_marshal = TRUE;
+      g_return_if_fail (closure->marshal || closure->meta_marshal);
 
-      if (!CLOSURE_SWAP_BITS (closure, &old, &new))
-       goto retry;
-
-      if (meta_marshal)
+      closure->ref_count += 1; /* preserve floating flag */
+      closure->in_marshal = TRUE;
+      if (closure->meta_marshal)
        {
          marshal_data = closure->notifiers[0].data;
          marshal = (GClosureMarshal) closure->notifiers[0].notify;
@@ -599,22 +434,15 @@ retry:
        }
       if (!in_marshal)
        closure_invoke_notifiers (closure, PRE_NOTIFY);
-
       marshal (closure,
               return_value,
               n_param_values, param_values,
               invocation_hint,
               marshal_data);
-
       if (!in_marshal)
        closure_invoke_notifiers (closure, POST_NOTIFY);
-
-      do {
-        CLOSURE_READ_BITS2 (closure, &old, &new);
-        new.in_marshal = in_marshal;
-        new.ref_count--;
-      }
-      while (!CLOSURE_SWAP_BITS (closure, &old, &new));
+      closure->in_marshal = in_marshal;
+      g_closure_unref (closure);
     }
 }
 
index 073497f..4b79caf 100644 (file)
@@ -116,8 +116,6 @@ static gulong                   gobject_signals[LAST_SIGNAL] = { 0, };
 G_LOCK_DEFINE_STATIC (construct_objects_lock);
 static GSList *construct_objects = NULL;
 
-static GStaticRecMutex notify_mutex = G_STATIC_REC_MUTEX_INIT;
-
 /* --- functions --- */
 #ifdef G_ENABLE_DEBUG
 #define        IF_DEBUG(debug_type)    if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
@@ -525,18 +523,9 @@ g_object_do_get_property (GObject     *object,
 static void
 g_object_real_dispose (GObject *object)
 {
-  guint ref_count;
-
   g_signal_handlers_destroy (object);
   g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
-
-  /* yes, temporarily altering the ref_count is hackish, but that
-   * enforces people not jerking around with weak_ref notifiers
-   */
-  ref_count = g_atomic_int_get (&object->ref_count);
-  object->ref_count = 0;
   g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
-  object->ref_count = ref_count;
 }
 
 static void
@@ -587,11 +576,9 @@ g_object_freeze_notify (GObject *object)
   if (g_atomic_int_get (&object->ref_count) == 0)
     return;
 
-  g_static_rec_mutex_lock (&notify_mutex);
   g_object_ref (object);
   g_object_notify_queue_freeze (object, &property_notify_context);
   g_object_unref (object);
-  g_static_rec_mutex_unlock (&notify_mutex);
 }
 
 void
@@ -624,11 +611,9 @@ g_object_notify (GObject     *object,
     {
       GObjectNotifyQueue *nqueue;
       
-      g_static_rec_mutex_lock (&notify_mutex);
       nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
       g_object_notify_queue_add (object, nqueue, pspec);
       g_object_notify_queue_thaw (object, nqueue);
-      g_static_rec_mutex_unlock (&notify_mutex);
     }
   g_object_unref (object);
 }
@@ -643,14 +628,12 @@ g_object_thaw_notify (GObject *object)
     return;
   
   g_object_ref (object);
-  g_static_rec_mutex_lock (&notify_mutex);
   nqueue = g_object_notify_queue_from_object (object, &property_notify_context);
   if (!nqueue || !nqueue->freeze_count)
     g_warning ("%s: property-changed notification for %s(%p) is not frozen",
               G_STRFUNC, G_OBJECT_TYPE_NAME (object), object);
   else
     g_object_notify_queue_thaw (object, nqueue);
-  g_static_rec_mutex_unlock (&notify_mutex);
   g_object_unref (object);
 }
 
@@ -706,9 +689,7 @@ object_set_property (GObject             *object,
   else
     {
       class->set_property (object, param_id, &tmp_value, pspec);
-      g_static_rec_mutex_lock (&notify_mutex);
       g_object_notify_queue_add (object, nqueue, pspec);
-      g_static_rec_mutex_unlock (&notify_mutex);
     }
   g_value_unset (&tmp_value);
 }
@@ -1063,7 +1044,6 @@ g_object_set_valist (GObject       *object,
   
   g_return_if_fail (G_IS_OBJECT (object));
   
-  g_static_rec_mutex_lock (&notify_mutex);
   g_object_ref (object);
   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
   
@@ -1120,7 +1100,6 @@ g_object_set_valist (GObject       *object,
 
   g_object_notify_queue_thaw (object, nqueue);
   g_object_unref (object);
-  g_static_rec_mutex_unlock (&notify_mutex);
 }
 
 void
@@ -1226,7 +1205,6 @@ g_object_set_property (GObject        *object,
   g_return_if_fail (property_name != NULL);
   g_return_if_fail (G_IS_VALUE (value));
   
-  g_static_rec_mutex_lock (&notify_mutex);
   g_object_ref (object);
   nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
   
@@ -1252,7 +1230,6 @@ g_object_set_property (GObject        *object,
   
   g_object_notify_queue_thaw (object, nqueue);
   g_object_unref (object);
-  g_static_rec_mutex_unlock (&notify_mutex);
 }
 
 void
@@ -1668,9 +1645,9 @@ void
 g_object_unref (gpointer _object)
 {
   GObject *object = _object;
-  gint old_val;
+  gint old_ref;
   gboolean is_zero;
-
+  
   g_return_if_fail (G_IS_OBJECT (object));
   g_return_if_fail (object->ref_count > 0);
   
@@ -1679,44 +1656,46 @@ g_object_unref (gpointer _object)
     G_BREAKPOINT ();
 #endif  /* G_ENABLE_DEBUG */
 
-retry1:
-  old_val = g_atomic_int_get (&object->ref_count);
-  if (old_val > 1)
+  /* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
+ retry_atomic_decrement1:
+  old_ref = g_atomic_int_get (&object->ref_count);
+  if (old_ref > 1)
     {
-      if (!g_atomic_int_compare_and_exchange (&object->ref_count, old_val, old_val-1))
-       goto retry1;
+      if (!g_atomic_int_compare_and_exchange (&object->ref_count, old_ref, old_ref - 1))
+       goto retry_atomic_decrement1;
 
       /* if we went from 2->1 we need to notify toggle refs if any */
-      if (old_val == 2 && OBJECT_HAS_TOGGLE_REF (object))
+      if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
        toggle_refs_notify (object, TRUE);
     }
   else
     {
-      /* removing the last ref */
+      /* we are about tp remove the last reference */
       G_OBJECT_GET_CLASS (object)->dispose (object);
 
-      /* dispose could have resurected the object */
-retry2:
-      old_val = g_atomic_int_get (&object->ref_count);
-      if (old_val > 1)
+      /* may have been re-referenced meanwhile */
+    retry_atomic_decrement2:
+      old_ref = g_atomic_int_get (&object->ref_count);
+      if (old_ref > 1)
         {
-          if (!g_atomic_int_compare_and_exchange (&object->ref_count, old_val, old_val-1))
-           goto retry2;
+          if (!g_atomic_int_compare_and_exchange (&object->ref_count, old_ref, old_ref - 1))
+           goto retry_atomic_decrement2;
 
           /* if we went from 2->1 we need to notify toggle refs if any */
-          if (old_val == 2 && OBJECT_HAS_TOGGLE_REF (object))
+          if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
            toggle_refs_notify (object, TRUE);
-
+          
          return;
        }
-
-      /* we are still taking away the last ref */
+      
+      /* we are still in the process of taking away the last ref */
+      g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
       g_signal_handlers_destroy (object);
       g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
-
-      /* now we really take away the last ref */
+      
+      /* decrement the last reference */
       is_zero = g_atomic_int_dec_and_test (&object->ref_count);
-
+      
       /* may have been re-referenced meanwhile */
       if (G_LIKELY (is_zero)) 
        {
index 7147823..0d97e37 100644 (file)
@@ -198,9 +198,7 @@ g_param_spec_sink (GParamSpec *pspec)
   g_return_if_fail (pspec->ref_count > 0);
 
   if (g_datalist_id_remove_no_notify (&pspec->qdata, quark_floating))
-    {
-      g_param_spec_unref (pspec);
-    }
+    g_param_spec_unref (pspec);
 }
 
 G_CONST_RETURN gchar*
index b834fd8..2366c8d 100644 (file)
@@ -222,9 +222,9 @@ struct _Handler
   Handler      *next;
   Handler      *prev;
   GQuark       detail;
-  guint         ref_count;     /* ABI change, was 16 bits but since it's internal... */
-  guint         block_count : 12;
-#define HANDLER_MAX_BLOCK_COUNT (1 << 12)
+  guint         ref_count;
+  guint         block_count : 16;
+#define HANDLER_MAX_BLOCK_COUNT (1 << 16)
   guint         after : 1;
   GClosure     *closure;
 };
@@ -454,17 +454,6 @@ handler_match_free1_R (HandlerMatch *node,
   return next;
 }
 
-/* copy of gclosure.c code here to make the first 32 bits of the closure
- * atomic. */
-typedef union 
-{
-  GClosure bits;
-  gint atomic;
-} GAtomicClosureBits;
-
-#define BITS_AS_INT(b)  (((GAtomicClosureBits*)(b))->atomic)
-#define CLOSURE_READ_BITS(cl,bits)      (BITS_AS_INT(bits) = g_atomic_int_get ((gint*)(cl)))
-
 static HandlerMatch*
 handlers_find (gpointer         instance,
               GSignalMatchType mask,
@@ -491,26 +480,20 @@ handlers_find (gpointer         instance,
        }
       
       mask = ~mask;
-      for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next) 
-        {
-         GClosure bits;
-
-         CLOSURE_READ_BITS (handler->closure, &bits);
-         
-          if (handler->sequential_number &&
-             ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
-             ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
-              ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
-             ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
-             ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
-                                               bits.meta_marshal == 0 &&
-                                               ((GCClosure*) handler->closure)->callback == func)))
-           {
-             mlist = handler_match_prepend (mlist, handler, signal_id);
-             if (one_and_only)
-               return mlist;
-           }
-       }
+      for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
+        if (handler->sequential_number &&
+           ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
+           ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
+            ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
+           ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
+           ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
+                                             handler->closure->meta_marshal == 0 &&
+                                             ((GCClosure*) handler->closure)->callback == func)))
+         {
+           mlist = handler_match_prepend (mlist, handler, signal_id);
+           if (one_and_only)
+             return mlist;
+         }
     }
   else
     {
@@ -535,25 +518,19 @@ handlers_find (gpointer         instance,
                }
              
               for (handler = hlist->handlers; handler; handler = handler->next)
-               {
-                 GClosure bits;
-
-                 CLOSURE_READ_BITS (handler->closure, &bits);
-         
-                 if (handler->sequential_number &&
-                     ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
-                      ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
-                      ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
-                     ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
-                     ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
-                                                       bits.meta_marshal == 0 &&
-                                                       ((GCClosure*) handler->closure)->callback == func)))
-                   {
-                     mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
-                     if (one_and_only)
-                       return mlist;
-                   }
-               }
+               if (handler->sequential_number &&
+                   ((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
+                    ((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
+                    ((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
+                   ((mask & G_SIGNAL_MATCH_UNBLOCKED) || handler->block_count == 0) &&
+                   ((mask & G_SIGNAL_MATCH_FUNC) || (handler->closure->marshal == node->c_marshaller &&
+                                                     handler->closure->meta_marshal == 0 &&
+                                                     ((GCClosure*) handler->closure)->callback == func)))
+                 {
+                   mlist = handler_match_prepend (mlist, handler, hlist->signal_id);
+                   if (one_and_only)
+                     return mlist;
+                 }
             }
         }
     }