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:
Ryan Lortie 2010-10-26 11:49:32 -04:00
parent e0caf4fd5e
commit 181982c47c

View File

@ -847,41 +847,50 @@ GVariant *
g_variant_get_child_value (GVariant *value,
gsize index_)
{
GVariant *child = NULL;
g_variant_lock (value);
if (value->state & STATE_SERIALISED)
if (~g_atomic_int_get (&value->state) & STATE_SERIALISED)
{
GVariantSerialised serialised = {
value->type_info,
(gpointer) value->contents.serialised.data,
value->size
};
GVariantSerialised s_child;
g_variant_lock (value);
/* 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_);
if (~value->state & STATE_SERIALISED)
{
GVariant *child;
/* 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;
}
else
child = g_variant_ref (value->contents.tree.children[index_]);
child = g_variant_ref (value->contents.tree.children[index_]);
g_variant_unlock (value);
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;
}
}
/**