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
This commit is contained in:
Marco Trevisan (Treviño) 2021-09-15 22:02:09 +02:00
parent e861f60dcb
commit a7262d6357
2 changed files with 28 additions and 1 deletions

View File

@ -1179,6 +1179,7 @@ g_object_real_dispose (GObject *object)
g_signal_handlers_destroy (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_closure_array, NULL);
g_datalist_id_set_data (&object->qdata, quark_weak_refs, 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 static void
@ -3574,6 +3575,7 @@ g_object_unref (gpointer _object)
g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL); g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);
g_signal_handlers_destroy (object); 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_refs, NULL);
g_datalist_id_set_data (&object->qdata, quark_weak_locations, NULL);
/* decrement the last reference */ /* decrement the last reference */
old_ref = g_atomic_int_add (&object->ref_count, -1); old_ref = g_atomic_int_add (&object->ref_count, -1);

View File

@ -600,6 +600,8 @@ weak_reffed_object_dispose (GObject *object)
g_weak_ref_set (weak_reffed->weak_ref, object); g_weak_ref_set (weak_reffed->weak_ref, object);
G_OBJECT_CLASS (weak_reffed_object_parent_class)->dispose (object); G_OBJECT_CLASS (weak_reffed_object_parent_class)->dispose (object);
g_assert_null (g_weak_ref_get (weak_reffed->weak_ref));
} }
static void static void
@ -635,6 +637,28 @@ test_weak_ref_on_dispose (void)
g_assert_null (g_weak_ref_get (&weak)); g_assert_null (g_weak_ref_get (&weak));
} }
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 static void
on_weak_ref_toggle_notify (gpointer data, on_weak_ref_toggle_notify (gpointer data,
GObject *object, GObject *object,
@ -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-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", 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-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/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/toggle-ref", test_toggle_ref);
g_test_add_func ("/object/qdata", test_object_qdata); g_test_add_func ("/object/qdata", test_object_qdata);