Commit 2209f63 for zlib
commit 2209f63bda59360dd2fe765b71f89d84955ddd24
Author: Mark Adler <git@madler.net>
Date: Sun Jan 18 10:18:46 2026 -0800
Make z_once() local to avoid conditional external symbols.
diff --git a/crc32.c b/crc32.c
index 630049f..4cc573f 100644
--- a/crc32.c
+++ b/crc32.c
@@ -24,8 +24,11 @@
# include <stdio.h>
# ifndef DYNAMIC_CRC_TABLE
# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
+# endif
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+# define Z_ONCE
+#endif
#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */
diff --git a/inftrees.c b/inftrees.c
index c050f8b..6b6f8dc 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -3,6 +3,15 @@
* For conditions of distribution and use, see copyright notice in zlib.h
*/
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+#ifdef BUILDFIXED
+# define Z_ONCE
+#endif
+
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
diff --git a/zlib.map b/zlib.map
index d0b8a20..6c4c031 100644
--- a/zlib.map
+++ b/zlib.map
@@ -113,5 +113,4 @@ ZLIB_1.3.2 {
uncompress2_z;
local:
inflate_fixed;
- z_once;
} ZLIB_1.3.1.2;
\ No newline at end of file
diff --git a/zutil.c b/zutil.c
index 3a94e91..6e8a369 100644
--- a/zutil.c
+++ b/zutil.c
@@ -305,61 +305,3 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
#endif /* MY_ZCALLOC */
#endif /* !Z_SOLO */
-
-#if defined(BUILDFIXED) || defined(DYNAMIC_CRC_TABLE)
-/*
- Define a z_once() function depending on the availability of atomics.
- */
-
-/* Check for the availability of atomics. */
-#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
- !defined(__STDC_NO_ATOMICS__)
-
-#include <stdatomic.h>
-
-/*
- Run the provided init() function exactly once, even if multiple threads
- invoke once() at the same time. The state must be a once_t initialized with
- Z_ONCE_INIT.
- */
-void z_once(z_once_t *state, void (*init)(void)) {
- if (!atomic_load(&state->done)) {
- if (atomic_flag_test_and_set(&state->begun))
- while (!atomic_load(&state->done))
- ;
- else {
- init();
- atomic_store(&state->done, 1);
- }
- }
-}
-
-#else /* no atomics */
-
-#warning zlib not thread-safe
-
-/* Test and set. Alas, not atomic, but tries to limit the period of
- vulnerability. */
-local int test_and_set(int volatile *flag) {
- int was;
-
- was = *flag;
- *flag = 1;
- return was;
-}
-
-/* Run the provided init() function once. This is not thread-safe. */
-void z_once(z_once_t *state, void (*init)(void)) {
- if (!state->done) {
- if (test_and_set(&state->begun))
- while (!state->done)
- ;
- else {
- init();
- state->done = 1;
- }
- }
-}
-
-#endif
-#endif
diff --git a/zutil.h b/zutil.h
index 94fa1af..acc1907 100644
--- a/zutil.h
+++ b/zutil.h
@@ -254,30 +254,74 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-#ifdef MAKEFIXED
-# ifndef BUILDFIXED
-# define BUILDFIXED
-# endif
-#endif
-#if defined(BUILDFIXED) || defined(DYNAMIC_CRC_TABLE)
-/* Structure for z_once(), which must be initialized with Z_ONCE_INIT. */
-typedef struct z_once_s z_once_t;
-void ZLIB_INTERNAL z_once(z_once_t *state, void (*init)(void));
+#ifdef Z_ONCE
+/*
+ Create a local z_once() function depending on the availability of atomics.
+ */
+
+/* Check for the availability of atomics. */
#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
!defined(__STDC_NO_ATOMICS__)
+
#include <stdatomic.h>
-struct z_once_s {
+typedef struct {
atomic_flag begun;
atomic_int done;
-};
+} z_once_t;
#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0}
-#else /* no atomics! */
-struct z_once_s {
+
+/*
+ Run the provided init() function exactly once, even if multiple threads
+ invoke once() at the same time. The state must be a once_t initialized with
+ Z_ONCE_INIT.
+ */
+local void z_once(z_once_t *state, void (*init)(void)) {
+ if (!atomic_load(&state->done)) {
+ if (atomic_flag_test_and_set(&state->begun))
+ while (!atomic_load(&state->done))
+ ;
+ else {
+ init();
+ atomic_store(&state->done, 1);
+ }
+ }
+}
+
+#else /* no atomics */
+
+#warning zlib not thread-safe
+
+typedef struct z_once_s {
volatile int begun;
volatile int done;
-};
+} z_once_t;
#define Z_ONCE_INIT {0, 0}
-#endif
-#endif
+
+/* Test and set. Alas, not atomic, but tries to limit the period of
+ vulnerability. */
+local int test_and_set(int volatile *flag) {
+ int was;
+
+ was = *flag;
+ *flag = 1;
+ return was;
+}
+
+/* Run the provided init() function once. This is not thread-safe. */
+local void z_once(z_once_t *state, void (*init)(void)) {
+ if (!state->done) {
+ if (test_and_set(&state->begun))
+ while (!state->done)
+ ;
+ else {
+ init();
+ state->done = 1;
+ }
+ }
+}
+
+#endif /* ?atomics */
+
+#endif /* Z_ONCE */
#endif /* ZUTIL_H */