mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 16:32:18 +01:00 
			
		
		
		
	gobject: drop OPTIONAL_BIT_LOCK_WEAK_REFS bit lock
With the previous changes, all accesses to the WeakRefStack go through
g_datalist_id_update_atomic() and are guarded by the GData's bit lock.
At this point, the OPTIONAL_BIT_LOCK_WEAK_REFS lock is unnecessary and
can be dropped.
A minor benefit is that g_object_weak_{ref,unref}() needs now one lock
less.
Also note that this rework fixes a potential race for weak refs. Note
that we have two calls
  g_datalist_id_set_data (&object->qdata, quark_weak_notifies, NULL);
that don't take OPTIONAL_BIT_LOCK_WEAK_REFS lock. One of these calls is
right before finalize(). At that point, no other thread can hold a
reference to the object to race and we are good. However, the other call
is from g_object_real_dispose(). At that point, theoretically the object
could have been resurrected and a pointer could have been passed to
another thread. Calling then g_object_weak_ref()/g_object_weak_unref()
will race. We would have required a OPTIONAL_BIT_LOCK_WEAK_REFS lock
around those g_datalist_id_set_data(,,NULL) calls.
Instead, this is now also fixed, because every update to the
WeakRefStack happens while holding the GData lock. So if you call
g_datalist_id_set_data(,,NULL), the WeakRefStack is removed from the
GData (and later freed by weak_refs_notify() and can no longer
concurrently updated by g_object_weak_{ref,unref}().
			
			
This commit is contained in:
		
				
					committed by
					
						 Philip Withnall
						Philip Withnall
					
				
			
			
				
	
			
			
			
						parent
						
							5da7ed2bc9
						
					
				
				
					commit
					93b5b8a051
				
			| @@ -124,9 +124,8 @@ enum { | ||||
|  * parallel as possible. The alternative would be to add individual locking | ||||
|  * integers to GObjectPrivate. But increasing memory usage for more parallelism | ||||
|  * (per-object!) is not worth it. */ | ||||
| #define OPTIONAL_BIT_LOCK_WEAK_REFS      1 | ||||
| #define OPTIONAL_BIT_LOCK_NOTIFY         2 | ||||
| #define OPTIONAL_BIT_LOCK_TOGGLE_REFS    3 | ||||
| #define OPTIONAL_BIT_LOCK_NOTIFY 1 | ||||
| #define OPTIONAL_BIT_LOCK_TOGGLE_REFS 2 | ||||
|  | ||||
| #if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P >= 8 | ||||
| #define HAVE_OPTIONAL_FLAGS_IN_GOBJECT 1 | ||||
| @@ -3732,12 +3731,10 @@ g_object_weak_ref (GObject    *object, | ||||
|   g_return_if_fail (notify != NULL); | ||||
|   g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1); | ||||
|  | ||||
|   object_bit_lock (object, OPTIONAL_BIT_LOCK_WEAK_REFS); | ||||
|   _g_datalist_id_update_atomic (&object->qdata, | ||||
|                                 quark_weak_notifies, | ||||
|                                 g_object_weak_ref_cb, | ||||
|                                 ((gpointer[]){ object, notify, data })); | ||||
|   object_bit_unlock (object, OPTIONAL_BIT_LOCK_WEAK_REFS); | ||||
| } | ||||
|  | ||||
| static gpointer | ||||
| @@ -3795,12 +3792,10 @@ g_object_weak_unref (GObject    *object, | ||||
|   g_return_if_fail (G_IS_OBJECT (object)); | ||||
|   g_return_if_fail (notify != NULL); | ||||
|  | ||||
|   object_bit_lock (object, OPTIONAL_BIT_LOCK_WEAK_REFS); | ||||
|   _g_datalist_id_update_atomic (&object->qdata, | ||||
|                                 quark_weak_notifies, | ||||
|                                 g_object_weak_unref_cb, | ||||
|                                 ((gpointer[]){ notify, data })); | ||||
|   object_bit_unlock (object, OPTIONAL_BIT_LOCK_WEAK_REFS); | ||||
| } | ||||
|  | ||||
| /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user