mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 19:22:11 +01:00
gobject: factor out toggle_refs_get_notify_unlocked() function
This is the part of toggle_refs_notify(), for which we usually hold the lock. It will be used next.
This commit is contained in:
parent
2276099236
commit
b2a68d6ec4
@ -3574,32 +3574,45 @@ typedef struct {
|
|||||||
} toggle_refs[1]; /* flexible array */
|
} toggle_refs[1]; /* flexible array */
|
||||||
} ToggleRefStack;
|
} ToggleRefStack;
|
||||||
|
|
||||||
|
static GToggleNotify
|
||||||
|
toggle_refs_get_notify_unlocked (GObject *object,
|
||||||
|
gpointer *out_data)
|
||||||
|
{
|
||||||
|
ToggleRefStack *tstackptr;
|
||||||
|
|
||||||
|
if (!OBJECT_HAS_TOGGLE_REF (object))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
tstackptr = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
|
||||||
|
|
||||||
|
if (tstackptr->n_toggle_refs != 1)
|
||||||
|
{
|
||||||
|
/* There are multiple references. We won't notify.
|
||||||
|
*
|
||||||
|
* Note that the user MUST pair g_object_add_toggle_ref() with
|
||||||
|
* g_object_remove_toggle_ref(). In that case, having a
|
||||||
|
* "n_toggle_refs" larger than one, also means that we have multiple
|
||||||
|
* references. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_data = tstackptr->toggle_refs[0].data;
|
||||||
|
return tstackptr->toggle_refs[0].notify;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
toggle_refs_notify (GObject *object,
|
toggle_refs_notify (GObject *object,
|
||||||
gboolean is_last_ref)
|
gboolean is_last_ref)
|
||||||
{
|
{
|
||||||
ToggleRefStack tstack, *tstackptr;
|
GToggleNotify notify;
|
||||||
|
gpointer data;
|
||||||
|
|
||||||
G_LOCK (toggle_refs_mutex);
|
G_LOCK (toggle_refs_mutex);
|
||||||
/* If another thread removed the toggle reference on the object, while
|
notify = toggle_refs_get_notify_unlocked (object, &data);
|
||||||
* we were waiting here, there's nothing to notify.
|
|
||||||
* So let's check again if the object has toggle reference and in case return.
|
|
||||||
*/
|
|
||||||
if (!OBJECT_HAS_TOGGLE_REF (object))
|
|
||||||
{
|
|
||||||
G_UNLOCK (toggle_refs_mutex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tstackptr = g_datalist_id_get_data (&object->qdata, quark_toggle_refs);
|
|
||||||
tstack = *tstackptr;
|
|
||||||
G_UNLOCK (toggle_refs_mutex);
|
G_UNLOCK (toggle_refs_mutex);
|
||||||
|
|
||||||
/* Reentrancy here is not as tricky as it seems, because a toggle reference
|
if (notify)
|
||||||
* will only be notified when there is exactly one of them.
|
notify (data, object, is_last_ref);
|
||||||
*/
|
|
||||||
g_assert (tstack.n_toggle_refs == 1);
|
|
||||||
tstack.toggle_refs[0].notify (tstack.toggle_refs[0].data, object, is_last_ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user