Prevent race condition in g_io_condition_get_type
authorStefan Ekenberg <stefeg@axis.com>
Wed, 3 Jun 2015 13:59:57 +0000 (15:59 +0200)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 5 Jun 2015 02:30:50 +0000 (22:30 -0400)
Prevents race condition in function g_io_condition_get_type by ensuring
that the initialization section for 'etype' is executed only once
during a program's life time, and that concurrent threads are blocked
until initialization completes. This changes solves the problem that
concurrent threads could execute the check 'etype == 0' before any of
them had initialized it, which in turn meant that multiple threads
would then attempt to register the "GIOCondition" type.

https://bugzilla.gnome.org/show_bug.cgi?id=750386

gobject/gsourceclosure.c

index b74bdb6..910b6b2 100644 (file)
@@ -32,8 +32,9 @@ G_DEFINE_BOXED_TYPE (GIOChannel, g_io_channel, g_io_channel_ref, g_io_channel_un
 GType
 g_io_condition_get_type (void)
 {
-  static GType etype = 0;
-  if (etype == 0)
+  static volatile GType etype = 0;
+
+  if (g_once_init_enter (&etype))
     {
       static const GFlagsValue values[] = {
        { G_IO_IN,   "G_IO_IN",   "in" },
@@ -44,7 +45,8 @@ g_io_condition_get_type (void)
        { G_IO_NVAL, "G_IO_NVAL", "nval" },
        { 0, NULL, NULL }
       };
-      etype = g_flags_register_static ("GIOCondition", values);
+      GType type_id = g_flags_register_static ("GIOCondition", values);
+      g_once_init_leave (&etype, type_id);
     }
   return etype;
 }