[glib] g_object_unref racy condition can lead to crash
- From: Cody Russell <bratsche src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib] g_object_unref racy condition can lead to crash
- Date: Tue, 6 Oct 2009 16:30:51 +0000 (UTC)
commit 855deaa5780bfef3f6e8b3a41d00d6c7e40ca406
Author: Cody Russell <bratsche gnome org>
Date: Tue Oct 6 12:27:12 2009 -0400
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
gobject/gobject.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 8432488..f906d31 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -2425,11 +2425,14 @@ g_object_unref (gpointer _object)
old_ref = g_atomic_int_get (&object->ref_count);
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))
goto retry_atomic_decrement1;
/* 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);
}
else
@@ -2442,13 +2445,16 @@ g_object_unref (gpointer _object)
old_ref = g_atomic_int_get ((int *)&object->ref_count);
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))
goto retry_atomic_decrement2;
/* 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);
-
+
return;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]