mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 16:32:18 +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:
		| @@ -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; | ||||
| 	} | ||||
|        | ||||
|   | ||||
		Reference in New Issue
	
	Block a user