X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgvarianttypeinfo.c;h=b398d657a860499e66e7e7d7c1f7739202538674;hb=1cbdbef77209fe82239bd10f062425491cf256ae;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); +}