diff --git a/gobject/gobject.c b/gobject/gobject.c index c558c1197..4f4a463ef 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -3536,10 +3536,11 @@ g_object_unref (gpointer _object) } /* We got the lock first, so the object will definitely die - * now. Clear out all the weak references. + * now. Clear out all the weak references, if they're still set. */ - weak_locations_free_unlocked (weak_locations); - g_datalist_id_remove_no_notify (&object->qdata, quark_weak_locations); + weak_locations = g_datalist_id_remove_no_notify (&object->qdata, + quark_weak_locations); + g_clear_pointer (&weak_locations, weak_locations_free_unlocked); g_rw_lock_writer_unlock (&weak_locations_lock); } @@ -4731,6 +4732,12 @@ g_weak_ref_set (GWeakRef *weak_ref, g_assert (weak_locations != NULL); *weak_locations = g_slist_remove (*weak_locations, weak_ref); + + if (!*weak_locations) + { + weak_locations_free_unlocked (weak_locations); + g_datalist_id_remove_no_notify (&old_object->qdata, quark_weak_locations); + } } /* Add the weak ref to the new object */ diff --git a/gobject/tests/reference.c b/gobject/tests/reference.c index de49ff1fd..e84c66467 100644 --- a/gobject/tests/reference.c +++ b/gobject/tests/reference.c @@ -558,6 +558,18 @@ test_weak_ref (void) g_weak_ref_clear (&weak3); + /* unset dynamic_weak... */ + g_weak_ref_set (dynamic_weak, NULL); + g_assert_null (g_weak_ref_get (dynamic_weak)); + + /* initializing a weak reference to an object that had before works */ + g_weak_ref_set (dynamic_weak, obj2); + tmp = g_weak_ref_get (dynamic_weak); + g_assert_true (tmp == obj2); + g_assert_cmpint (obj2->ref_count, ==, 2); + g_object_unref (tmp); + g_assert_cmpint (obj2->ref_count, ==, 1); + /* clear and free dynamic_weak... */ g_weak_ref_clear (dynamic_weak);