diff options
author | Stefan Ekenberg <stefeg@axis.com> | 2015-06-03 15:59:57 +0200 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2015-06-04 22:30:50 -0400 |
commit | 338741fff5381d1a8d11b8f62c9e208af8b016fa (patch) | |
tree | da203c9a0f995565753d13f540af4ab12dc82f05 /gobject/gsourceclosure.c | |
parent | 6c43b6a21aca5cac33992c6b690e566ac1664997 (diff) |
Prevent race condition in g_io_condition_get_type
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
Diffstat (limited to 'gobject/gsourceclosure.c')
-rw-r--r-- | gobject/gsourceclosure.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/gobject/gsourceclosure.c b/gobject/gsourceclosure.c index b74bdb679..910b6b2e3 100644 --- a/gobject/gsourceclosure.c +++ b/gobject/gsourceclosure.c @@ -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; } |