mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 18:52:09 +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
87a34c37a7
commit
626b6518b3
@ -667,18 +667,45 @@ g_object_notify_queue_free (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GObjectNotifyQueue *
|
static GObjectNotifyQueue *
|
||||||
g_object_notify_queue_create_queue_frozen (GObject *object)
|
g_object_notify_queue_new_frozen (void)
|
||||||
{
|
{
|
||||||
GObjectNotifyQueue *nqueue;
|
GObjectNotifyQueue *nqueue;
|
||||||
|
|
||||||
nqueue = g_new0 (GObjectNotifyQueue, 1);
|
nqueue = g_new (GObjectNotifyQueue, 1);
|
||||||
|
|
||||||
*nqueue = (GObjectNotifyQueue){
|
*nqueue = (GObjectNotifyQueue){
|
||||||
.freeze_count = 1,
|
.freeze_count = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
g_datalist_id_set_data_full (&object->qdata, quark_notify_queue,
|
return nqueue;
|
||||||
nqueue, g_object_notify_queue_free);
|
}
|
||||||
|
|
||||||
|
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;
|
return nqueue;
|
||||||
}
|
}
|
||||||
@ -689,24 +716,11 @@ g_object_notify_queue_freeze (GObject *object)
|
|||||||
GObjectNotifyQueue *nqueue;
|
GObjectNotifyQueue *nqueue;
|
||||||
|
|
||||||
object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
||||||
nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue);
|
nqueue = _g_datalist_id_update_atomic (&object->qdata,
|
||||||
if (!nqueue)
|
quark_notify_queue,
|
||||||
{
|
g_object_notify_queue_freeze_cb,
|
||||||
nqueue = g_object_notify_queue_create_queue_frozen (object);
|
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:
|
|
||||||
object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
||||||
|
|
||||||
return nqueue;
|
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
|
* Note that this freeze will be balanced at the end of object
|
||||||
* initialization.
|
* 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