mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-02 20:16:52 +02:00
gdataset: add "already_locked" argument to g_datalist_id_update_atomic()
This allows the caller to take the lock on the GData first, and perform some operations. This is useful under the assumption, that the caller can find cases where calling g_datalist_id_update_atomic() is unnecessary, but it's still necessary to perform that check while holding a lock. That will yield better performance, if we can avoid calling g_datalist_id_update_atomic(). That matters for checking the toggle-notify in g_object_ref()/g_object_unref(). Note that with "already_locked", g_datalist_id_update_atomic() will still unlock the GData at the end. That is because the API of g_datalist_id_update_atomic() requires that it might re-allocate the buffer, and it can do a more efficient unlock in that case, instead of leaving it to the caller. The usage and purpose of this parameter is very special, so this asymmetry is taken because the only callers will be fine with this behavior, and it results in potentially more efficient unlocking.
This commit is contained in:
parent
cb5c1cf60a
commit
6fc7abe5c0
@ -1051,6 +1051,11 @@ g_datalist_id_remove_no_notify (GData **datalist,
|
||||
* g_datalist_id_update_atomic:
|
||||
* @datalist: the data list
|
||||
* @key_id: the key to add.
|
||||
* @already_locked: if TRUE, the caller already called g_datalist_lock(). Note
|
||||
* that the function will always unlock at the end. That is because the
|
||||
* function may need to reset the pointer, which is most efficiently done
|
||||
* with g_datalist_unlock_and_set(). This adds an asymmetry, but the usage
|
||||
* of this is very peculiar anyway.
|
||||
* @callback: (scope call): callback to update (set, remove, steal, update) the
|
||||
* data.
|
||||
* @user_data: the user data for @callback.
|
||||
@ -1080,6 +1085,7 @@ g_datalist_id_remove_no_notify (GData **datalist,
|
||||
gpointer
|
||||
g_datalist_id_update_atomic (GData **datalist,
|
||||
GQuark key_id,
|
||||
gboolean already_locked,
|
||||
GDataListUpdateAtomicFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -1090,7 +1096,14 @@ g_datalist_id_update_atomic (GData **datalist,
|
||||
GDestroyNotify new_destroy;
|
||||
guint32 idx;
|
||||
|
||||
d = g_datalist_lock_and_get (datalist);
|
||||
if (G_UNLIKELY (already_locked))
|
||||
{
|
||||
d = G_DATALIST_GET_POINTER (datalist);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = g_datalist_lock_and_get (datalist);
|
||||
}
|
||||
|
||||
data = datalist_find (d, key_id, &idx);
|
||||
|
||||
|
@ -78,6 +78,7 @@ typedef gpointer (*GDataListUpdateAtomicFunc) (gpointer *data,
|
||||
|
||||
gpointer g_datalist_id_update_atomic (GData **datalist,
|
||||
GQuark key_id,
|
||||
gboolean already_locked,
|
||||
GDataListUpdateAtomicFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
|
@ -305,6 +305,7 @@ typedef struct {
|
||||
|
||||
gpointer (*g_datalist_id_update_atomic) (GData **datalist,
|
||||
GQuark key_id,
|
||||
gboolean already_locked,
|
||||
GDataListUpdateAtomicFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
@ -345,7 +346,10 @@ guint g_uint_hash (gconstpointer v);
|
||||
#endif
|
||||
|
||||
/* Convenience wrapper to call private g_datalist_id_update_atomic() function. */
|
||||
#define _g_datalist_id_update_atomic_full(datalist, key_id, already_locked, callback, user_data) \
|
||||
(GLIB_PRIVATE_CALL (g_datalist_id_update_atomic) ((datalist), (key_id), (already_locked), (callback), (user_data)))
|
||||
|
||||
#define _g_datalist_id_update_atomic(datalist, key_id, callback, user_data) \
|
||||
(GLIB_PRIVATE_CALL (g_datalist_id_update_atomic) ((datalist), (key_id), (callback), (user_data)))
|
||||
_g_datalist_id_update_atomic_full((datalist), (key_id), FALSE, (callback), (user_data))
|
||||
|
||||
#endif /* __GLIB_PRIVATE_H__ */
|
||||
|
@ -235,10 +235,11 @@ static GQuark quark_weak_locations = 0;
|
||||
|
||||
static gpointer (*_local_g_datalist_id_update_atomic) (GData **datalist,
|
||||
GQuark key_id,
|
||||
gboolean already_locked,
|
||||
GDataListUpdateAtomicFunc callback,
|
||||
gpointer user_data) = NULL;
|
||||
#undef _g_datalist_id_update_atomic
|
||||
#define _g_datalist_id_update_atomic(...) ((_local_g_datalist_id_update_atomic) (__VA_ARGS__))
|
||||
#undef _g_datalist_id_update_atomic_full
|
||||
#define _g_datalist_id_update_atomic_full(...) ((_local_g_datalist_id_update_atomic) (__VA_ARGS__))
|
||||
|
||||
#if HAVE_PRIVATE
|
||||
G_ALWAYS_INLINE static inline GObjectPrivate *
|
||||
|
Loading…
x
Reference in New Issue
Block a user