mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-24 22:46:15 +01:00
c4c76d77cb
The existing g_pointer_bit_lock() and g_pointer_bit_unlock() API requires the user to understand/reimplement how bits of the pointer get mangled. Add helper functions for that. The useful thing to do with g_pointer_bit_lock() API is to get/set pointers while having it locked. For example, to set the pointer a user can do: g_pointer_bit_lock (&lockptr, lock_bit); ptr2 = set_bit_pointer_as_if_locked(ptr, lock_bit); g_atomic_pointer_set (&lockptr, ptr2); g_pointer_bit_unlock (&lockptr, lock_bit); That has several problems: - it requires one extra atomic operations (3 instead of 2, in the non-contended case). - the first g_atomic_pointer_set() already wakes blocked threads, which find themselves still being locked and needs to go back to sleep. - the user needs to re-implement how bit-locking mangles the pointer so that it looks as if it were locked. - while the user tries to re-implement what glib does to mangle the pointer for bitlocking, there is no immediate guarantee that they get it right. Now we can do instead: g_pointer_bit_lock(&lockptr, lock_bit); g_pointer_bit_unlock_and_set(&lockptr, lock_bit, ptr, 0); This will also emit a critical if @ptr has the locked bit set. g_pointer_bit_lock() really only works with pointers that have a certain alignment, and the lowest bits unset. Otherwise, there is no space to encode both the locking and all pointer values. The new assertion helps to catch such bugs. Also, g_pointer_bit_lock_mask_ptr() is here, so we can do: g_pointer_bit_lock(&lockptr, lock_bit); /* set a pointer separately, when g_pointer_bit_unlock_and_set() is unsuitable. */ g_atomic_pointer_set(&lockptr, g_pointer_bit_lock_mask_ptr(ptr, lock_bit, TRUE, 0, NULL)); ... g_pointer_bit_unlock(&lockptr, lock_bit); and: g_pointer_bit_lock(&lockptr, lock_bit); /* read the real pointer after getting the lock. */ ptr = g_pointer_bit_lock_mask_ptr(lockptr, lock_bit, FALSE, 0, NULL)); ... g_pointer_bit_unlock(&lockptr, lock_bit); |
||
---|---|---|
.. | ||
performance | ||
accumulator.c | ||
autoptr.c | ||
basic-signals.c | ||
basics-gobject.c | ||
binding.c | ||
bindinggroup.c | ||
boxed.c | ||
closure-refcount.c | ||
closure.c | ||
custom-dispatch.c | ||
cxx.cpp | ||
defaultiface.c | ||
deftype.c | ||
deprecated-properties.c | ||
dynamictests.c | ||
dynamictype.c | ||
enums.c | ||
flags.c | ||
genmarshal.py | ||
gobject-query.py | ||
ifaceproperties.c | ||
marshalers.list | ||
max-version.c | ||
meson.build | ||
mkenums.py | ||
notify-init2.c | ||
notify-init.c | ||
object.c | ||
objects-refcount1.c | ||
objects-refcount2.c | ||
override.c | ||
param.c | ||
private.c | ||
properties-introspection.c | ||
properties-refcount1.c | ||
properties-refcount2.c | ||
properties-refcount3.c | ||
properties-refcount4.c | ||
properties.c | ||
qdata.c | ||
reference.c | ||
references.c | ||
signal-handler.c | ||
signalgroup.c | ||
signals-refcount.c | ||
signals.c | ||
singleton.c | ||
taptestrunner.py | ||
testcommon.h | ||
testing.c | ||
testmodule.c | ||
testmodule.h | ||
threadtests.c | ||
type-flags.c | ||
type.c | ||
value.c |