This mimics what is done in FreeBSD localtime.c. * localtime.c (THREAD_SAFE): Default to 0. All uses changed. (once_t, ONCE_INIT, once): New type, macro, and function. (gmtcheck1): New function, with the guts of the old gmtcheck. (gmtcheck): Use it, along with ‘once’. --- localtime.c | 54 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/localtime.c b/localtime.c index c9836b2d..a00cf743 100644 --- a/localtime.c +++ b/localtime.c @@ -44,11 +44,15 @@ struct stat { char st_ctime, st_dev, st_ino; } # define st_ctim st_ctimespec #endif +#ifndef THREAD_SAFE +# define THREAD_SAFE 0 +#endif + #ifndef THREAD_RWLOCK # define THREAD_RWLOCK 0 #endif -#if defined THREAD_SAFE && THREAD_SAFE +#if THREAD_SAFE # include <pthread.h> # ifndef THREAD_PREFER_SINGLE @@ -133,6 +137,27 @@ rd2wrlock(ATTRIBUTE_MAYBE_UNUSED bool threaded) return 0; } +#if THREAD_SAFE +typedef pthread_once_t once_t; +# define ONCE_INIT PTHREAD_ONCE_INIT +#else +typedef bool once_t; +# define ONCE_INIT false +#endif + +static void +once(once_t *once_control, void (*init_routine)(void)) +{ +#if THREAD_SAFE + pthread_once(once_control, init_routine); +#else + if (!*once_control) { + *once_control = true; + init_routine(); + } +#endif +} + /* Unless intptr_t is missing, pacify gcc -Wcast-qual on char const * exprs. Use this carefully, as the casts disable type checking. This is a macro so that it can be used in static initializers. */ @@ -1921,25 +1946,20 @@ tzset(void) #endif static void -gmtcheck(void) +gmtcheck1(void) { - static bool gmt_is_set; - int err = lock(); - if (0 < err) - return; - if (! gmt_is_set) { - if (rd2wrlock(!err) != 0) - return; - if (!THREAD_RWLOCK || !gmt_is_set) { #if ALL_STATE - gmtptr = malloc(sizeof *gmtptr); + gmtptr = malloc(sizeof *gmtptr); #endif - if (gmtptr) - gmtload(gmtptr); - gmt_is_set = true; - } - } - unlock(!err); + if (gmtptr) + gmtload(gmtptr); +} + +static void +gmtcheck(void) +{ + static once_t gmt_once = ONCE_INIT; + once(&gmt_once, gmtcheck1); } #if NETBSD_INSPIRED && !USE_TIMEX_T -- 2.48.1