mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-05 10:38:08 +01:00
gobject: rework g_object_notify_queue_freeze() to use g_datalist_id_update_atomic()
A common pattern is to look whether a GData entry exists, and if it doesn't, add it. For that, we currently always must take a OPTIONAL_BIT_LOCK_NOTIFY lock. This can be avoided, because GData already uses an internal mutex. By using g_datalist_id_update_atomic(), we can perform all relevant operations while holding that mutex. Move functionality from g_object_notify_queue_freeze() inside g_datalist_id_update_atomic(). The goal will be to drop the OPTIONAL_BIT_LOCK_NOTIFY lock in a later commit.
This commit is contained in:
parent
0564abf6e0
commit
56dc2a390b
@ -667,18 +667,45 @@ g_object_notify_queue_free (gpointer data)
|
||||
}
|
||||
|
||||
static GObjectNotifyQueue *
|
||||
g_object_notify_queue_create_queue_frozen (GObject *object)
|
||||
g_object_notify_queue_new_frozen (void)
|
||||
{
|
||||
GObjectNotifyQueue *nqueue;
|
||||
|
||||
nqueue = g_new0 (GObjectNotifyQueue, 1);
|
||||
|
||||
nqueue = g_new (GObjectNotifyQueue, 1);
|
||||
*nqueue = (GObjectNotifyQueue){
|
||||
.freeze_count = 1,
|
||||
};
|
||||
|
||||
g_datalist_id_set_data_full (&object->qdata, quark_notify_queue,
|
||||
nqueue, g_object_notify_queue_free);
|
||||
return nqueue;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
g_object_notify_queue_freeze_cb (gpointer *data,
|
||||
GDestroyNotify *destroy_notify,
|
||||
gpointer user_data)
|
||||
{
|
||||
GObject *object = user_data;
|
||||
GObjectNotifyQueue *nqueue = *data;
|
||||
|
||||
if (!nqueue)
|
||||
{
|
||||
/* The nqueue doesn't exist yet. We create it, and freeze thus 1 time. */
|
||||
nqueue = g_object_notify_queue_new_frozen ();
|
||||
*data = nqueue;
|
||||
*destroy_notify = g_object_notify_queue_free;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nqueue->freeze_count >= 65535)
|
||||
{
|
||||
g_critical ("Free queue for %s (%p) is larger than 65535,"
|
||||
" called g_object_freeze_notify() too often."
|
||||
" Forgot to call g_object_thaw_notify() or infinite loop",
|
||||
G_OBJECT_TYPE_NAME (object), object);
|
||||
}
|
||||
else
|
||||
nqueue->freeze_count++;
|
||||
}
|
||||
|
||||
return nqueue;
|
||||
}
|
||||
@ -689,24 +716,11 @@ g_object_notify_queue_freeze (GObject *object)
|
||||
GObjectNotifyQueue *nqueue;
|
||||
|
||||
object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
||||
nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue);
|
||||
if (!nqueue)
|
||||
{
|
||||
nqueue = g_object_notify_queue_create_queue_frozen (object);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nqueue->freeze_count >= 65535)
|
||||
g_critical("Free queue for %s (%p) is larger than 65535,"
|
||||
" called g_object_freeze_notify() too often."
|
||||
" Forgot to call g_object_thaw_notify() or infinite loop",
|
||||
G_OBJECT_TYPE_NAME (object), object);
|
||||
else
|
||||
nqueue->freeze_count++;
|
||||
|
||||
out:
|
||||
nqueue = _g_datalist_id_update_atomic (&object->qdata,
|
||||
quark_notify_queue,
|
||||
g_object_notify_queue_freeze_cb,
|
||||
object);
|
||||
object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
||||
|
||||
return nqueue;
|
||||
}
|
||||
|
||||
@ -797,7 +811,9 @@ g_object_notify_queue_add (GObject *object,
|
||||
* Note that this freeze will be balanced at the end of object
|
||||
* initialization.
|
||||
*/
|
||||
nqueue = g_object_notify_queue_create_queue_frozen (object);
|
||||
nqueue = g_object_notify_queue_new_frozen ();
|
||||
g_datalist_id_set_data_full (&object->qdata, quark_notify_queue,
|
||||
nqueue, g_object_notify_queue_free);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user