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