From 2955981569808304399d16847712f0ef97c6355b Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 16 Aug 2011 19:12:59 -0400 Subject: [PATCH] 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 --- glib/gmain.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) 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); -- 2.7.4