[libdazzle] signal-group: be more flexible in cleanup



commit bfeb73ed739fe50d525a91ddfd2c0d09be657b2a
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jan 12 14:30:33 2018 -0800

    signal-group: be more flexible in cleanup
    
     - Ensure we hold a reference during cleanup, so that the object
       cannot be finalized out from underneath us.
     - Don't disconnect if we lost our target.
     - Code style cleanup

 src/bindings/dzl-signal-group.c | 48 +++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 19 deletions(-)
---
diff --git a/src/bindings/dzl-signal-group.c b/src/bindings/dzl-signal-group.c
index 011b5a2..cfbf294 100644
--- a/src/bindings/dzl-signal-group.c
+++ b/src/bindings/dzl-signal-group.c
@@ -233,24 +233,32 @@ dzl_signal_group_bind (DzlSignalGroup *self,
 static void
 dzl_signal_group_unbind (DzlSignalGroup *self)
 {
-  GObject *target;
-  gsize i;
+  g_autoptr(GObject) target = NULL;
 
   g_return_if_fail (DZL_IS_SIGNAL_GROUP (self));
 
-  if (self->target == NULL)
-    return;
-
-  target = self->target;
-  self->target = NULL;
-
-  g_object_weak_unref (target,
-                       dzl_signal_group__target_weak_notify,
-                       self);
+  if (NULL != (target = g_steal_pointer (&self->target)))
+    {
+      /*
+       * If we have a valid target, we want to hold a reference to it
+       * while we do the disconnections, just to ensure it is not
+       * finalized out from underneath us.
+       */
+      g_object_ref (target);
+
+      /*
+       * Let go of our weak reference now that we have a full reference
+       * for the life of this function.
+       */
+      g_object_weak_unref (target,
+                           dzl_signal_group__target_weak_notify,
+                           self);
+    }
 
-  for (i = 0; i < self->handlers->len; i++)
+  for (guint i = 0; i < self->handlers->len; i++)
     {
       SignalHandler *handler;
+      gulong handler_id;
 
       handler = g_ptr_array_index (self->handlers, i);
 
@@ -258,15 +266,17 @@ dzl_signal_group_unbind (DzlSignalGroup *self)
       g_assert (handler->signal_id != 0);
       g_assert (handler->closure != NULL);
 
-      if (handler->handler_id != 0)
-        {
-          gulong handler_id;
+      handler_id = handler->handler_id;
+      handler->handler_id = 0;
 
-          handler_id = handler->handler_id;
-          handler->handler_id = 0;
+      /*
+       * If @target is NULL, we lost a race to cleanup the weak
+       * instance and the signal connections have already been
+       * finalized and therefore nothing to do.
+       */
 
-          g_signal_handler_disconnect (target, handler_id);
-        }
+      if (target != NULL && handler_id != 0)
+        g_signal_handler_disconnect (target, handler_id);
     }
 
   g_signal_emit (self, signals [UNBIND], 0);


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