mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
g_object_unref racy condition can lead to crash
Store whether the object has a toggleref before decrementing the refcount to prevent race condition when two threads simultaneously try to unref an object with a refcount of 2. Patch by Antoine Tremblay. https://bugzilla.gnome.org/show_bug.cgi?id=551706
This commit is contained in:
parent
afa0db59df
commit
855deaa578
@ -2425,11 +2425,14 @@ g_object_unref (gpointer _object)
|
|||||||
old_ref = g_atomic_int_get (&object->ref_count);
|
old_ref = g_atomic_int_get (&object->ref_count);
|
||||||
if (old_ref > 1)
|
if (old_ref > 1)
|
||||||
{
|
{
|
||||||
|
/* valid if last 2 refs are owned by this call to unref and the toggle_ref */
|
||||||
|
gboolean has_toggle_ref = OBJECT_HAS_TOGGLE_REF (object);
|
||||||
|
|
||||||
if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1))
|
if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1))
|
||||||
goto retry_atomic_decrement1;
|
goto retry_atomic_decrement1;
|
||||||
|
|
||||||
/* if we went from 2->1 we need to notify toggle refs if any */
|
/* if we went from 2->1 we need to notify toggle refs if any */
|
||||||
if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
|
if (old_ref == 2 && has_toggle_ref) /* The last ref being held in this case is owned by the toggle_ref */
|
||||||
toggle_refs_notify (object, TRUE);
|
toggle_refs_notify (object, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2442,11 +2445,14 @@ g_object_unref (gpointer _object)
|
|||||||
old_ref = g_atomic_int_get ((int *)&object->ref_count);
|
old_ref = g_atomic_int_get ((int *)&object->ref_count);
|
||||||
if (old_ref > 1)
|
if (old_ref > 1)
|
||||||
{
|
{
|
||||||
|
/* valid if last 2 refs are owned by this call to unref and the toggle_ref */
|
||||||
|
gboolean has_toggle_ref = OBJECT_HAS_TOGGLE_REF (object);
|
||||||
|
|
||||||
if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1))
|
if (!g_atomic_int_compare_and_exchange ((int *)&object->ref_count, old_ref, old_ref - 1))
|
||||||
goto retry_atomic_decrement2;
|
goto retry_atomic_decrement2;
|
||||||
|
|
||||||
/* if we went from 2->1 we need to notify toggle refs if any */
|
/* if we went from 2->1 we need to notify toggle refs if any */
|
||||||
if (old_ref == 2 && OBJECT_HAS_TOGGLE_REF (object))
|
if (old_ref == 2 && has_toggle_ref) /* The last ref being held in this case is owned by the toggle_ref */
|
||||||
toggle_refs_notify (object, TRUE);
|
toggle_refs_notify (object, TRUE);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user