From: Dan Winship Date: Tue, 16 Aug 2011 23:12:59 +0000 (-0400) Subject: g_get_monotonic_time: fix race condition X-Git-Tag: 2.29.90~74 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;ds=sidebyside;h=2955981569808304399d16847712f0ef97c6355b;p=platform%2Fupstream%2Fglib.git g_get_monotonic_time: fix race condition Since there was nothing guaranteeing synchronization of the assignments to checked and clockid, it would be possible for one thread to set clockid = CLOCK_MONOTONIC, and for another thread to see checked = TRUE but still clockid = CLOCK_REALTIME. https://bugzilla.gnome.org/show_bug.cgi?id=655129 --- diff --git a/glib/gmain.c b/glib/gmain.c index 75c2c0e..a7bcc0f 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -2042,25 +2042,24 @@ g_get_monotonic_time (void) #ifdef HAVE_CLOCK_GETTIME /* librt clock_gettime() is our first choice */ { - static int clockid = CLOCK_REALTIME; +#ifdef HAVE_MONOTONIC_CLOCK + static volatile gsize clockid = 0; +#else + static clockid_t clockid = CLOCK_REALTIME; +#endif struct timespec ts; #ifdef HAVE_MONOTONIC_CLOCK - /* We have to check if we actually have monotonic clock support. - * - * There is no thread safety issue here since there is no harm if we - * check twice. - */ - { - static gboolean checked; + if (g_once_init_enter (&clockid)) + { + clockid_t best_clockid; - if G_UNLIKELY (!checked) - { - if (sysconf (_SC_MONOTONIC_CLOCK) >= 0) - clockid = CLOCK_MONOTONIC; - checked = TRUE; - } - } + if (sysconf (_SC_MONOTONIC_CLOCK) >= 0) + best_clockid = CLOCK_MONOTONIC; + else + best_clockid = CLOCK_REALTIME; + g_once_init_leave (&clockid, (gsize)best_clockid); + } #endif clock_gettime (clockid, &ts);