mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-23 18:52:09 +01:00
gobject: rework g_object_notify_queue_add() to use g_datalist_id_update_atomic()
The goal is to drop OPTIONAL_BIT_LOCK_NOTIFY lock. This is one step. Move code inside g_datalist_id_update_atomic().
This commit is contained in:
parent
5d81e243d4
commit
7932b56c47
@ -808,54 +808,83 @@ out:
|
|||||||
g_object_notify_queue_free (nqueue);
|
g_object_notify_queue_free (nqueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
typedef struct
|
||||||
g_object_notify_queue_add (GObject *object,
|
|
||||||
GObjectNotifyQueue *nqueue,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gboolean in_init)
|
|
||||||
{
|
{
|
||||||
object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
GObject *object;
|
||||||
|
GObjectNotifyQueue *nqueue;
|
||||||
|
GParamSpec *pspec;
|
||||||
|
gboolean in_init;
|
||||||
|
} NotifyQueueAddData;
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
g_object_notify_queue_add_cb (gpointer *data,
|
||||||
|
GDestroyNotify *destroy_notify,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
NotifyQueueAddData *nqdata = user_data;
|
||||||
|
GObjectNotifyQueue *nqueue = *data;
|
||||||
|
|
||||||
|
#if G_ENABLE_DEBUG
|
||||||
|
g_assert (!nqdata->nqueue || nqdata->nqueue == nqueue);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!nqueue)
|
if (!nqueue)
|
||||||
{
|
{
|
||||||
/* We are called without an nqueue. Figure out whether a notification
|
if (!nqdata->in_init)
|
||||||
* should be queued. */
|
|
||||||
nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue);
|
|
||||||
|
|
||||||
if (!nqueue)
|
|
||||||
{
|
{
|
||||||
if (!in_init)
|
/* We are not in-init and are currently not frozen. There is nothing
|
||||||
{
|
* to do. We return FALSE to the caller, which then will dispatch
|
||||||
/* We don't have a notify queue and are not in_init. The event
|
* the event right away. */
|
||||||
* is not to be queued. The caller will dispatch directly. */
|
return GINT_TO_POINTER (FALSE);
|
||||||
object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We are "in_init", but did not freeze the queue in g_object_init
|
|
||||||
* yet. Instead, we gained a notify handler in instance init, so now
|
|
||||||
* we need to freeze just-in-time.
|
|
||||||
*
|
|
||||||
* Note that this freeze will be balanced at the end of object
|
|
||||||
* initialization.
|
|
||||||
*/
|
|
||||||
nqueue = g_object_notify_queue_new_frozen ();
|
|
||||||
g_datalist_id_set_data_full (&object->qdata, quark_notify_queue,
|
|
||||||
nqueue, g_object_notify_queue_free);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we are "in_init", we always want to create a queue now.
|
||||||
|
*
|
||||||
|
* Note in that case, the freeze will be balanced at the end of object
|
||||||
|
* initialization.
|
||||||
|
*
|
||||||
|
* We only ensure that a nqueue exists. If it doesn't exist, we create
|
||||||
|
* it (and freeze once). If it already exists (and is frozen), we don't
|
||||||
|
* freeze an additional time. */
|
||||||
|
nqueue = g_object_notify_queue_new_frozen ();
|
||||||
|
*data = nqueue;
|
||||||
|
*destroy_notify = g_object_notify_queue_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (nqueue->n_pspecs < 65535);
|
g_assert (nqueue->n_pspecs < 65535);
|
||||||
|
|
||||||
if (g_slist_find (nqueue->pspecs, pspec) == NULL)
|
if (!g_slist_find (nqueue->pspecs, nqdata->pspec))
|
||||||
{
|
{
|
||||||
nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
|
nqueue->pspecs = g_slist_prepend (nqueue->pspecs, nqdata->pspec);
|
||||||
nqueue->n_pspecs++;
|
nqueue->n_pspecs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GINT_TO_POINTER (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
g_object_notify_queue_add (GObject *object,
|
||||||
|
GObjectNotifyQueue *nqueue,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
gboolean in_init)
|
||||||
|
{
|
||||||
|
gpointer result;
|
||||||
|
|
||||||
|
object_bit_lock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
||||||
|
|
||||||
|
result = _g_datalist_id_update_atomic (&object->qdata,
|
||||||
|
quark_notify_queue,
|
||||||
|
g_object_notify_queue_add_cb,
|
||||||
|
&((NotifyQueueAddData){
|
||||||
|
.object = object,
|
||||||
|
.nqueue = nqueue,
|
||||||
|
.pspec = pspec,
|
||||||
|
.in_init = in_init,
|
||||||
|
}));
|
||||||
|
|
||||||
object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
object_bit_unlock (object, OPTIONAL_BIT_LOCK_NOTIFY);
|
||||||
|
|
||||||
return TRUE;
|
return GPOINTER_TO_INT (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user