[glib] GVariant: avoid locking in a common case
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GVariant: avoid locking in a common case
- Date: Tue, 26 Oct 2010 15:52:18 +0000 (UTC)
commit 181982c47cde49b3aff2293729f5aee5987db8af
Author: Ryan Lortie <desrt desrt ca>
Date: Tue Oct 26 11:49:32 2010 -0400
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
glib/gvariant-core.c | 69 ++++++++++++++++++++++++++++---------------------
1 files changed, 39 insertions(+), 30 deletions(-)
---
diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
index 6f01930..d783053 100644
--- a/glib/gvariant-core.c
+++ b/glib/gvariant-core.c
@@ -847,41 +847,50 @@ GVariant *
g_variant_get_child_value (GVariant *value,
gsize index_)
{
- GVariant *child = NULL;
+ if (~g_atomic_int_get (&value->state) & STATE_SERIALISED)
+ {
+ g_variant_lock (value);
- g_variant_lock (value);
+ if (~value->state & STATE_SERIALISED)
+ {
+ GVariant *child;
- if (value->state & STATE_SERIALISED)
- {
- GVariantSerialised serialised = {
- value->type_info,
- (gpointer) value->contents.serialised.data,
- value->size
- };
- GVariantSerialised s_child;
+ child = g_variant_ref (value->contents.tree.children[index_]);
+ g_variant_unlock (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_);
-
- /* 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_]);
+ return child;
+ }
- g_variant_unlock (value);
+ g_variant_unlock (value);
+ }
- return child;
+ {
+ 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;
+ }
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]