mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
gobject: Cleanup weak locations when the last one has been removed
As per the previous change, an object that had weak locations set may need to lock again the weak locations mutex during qdata cleanup, but we can avoid this when we know we're removing the last location, by removing the qdata entry and freeing the data. In case a new location is needed for the same object, new data will be added. However, by doing this the weak locations during dispose may be invalidated once the weak locations lock is passed, so check again if this is the case while removing them.
This commit is contained in:
parent
ea68b22135
commit
e861f60dcb
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user