Fix g_binding_unbind() when the source and target are the same
authorGarrett Regier <garrettregier@gmail.com>
Thu, 14 May 2015 05:15:27 +0000 (22:15 -0700)
committerGarrett Regier <garrettregier@gmail.com>
Thu, 14 May 2015 10:58:53 +0000 (03:58 -0700)
It tried to remove a weak ref, but it is only taken if the
source and target object are different.

https://bugzilla.gnome.org/show_bug.cgi?id=749352

gobject/gbinding.c
gobject/tests/binding.c

index 7bcdb4c..f9afaad 100644 (file)
@@ -438,6 +438,8 @@ static inline void
 g_binding_unbind_internal (GBinding *binding,
                            gboolean  unref_binding)
 {
+  gboolean source_is_target = binding->source == binding->target;
+
   /* dispose of the transformation data */
   if (binding->notify != NULL)
     {
@@ -464,8 +466,11 @@ g_binding_unbind_internal (GBinding *binding,
       if (binding->target_notify != 0)
         g_signal_handler_disconnect (binding->target, binding->target_notify);
 
-      g_object_weak_unref (binding->target, weak_unbind, binding);
-      remove_binding_qdata (binding->target, binding);
+      if (!source_is_target)
+        {
+          g_object_weak_unref (binding->target, weak_unbind, binding);
+          remove_binding_qdata (binding->target, binding);
+        }
 
       binding->target_notify = 0;
       binding->target = NULL;
index ac82f6d..b327faf 100644 (file)
@@ -610,6 +610,19 @@ binding_unbind (void)
 
   g_object_unref (source);
   g_object_unref (target);
+
+
+  /* g_binding_unbind() has a special case for this */
+  source = g_object_new (binding_source_get_type (), NULL);
+  binding = g_object_bind_property (source, "foo",
+                                    source, "bar",
+                                    G_BINDING_DEFAULT);
+  g_object_add_weak_pointer (G_OBJECT (binding), (gpointer *) &binding);
+
+  g_binding_unbind (binding);
+  g_assert (binding == NULL);
+
+  g_object_unref (source);
 }
 
 static void