X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgvarianttypeinfo.c;h=b398d657a860499e66e7e7d7c1f7739202538674;hb=35eaf037bdfca985abf5d349e7355f1d2ed9c77b;hp=08439c9e0ac0394defdd1661f52905f7aa5190cd;hpb=0f246e28ca6651b7b40a5a5668b45729226ca177;p=platform%2Fupstream%2Fglib.git
diff --git a/glib/gvarianttypeinfo.c b/glib/gvarianttypeinfo.c
index 08439c9..b398d65 100644
--- a/glib/gvarianttypeinfo.c
+++ b/glib/gvarianttypeinfo.c
@@ -13,17 +13,19 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see .
*
* Author: Ryan Lortie
*/
+#include "config.h"
+
#include "gvarianttypeinfo.h"
-#include
-#include "galias.h"
+#include
+#include
+#include
+#include
/* < private >
* GVariantTypeInfo:
@@ -46,7 +48,7 @@
* for "as" (note that "s" and "v" always exist in the static array).
*
* The trickiest part of GVariantTypeInfo (and in fact, the major reason
- * for its existance) is the storage of somewhat magical constants that
+ * for its existence) is the storage of somewhat magical constants that
* allow for O(1) lookups of items in tuples. This is described below.
*
* 'container_class' is set to 'a' or 'r' if the GVariantTypeInfo is
@@ -106,33 +108,35 @@ typedef struct
/* Hard-code the base types in a constant array */
static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
#define fixed_aligned(x) x, x - 1
+#define not_a_type 0,
#define unaligned 0, 0
#define aligned(x) 0, x - 1
/* 'b' */ { fixed_aligned(1) }, /* boolean */
- /* 'c' */ { },
+ /* 'c' */ { not_a_type },
/* 'd' */ { fixed_aligned(8) }, /* double */
- /* 'e' */ { },
- /* 'f' */ { },
+ /* 'e' */ { not_a_type },
+ /* 'f' */ { not_a_type },
/* 'g' */ { unaligned }, /* signature string */
/* 'h' */ { fixed_aligned(4) }, /* file handle (int32) */
/* 'i' */ { fixed_aligned(4) }, /* int32 */
- /* 'j' */ { },
- /* 'k' */ { },
- /* 'l' */ { },
- /* 'm' */ { },
+ /* 'j' */ { not_a_type },
+ /* 'k' */ { not_a_type },
+ /* 'l' */ { not_a_type },
+ /* 'm' */ { not_a_type },
/* 'n' */ { fixed_aligned(2) }, /* int16 */
/* 'o' */ { unaligned }, /* object path string */
- /* 'p' */ { },
+ /* 'p' */ { not_a_type },
/* 'q' */ { fixed_aligned(2) }, /* uint16 */
- /* 'r' */ { },
+ /* 'r' */ { not_a_type },
/* 's' */ { unaligned }, /* string */
/* 't' */ { fixed_aligned(8) }, /* uint64 */
/* 'u' */ { fixed_aligned(4) }, /* uint32 */
/* 'v' */ { aligned(8) }, /* variant */
- /* 'w' */ { },
+ /* 'w' */ { not_a_type },
/* 'x' */ { fixed_aligned(8) }, /* int64 */
/* 'y' */ { fixed_aligned(1) }, /* byte */
#undef fixed_aligned
+#undef not_a_type
#undef unaligned
#undef aligned
};
@@ -216,8 +220,8 @@ g_variant_type_info_get_type_string (GVariantTypeInfo *info)
/* < private >
* g_variant_type_info_query:
* @info: a #GVariantTypeInfo
- * @alignment: the location to store the alignment, or %NULL
- * @fixed_size: the location to store the fixed size, or %NULL
+ * @alignment: (allow-none): the location to store the alignment, or %NULL
+ * @fixed_size: (allow-none): the location to store the fixed size, or %NULL
*
* Queries @info to determine the alignment requirements and fixed size
* (if any) of the type.
@@ -248,11 +252,11 @@ g_variant_type_info_query (GVariantTypeInfo *info,
}
/* == array == */
-#define ARRAY_INFO_CLASS 'a'
+#define GV_ARRAY_INFO_CLASS 'a'
static ArrayInfo *
-ARRAY_INFO (GVariantTypeInfo *info)
+GV_ARRAY_INFO (GVariantTypeInfo *info)
{
- g_variant_type_info_check (info, ARRAY_INFO_CLASS);
+ g_variant_type_info_check (info, GV_ARRAY_INFO_CLASS);
return (ArrayInfo *) info;
}
@@ -262,7 +266,7 @@ array_info_free (GVariantTypeInfo *info)
{
ArrayInfo *array_info;
- g_assert (info->container_class == ARRAY_INFO_CLASS);
+ g_assert (info->container_class == GV_ARRAY_INFO_CLASS);
array_info = (ArrayInfo *) info;
g_variant_type_info_unref (array_info->element);
@@ -275,7 +279,7 @@ array_info_new (const GVariantType *type)
ArrayInfo *info;
info = g_slice_new (ArrayInfo);
- info->container.info.container_class = ARRAY_INFO_CLASS;
+ info->container.info.container_class = GV_ARRAY_INFO_CLASS;
info->element = g_variant_type_info_get (g_variant_type_element (type));
info->container.info.alignment = info->element->alignment;
@@ -294,14 +298,14 @@ array_info_new (const GVariantType *type)
GVariantTypeInfo *
g_variant_type_info_element (GVariantTypeInfo *info)
{
- return ARRAY_INFO (info)->element;
+ return GV_ARRAY_INFO (info)->element;
}
/* < private >
* g_variant_type_query_element:
* @info: a #GVariantTypeInfo for an array or maybe type
- * @alignment: the location to store the alignment, or %NULL
- * @fixed_size: the location to store the fixed size, or %NULL
+ * @alignment: (allow-none): the location to store the alignment, or %NULL
+ * @fixed_size: (allow-none): the location to store the fixed size, or %NULL
*
* Returns the alignment requires and fixed size (if any) for the
* element type of the array. This call is a convenience wrapper around
@@ -312,16 +316,16 @@ g_variant_type_info_query_element (GVariantTypeInfo *info,
guint *alignment,
gsize *fixed_size)
{
- g_variant_type_info_query (ARRAY_INFO (info)->element,
+ g_variant_type_info_query (GV_ARRAY_INFO (info)->element,
alignment, fixed_size);
}
/* == tuple == */
-#define TUPLE_INFO_CLASS 'r'
+#define GV_TUPLE_INFO_CLASS 'r'
static TupleInfo *
-TUPLE_INFO (GVariantTypeInfo *info)
+GV_TUPLE_INFO (GVariantTypeInfo *info)
{
- g_variant_type_info_check (info, TUPLE_INFO_CLASS);
+ g_variant_type_info_check (info, GV_TUPLE_INFO_CLASS);
return (TupleInfo *) info;
}
@@ -332,11 +336,11 @@ tuple_info_free (GVariantTypeInfo *info)
TupleInfo *tuple_info;
gint i;
- g_assert (info->container_class == TUPLE_INFO_CLASS);
+ g_assert (info->container_class == GV_TUPLE_INFO_CLASS);
tuple_info = (TupleInfo *) info;
for (i = 0; i < tuple_info->n_members; i++)
- g_variant_type_info_unref (tuple_info->members[i].type);
+ g_variant_type_info_unref (tuple_info->members[i].type_info);
g_slice_free1 (sizeof (GVariantMemberInfo) * tuple_info->n_members,
tuple_info->members);
@@ -357,8 +361,17 @@ tuple_allocate_members (const GVariantType *type,
item_type = g_variant_type_first (type);
while (item_type)
{
- (*members)[i++].type = g_variant_type_info_get (item_type);
+ GVariantMemberInfo *member = &(*members)[i++];
+
+ member->type_info = g_variant_type_info_get (item_type);
item_type = g_variant_type_next (item_type);
+
+ if (member->type_info->fixed_size)
+ member->ending_type = G_VARIANT_MEMBER_ENDING_FIXED;
+ else if (item_type == NULL)
+ member->ending_type = G_VARIANT_MEMBER_ENDING_LAST;
+ else
+ member->ending_type = G_VARIANT_MEMBER_ENDING_OFFSET;
}
g_assert (i == *n_members);
@@ -377,8 +390,8 @@ tuple_get_item (TupleInfo *info,
if (&info->members[info->n_members] == item)
return FALSE;
- *d = item->type->alignment;
- *e = item->type->fixed_size;
+ *d = item->type_info->alignment;
+ *e = item->type_info->fixed_size;
return TRUE;
}
@@ -591,7 +604,7 @@ tuple_set_base_info (TupleInfo *info)
/* can find the max of a list of "one less than" powers of two
* by 'or'ing them
*/
- base->alignment |= m->type->alignment;
+ base->alignment |= m->type_info->alignment;
m--; /* take 'm' back to the last item */
@@ -599,7 +612,7 @@ tuple_set_base_info (TupleInfo *info)
* offsets are stored and the last item is fixed-sized too (since
* an offset is never stored for the last item).
*/
- if (m->i == -1 && m->type->fixed_size)
+ if (m->i == -1 && m->type_info->fixed_size)
/* in that case, the fixed size can be found by finding the
* start of the last item (in the usual way) and adding its
* fixed size.
@@ -609,7 +622,7 @@ tuple_set_base_info (TupleInfo *info)
* easier) so we round up to that here.
*/
base->fixed_size =
- tuple_align (((m->a & m->b) | m->c) + m->type->fixed_size,
+ tuple_align (((m->a & m->b) | m->c) + m->type_info->fixed_size,
base->alignment);
else
/* else, the tuple is not fixed size */
@@ -647,7 +660,7 @@ tuple_info_new (const GVariantType *type)
TupleInfo *info;
info = g_slice_new (TupleInfo);
- info->container.info.container_class = TUPLE_INFO_CLASS;
+ info->container.info.container_class = GV_TUPLE_INFO_CLASS;
tuple_allocate_members (type, &info->members, &info->n_members);
tuple_generate_table (info);
@@ -666,7 +679,7 @@ tuple_info_new (const GVariantType *type)
gsize
g_variant_type_info_n_members (GVariantTypeInfo *info)
{
- return TUPLE_INFO (info)->n_members;
+ return GV_TUPLE_INFO (info)->n_members;
}
/* < private >
@@ -685,7 +698,7 @@ const GVariantMemberInfo *
g_variant_type_info_member_info (GVariantTypeInfo *info,
gsize index)
{
- TupleInfo *tuple_info = TUPLE_INFO (info);
+ TupleInfo *tuple_info = GV_TUPLE_INFO (info);
if (index < tuple_info->n_members)
return &tuple_info->members[index];
@@ -694,7 +707,7 @@ g_variant_type_info_member_info (GVariantTypeInfo *info,
}
/* == new/ref/unref == */
-static GStaticRecMutex g_variant_type_info_lock = G_STATIC_REC_MUTEX_INIT;
+static GRecMutex g_variant_type_info_lock;
static GHashTable *g_variant_type_info_table;
/* < private >
@@ -725,13 +738,13 @@ g_variant_type_info_get (const GVariantType *type)
GVariantTypeInfo *info;
gchar *type_string;
- if G_UNLIKELY (g_variant_type_info_table == NULL)
- g_variant_type_info_table = g_hash_table_new (g_str_hash,
- g_str_equal);
-
type_string = g_variant_type_dup_string (type);
- g_static_rec_mutex_lock (&g_variant_type_info_lock);
+ g_rec_mutex_lock (&g_variant_type_info_lock);
+
+ if (g_variant_type_info_table == NULL)
+ g_variant_type_info_table = g_hash_table_new (g_str_hash,
+ g_str_equal);
info = g_hash_table_lookup (g_variant_type_info_table, type_string);
if (info == NULL)
@@ -758,7 +771,7 @@ g_variant_type_info_get (const GVariantType *type)
else
g_variant_type_info_ref (info);
- g_static_rec_mutex_unlock (&g_variant_type_info_lock);
+ g_rec_mutex_unlock (&g_variant_type_info_lock);
g_variant_type_info_check (info, 0);
g_free (type_string);
@@ -819,23 +832,36 @@ g_variant_type_info_unref (GVariantTypeInfo *info)
{
ContainerInfo *container = (ContainerInfo *) info;
+ g_rec_mutex_lock (&g_variant_type_info_lock);
if (g_atomic_int_dec_and_test (&container->ref_count))
{
- g_static_rec_mutex_lock (&g_variant_type_info_lock);
g_hash_table_remove (g_variant_type_info_table,
container->type_string);
- g_static_rec_mutex_unlock (&g_variant_type_info_lock);
+ if (g_hash_table_size (g_variant_type_info_table) == 0)
+ {
+ g_hash_table_unref (g_variant_type_info_table);
+ g_variant_type_info_table = NULL;
+ }
+ g_rec_mutex_unlock (&g_variant_type_info_lock);
g_free (container->type_string);
- if (info->container_class == ARRAY_INFO_CLASS)
+ if (info->container_class == GV_ARRAY_INFO_CLASS)
array_info_free (info);
- else if (info->container_class == TUPLE_INFO_CLASS)
+ else if (info->container_class == GV_TUPLE_INFO_CLASS)
tuple_info_free (info);
else
g_assert_not_reached ();
}
+ else
+ g_rec_mutex_unlock (&g_variant_type_info_lock);
}
}
+
+void
+g_variant_type_info_assert_no_infos (void)
+{
+ g_assert (g_variant_type_info_table == NULL);
+}