From 2209f63bda59360dd2fe765b71f89d84955ddd24 Mon Sep 17 00:00:00 2001 From: Mark Adler Date: Sun, 18 Jan 2026 10:18:46 -0800 Subject: Make z_once() local to avoid conditional external symbols. --- crc32.c | 7 ++++-- inftrees.c | 9 ++++++++ zlib.map | 1 - zutil.c | 58 ----------------------------------------------- zutil.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 5 files changed, 74 insertions(+), 77 deletions(-) diff --git a/crc32.c b/crc32.c index 630049fc..4cc573f8 100644 --- a/crc32.c +++ b/crc32.c @@ -24,8 +24,11 @@ # include # 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 c050f8bb..6b6f8dc4 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 d0b8a204..6c4c0311 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 3a94e917..6e8a3697 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 - -/* - 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 94fa1aff..acc1907f 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 -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 */ -- cgit v1.2.3-55-g6feb