gobject: rework g_object_add_toggle_ref() to use g_datalist_id_update_atomic()

This commit is contained in:
Thomas Haller 2024-01-30 12:48:19 +01:00
parent 50b5ea1781
commit d37a899d68

View File

@ -4091,12 +4091,22 @@ g_object_force_floating (GObject *object)
floating_flag_handler (object, +1); floating_flag_handler (object, +1);
} }
typedef struct { typedef struct
guint n_toggle_refs; {
struct {
GToggleNotify notify; GToggleNotify notify;
gpointer data; gpointer data;
} toggle_refs[1]; /* flexible array */ } ToggleRefTuple;
typedef struct
{
GObject *object;
ToggleRefTuple tuple;
} ToggleRefCallbackData;
typedef struct
{
guint n_toggle_refs;
ToggleRefTuple toggle_refs[1]; /* flexible array */
} ToggleRefStack; } ToggleRefStack;
static gpointer static gpointer
@ -4202,6 +4212,38 @@ toggle_refs_check_and_ref_or_deref (GObject *object,
return TRUE; return TRUE;
} }
static gpointer
toggle_refs_ref_cb (gpointer *data,
GDestroyNotify *destroy_notify,
gpointer user_data)
{
ToggleRefCallbackData *trdata = user_data;
ToggleRefStack *tstack = *data;
guint i;
if (!tstack)
{
tstack = g_new (ToggleRefStack, 1);
tstack->n_toggle_refs = 1;
i = 0;
g_datalist_set_flags (&trdata->object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG);
*destroy_notify = g_free;
}
else
{
i = tstack->n_toggle_refs++;
tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i);
}
*data = tstack;
tstack->toggle_refs[i] = trdata->tuple;
return NULL;
}
/** /**
* g_object_add_toggle_ref: (skip) * g_object_add_toggle_ref: (skip)
* @object: a #GObject * @object: a #GObject
@ -4253,9 +4295,6 @@ g_object_add_toggle_ref (GObject *object,
GToggleNotify notify, GToggleNotify notify,
gpointer data) gpointer data)
{ {
ToggleRefStack *tstack;
guint i;
g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (G_IS_OBJECT (object));
g_return_if_fail (notify != NULL); g_return_if_fail (notify != NULL);
g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1); g_return_if_fail (g_atomic_int_get (&object->ref_count) >= 1);
@ -4263,29 +4302,16 @@ g_object_add_toggle_ref (GObject *object,
g_object_ref (object); g_object_ref (object);
object_bit_lock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS); object_bit_lock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
tstack = g_datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs);
if (tstack)
{
i = tstack->n_toggle_refs++;
/* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared
* in tstate->toggle_refs */
tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i);
}
else
{
tstack = g_renew (ToggleRefStack, NULL, 1);
tstack->n_toggle_refs = 1;
i = 0;
}
/* Set a flag for fast lookup after adding the first toggle reference */ _g_datalist_id_update_atomic (&object->qdata,
if (tstack->n_toggle_refs == 1) quark_toggle_refs,
g_datalist_set_flags (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG); toggle_refs_ref_cb,
&((ToggleRefCallbackData){
.object = object,
.tuple.notify = notify,
.tuple.data = data,
}));
tstack->toggle_refs[i].notify = notify;
tstack->toggle_refs[i].data = data;
g_datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack,
(GDestroyNotify)g_free);
object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS); object_bit_unlock (object, OPTIONAL_BIT_LOCK_TOGGLE_REFS);
} }