[gtk/prop-list: 11/179] expression: Invalidate bindings before destroying them



commit a2db60d153ea33e03af599d85c6019f7204c7d6e
Author: Benjamin Otte <otte redhat com>
Date:   Tue Nov 26 03:57:40 2019 +0100

    expression: Invalidate bindings before destroying them
    
    Use a weak ref to invalidate bindings. Make sure that this happens
    before creating any watches, so that notifies from the
    watched expression about changes will not trigger set_property() calls
    during dispose()/finalize().
    
    Invalidating also ensures that the watches aren't removed, which can
    trigger warnings if the watches are watching the object itself, and the
    weak refs cannot be removed anymore.

 gtk/gtkexpression.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c
index b840121bfe..a6554ec7ad 100644
--- a/gtk/gtkexpression.c
+++ b/gtk/gtkexpression.c
@@ -1267,6 +1267,21 @@ typedef struct {
   GParamSpec *pspec;
 } GtkExpressionBind;
 
+static void
+invalidate_binds (gpointer unused,
+                  GObject *object)
+{
+  GSList *l, *binds;
+
+  binds = g_object_get_data (object, "gtk-expression-binds");
+  for (l = binds; l; l = l->next)
+    {
+      GtkExpressionBind *bind = l->data;
+
+      bind->object = NULL;
+    }
+}
+
 static void
 free_binds (gpointer data)
 {
@@ -1294,6 +1309,8 @@ gtk_expression_bind_free (gpointer data)
       binds = g_slist_remove (binds, bind);
       if (binds)
         g_object_set_data_full (bind->object, "gtk-expression-binds", binds, free_binds);
+      else
+        g_object_weak_unref (bind->object, invalidate_binds, NULL);
     }
   gtk_expression_unref (bind->expression);
 
@@ -1306,6 +1323,9 @@ gtk_expression_bind_notify (gpointer data)
   GValue value = G_VALUE_INIT;
   GtkExpressionBind *bind = data;
 
+  if (bind->object == NULL)
+    return;
+
   if (!gtk_expression_evaluate (bind->expression, bind->object, &value))
     return;
 
@@ -1361,6 +1381,9 @@ gtk_expression_bind (GtkExpression *self,
     }
 
   bind = g_slice_new0 (GtkExpressionBind);
+  binds = g_object_steal_data (object, "gtk-expression-binds");
+  if (binds == NULL)
+    g_object_weak_ref (object, invalidate_binds, NULL);
   bind->expression = self;
   bind->object = object;
   bind->pspec = pspec;
@@ -1369,7 +1392,6 @@ gtk_expression_bind (GtkExpression *self,
                                       gtk_expression_bind_notify,
                                       bind,
                                       gtk_expression_bind_free);
-  binds = g_object_steal_data (object, "gtk-expression-binds");
   binds = g_slist_prepend (binds, bind);
   g_object_set_data_full (object, "gtk-expression-binds", binds, free_binds);
 


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