mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-23 15:49:16 +02: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:
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user