From a94d4648c8a55bbf9d52817db305d19c581acf91 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 26 Nov 2019 03:57:40 +0100 Subject: [PATCH] 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 e7cd1fcc84..493d29da9d 100644 --- a/gtk/gtkexpression.c +++ b/gtk/gtkexpression.c @@ -1263,6 +1263,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) { @@ -1290,6 +1305,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); @@ -1302,6 +1319,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; @@ -1357,6 +1377,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; @@ -1365,7 +1388,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);