summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2021-09-15 22:02:09 +0200
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2021-09-17 12:28:01 +0200
commita7262d63576c4e4624adc1353b47146c6860be0d (patch)
treea0b0cc9f304005ef92595f8df0cae0f6538a2ddf
parente861f60dcbfc93b46623df8fccc9ce12c7f9d1e1 (diff)
downloadglib-a7262d63576c4e4624adc1353b47146c6860be0d.tar.gz
gobject: Cleanup weak locations data as part of dispose
Weak locations were not fully cleaned on run_dispose() and after dispose vfunc was called, so ensure that this is the case. Fixes: #865
-rw-r--r--gobject/gobject.c4
-rw-r--r--gobject/tests/reference.c25
2 files changed, 28 insertions, 1 deletions
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 4f4a463ef..a0685db28 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -1179,6 +1179,7 @@ g_object_real_dispose (GObject *object)
g_signal_handlers_destroy (object);
g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
+ g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
}
static void
@@ -3574,7 +3575,8 @@ g_object_unref (gpointer _object)
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);
-
+ g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
+
/* decrement the last reference */
old_ref = g_atomic_int_add (&object->ref_count, -1);
g_return_if_fail (old_ref > 0);
diff --git a/gobject/tests/reference.c b/gobject/tests/reference.c
index e84c66467..7b12ac547 100644
--- a/gobject/tests/reference.c
+++ b/gobject/tests/reference.c
@@ -600,6 +600,8 @@ weak_reffed_object_dispose (GObject *object)
g_weak_ref_set (weak_reffed->weak_ref, object);
G_OBJECT_CLASS (weak_reffed_object_parent_class)->dispose (object);
+
+ g_assert_null (g_weak_ref_get (weak_reffed->weak_ref));
}
static void
@@ -636,6 +638,28 @@ test_weak_ref_on_dispose (void)
}
static void
+test_weak_ref_on_run_dispose (void)
+{
+ GObject *obj;
+ GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
+
+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/865");
+ g_test_summary ("Test that a weak ref is cleared on g_object_run_dispose()");
+
+ obj = g_object_new (G_TYPE_OBJECT, NULL);
+ g_weak_ref_init (&weak, obj);
+
+ g_assert_true (obj == g_weak_ref_get (&weak));
+ g_object_unref (obj);
+
+ g_object_run_dispose (obj);
+ g_assert_null (g_weak_ref_get (&weak));
+
+ g_clear_object (&obj);
+ g_assert_null (g_weak_ref_get (&weak));
+}
+
+static void
on_weak_ref_toggle_notify (gpointer data,
GObject *object,
gboolean is_last_ref)
@@ -939,6 +963,7 @@ main (int argc, char **argv)
g_test_add_func ("/object/weak-pointer/set-function", test_weak_pointer_set_function);
g_test_add_func ("/object/weak-ref", test_weak_ref);
g_test_add_func ("/object/weak-ref/on-dispose", test_weak_ref_on_dispose);
+ g_test_add_func ("/object/weak-ref/on-run-dispose", test_weak_ref_on_run_dispose);
g_test_add_func ("/object/weak-ref/on-toggle-notify", test_weak_ref_on_toggle_notify);
g_test_add_func ("/object/toggle-ref", test_toggle_ref);
g_test_add_func ("/object/qdata", test_object_qdata);