mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-14 16:26:17 +01:00
GVariant: avoid locking in a common case
Avoid acquiring the lock on the instance on the case of deserialising a child. We know that it is safe to do this unlocked because a serialised child will never become unserialised. Closes #626320
This commit is contained in:
parent
e0caf4fd5e
commit
181982c47c
@ -847,41 +847,50 @@ GVariant *
|
|||||||
g_variant_get_child_value (GVariant *value,
|
g_variant_get_child_value (GVariant *value,
|
||||||
gsize index_)
|
gsize index_)
|
||||||
{
|
{
|
||||||
GVariant *child = NULL;
|
if (~g_atomic_int_get (&value->state) & STATE_SERIALISED)
|
||||||
|
|
||||||
g_variant_lock (value);
|
|
||||||
|
|
||||||
if (value->state & STATE_SERIALISED)
|
|
||||||
{
|
{
|
||||||
GVariantSerialised serialised = {
|
g_variant_lock (value);
|
||||||
value->type_info,
|
|
||||||
(gpointer) value->contents.serialised.data,
|
|
||||||
value->size
|
|
||||||
};
|
|
||||||
GVariantSerialised s_child;
|
|
||||||
|
|
||||||
/* get the serialiser to extract the serialised data for the child
|
if (~value->state & STATE_SERIALISED)
|
||||||
* from the serialised data for the container
|
{
|
||||||
*/
|
GVariant *child;
|
||||||
s_child = g_variant_serialised_get_child (serialised, index_);
|
|
||||||
|
|
||||||
/* create a new serialised instance out of it */
|
child = g_variant_ref (value->contents.tree.children[index_]);
|
||||||
child = g_slice_new (GVariant);
|
g_variant_unlock (value);
|
||||||
child->type_info = s_child.type_info;
|
|
||||||
child->state = (value->state & STATE_TRUSTED) |
|
|
||||||
STATE_SERIALISED;
|
|
||||||
child->size = s_child.size;
|
|
||||||
child->ref_count = 1;
|
|
||||||
child->contents.serialised.buffer =
|
|
||||||
g_buffer_ref (value->contents.serialised.buffer);
|
|
||||||
child->contents.serialised.data = s_child.data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
child = g_variant_ref (value->contents.tree.children[index_]);
|
|
||||||
|
|
||||||
g_variant_unlock (value);
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
return child;
|
g_variant_unlock (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
GVariantSerialised serialised = {
|
||||||
|
value->type_info,
|
||||||
|
(gpointer) value->contents.serialised.data,
|
||||||
|
value->size
|
||||||
|
};
|
||||||
|
GVariantSerialised s_child;
|
||||||
|
GVariant *child;
|
||||||
|
|
||||||
|
/* get the serialiser to extract the serialised data for the child
|
||||||
|
* from the serialised data for the container
|
||||||
|
*/
|
||||||
|
s_child = g_variant_serialised_get_child (serialised, index_);
|
||||||
|
|
||||||
|
/* create a new serialised instance out of it */
|
||||||
|
child = g_slice_new (GVariant);
|
||||||
|
child->type_info = s_child.type_info;
|
||||||
|
child->state = (value->state & STATE_TRUSTED) |
|
||||||
|
STATE_SERIALISED;
|
||||||
|
child->size = s_child.size;
|
||||||
|
child->ref_count = 1;
|
||||||
|
child->contents.serialised.buffer =
|
||||||
|
g_buffer_ref (value->contents.serialised.buffer);
|
||||||
|
child->contents.serialised.data = s_child.data;
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user