[kdbus] sync with kdbus (kdbus.h - commit: 5ae1ecac44cb)
[platform/upstream/glib.git] / glib / gvarianttypeinfo.c
index ee94cb8..48d25df 100644 (file)
@@ -13,9 +13,7 @@
  * 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 <http://www.gnu.org/licenses/>.
  *
  * Author: Ryan Lortie <desrt@desrt.ca>
  */
 
 #include <glib/gtestutils.h>
 #include <glib/gthread.h>
+#include <glib/gslice.h>
 #include <glib/ghash.h>
 
-#include "galias.h"
-
 /* < private >
  * GVariantTypeInfo:
  *
@@ -51,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
@@ -111,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' */ { fixed_aligned(4) },   /* float */
   /* '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
 };
@@ -148,7 +147,7 @@ static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
  * GVariantTypeInfo itself, we save a bunch of relocations.
  */
 static const char g_variant_type_info_basic_chars[24][2] = {
-  "b", " ", "d", " ", " ", "g", "h", "i", " ", " ", " ", " ",
+  "b", " ", "d", " ", "f", "g", "h", "i", " ", " ", " ", " ",
   "n", "o", " ", "q", " ", "s", "t", "u", "v", " ", "x", "y"
 };
 
@@ -221,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.
@@ -253,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;
 }
@@ -267,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);
@@ -280,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;
@@ -299,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
@@ -317,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;
 }
@@ -337,7 +336,7 @@ 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++)
@@ -661,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);
@@ -680,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 >
@@ -699,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];
@@ -708,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 >
@@ -739,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)
@@ -772,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);
 
@@ -833,9 +832,9 @@ 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);
           if (g_hash_table_size (g_variant_type_info_table) == 0)
@@ -843,22 +842,26 @@ g_variant_type_info_unref (GVariantTypeInfo *info)
               g_hash_table_unref (g_variant_type_info_table);
               g_variant_type_info_table = NULL;
             }
-          g_static_rec_mutex_unlock (&g_variant_type_info_lock);
+          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);
     }
 }
 
-/* used from the test cases */
-#define assert_no_type_infos() \
-  g_assert (g_variant_type_info_table == NULL)
+void
+g_variant_type_info_assert_no_infos (void)
+{
+  g_assert (g_variant_type_info_table == NULL);
+}