diff options
| author | Mark Adler <git@madler.net> | 2026-01-18 10:18:46 -0800 |
|---|---|---|
| committer | Mark Adler <git@madler.net> | 2026-01-18 10:25:01 -0800 |
| commit | 2209f63bda59360dd2fe765b71f89d84955ddd24 (patch) | |
| tree | 3f061b4863c90a94f42960c49c96d8e80983f13b | |
| parent | 8e50fb08515ff0dd7e16247de47858cc204ac26e (diff) | |
| download | zlib-2209f63bda59360dd2fe765b71f89d84955ddd24.tar.gz zlib-2209f63bda59360dd2fe765b71f89d84955ddd24.tar.bz2 zlib-2209f63bda59360dd2fe765b71f89d84955ddd24.zip | |
Make z_once() local to avoid conditional external symbols.
| -rw-r--r-- | crc32.c | 7 | ||||
| -rw-r--r-- | inftrees.c | 9 | ||||
| -rw-r--r-- | zlib.map | 1 | ||||
| -rw-r--r-- | zutil.c | 58 | ||||
| -rw-r--r-- | zutil.h | 76 |
5 files changed, 74 insertions, 77 deletions
| @@ -24,8 +24,11 @@ | |||
| 24 | # include <stdio.h> | 24 | # include <stdio.h> |
| 25 | # ifndef DYNAMIC_CRC_TABLE | 25 | # ifndef DYNAMIC_CRC_TABLE |
| 26 | # define DYNAMIC_CRC_TABLE | 26 | # define DYNAMIC_CRC_TABLE |
| 27 | # endif /* !DYNAMIC_CRC_TABLE */ | 27 | # endif |
| 28 | #endif /* MAKECRCH */ | 28 | #endif |
| 29 | #ifdef DYNAMIC_CRC_TABLE | ||
| 30 | # define Z_ONCE | ||
| 31 | #endif | ||
| 29 | 32 | ||
| 30 | #include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ | 33 | #include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ |
| 31 | 34 | ||
| @@ -3,6 +3,15 @@ | |||
| 3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #ifdef MAKEFIXED | ||
| 7 | # ifndef BUILDFIXED | ||
| 8 | # define BUILDFIXED | ||
| 9 | # endif | ||
| 10 | #endif | ||
| 11 | #ifdef BUILDFIXED | ||
| 12 | # define Z_ONCE | ||
| 13 | #endif | ||
| 14 | |||
| 6 | #include "zutil.h" | 15 | #include "zutil.h" |
| 7 | #include "inftrees.h" | 16 | #include "inftrees.h" |
| 8 | #include "inflate.h" | 17 | #include "inflate.h" |
| @@ -113,5 +113,4 @@ ZLIB_1.3.2 { | |||
| 113 | uncompress2_z; | 113 | uncompress2_z; |
| 114 | local: | 114 | local: |
| 115 | inflate_fixed; | 115 | inflate_fixed; |
| 116 | z_once; | ||
| 117 | } ZLIB_1.3.1.2; \ No newline at end of file | 116 | } ZLIB_1.3.1.2; \ No newline at end of file |
| @@ -305,61 +305,3 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { | |||
| 305 | #endif /* MY_ZCALLOC */ | 305 | #endif /* MY_ZCALLOC */ |
| 306 | 306 | ||
| 307 | #endif /* !Z_SOLO */ | 307 | #endif /* !Z_SOLO */ |
| 308 | |||
| 309 | #if defined(BUILDFIXED) || defined(DYNAMIC_CRC_TABLE) | ||
| 310 | /* | ||
| 311 | Define a z_once() function depending on the availability of atomics. | ||
| 312 | */ | ||
| 313 | |||
| 314 | /* Check for the availability of atomics. */ | ||
| 315 | #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ | ||
| 316 | !defined(__STDC_NO_ATOMICS__) | ||
| 317 | |||
| 318 | #include <stdatomic.h> | ||
| 319 | |||
| 320 | /* | ||
| 321 | Run the provided init() function exactly once, even if multiple threads | ||
| 322 | invoke once() at the same time. The state must be a once_t initialized with | ||
| 323 | Z_ONCE_INIT. | ||
| 324 | */ | ||
| 325 | void z_once(z_once_t *state, void (*init)(void)) { | ||
| 326 | if (!atomic_load(&state->done)) { | ||
| 327 | if (atomic_flag_test_and_set(&state->begun)) | ||
| 328 | while (!atomic_load(&state->done)) | ||
| 329 | ; | ||
| 330 | else { | ||
| 331 | init(); | ||
| 332 | atomic_store(&state->done, 1); | ||
| 333 | } | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | #else /* no atomics */ | ||
| 338 | |||
| 339 | #warning zlib not thread-safe | ||
| 340 | |||
| 341 | /* Test and set. Alas, not atomic, but tries to limit the period of | ||
| 342 | vulnerability. */ | ||
| 343 | local int test_and_set(int volatile *flag) { | ||
| 344 | int was; | ||
| 345 | |||
| 346 | was = *flag; | ||
| 347 | *flag = 1; | ||
| 348 | return was; | ||
| 349 | } | ||
| 350 | |||
| 351 | /* Run the provided init() function once. This is not thread-safe. */ | ||
| 352 | void z_once(z_once_t *state, void (*init)(void)) { | ||
| 353 | if (!state->done) { | ||
| 354 | if (test_and_set(&state->begun)) | ||
| 355 | while (!state->done) | ||
| 356 | ; | ||
| 357 | else { | ||
| 358 | init(); | ||
| 359 | state->done = 1; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | } | ||
| 363 | |||
| 364 | #endif | ||
| 365 | #endif | ||
| @@ -254,30 +254,74 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ | |||
| 254 | #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ | 254 | #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ |
| 255 | (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) | 255 | (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) |
| 256 | 256 | ||
| 257 | #ifdef MAKEFIXED | 257 | #ifdef Z_ONCE |
| 258 | # ifndef BUILDFIXED | 258 | /* |
| 259 | # define BUILDFIXED | 259 | Create a local z_once() function depending on the availability of atomics. |
| 260 | # endif | 260 | */ |
| 261 | #endif | 261 | |
| 262 | #if defined(BUILDFIXED) || defined(DYNAMIC_CRC_TABLE) | 262 | /* Check for the availability of atomics. */ |
| 263 | /* Structure for z_once(), which must be initialized with Z_ONCE_INIT. */ | ||
| 264 | typedef struct z_once_s z_once_t; | ||
| 265 | void ZLIB_INTERNAL z_once(z_once_t *state, void (*init)(void)); | ||
| 266 | #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ | 263 | #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ |
| 267 | !defined(__STDC_NO_ATOMICS__) | 264 | !defined(__STDC_NO_ATOMICS__) |
| 265 | |||
| 268 | #include <stdatomic.h> | 266 | #include <stdatomic.h> |
| 269 | struct z_once_s { | 267 | typedef struct { |
| 270 | atomic_flag begun; | 268 | atomic_flag begun; |
| 271 | atomic_int done; | 269 | atomic_int done; |
| 272 | }; | 270 | } z_once_t; |
| 273 | #define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} | 271 | #define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} |
| 274 | #else /* no atomics! */ | 272 | |
| 275 | struct z_once_s { | 273 | /* |
| 274 | Run the provided init() function exactly once, even if multiple threads | ||
| 275 | invoke once() at the same time. The state must be a once_t initialized with | ||
| 276 | Z_ONCE_INIT. | ||
| 277 | */ | ||
| 278 | local void z_once(z_once_t *state, void (*init)(void)) { | ||
| 279 | if (!atomic_load(&state->done)) { | ||
| 280 | if (atomic_flag_test_and_set(&state->begun)) | ||
| 281 | while (!atomic_load(&state->done)) | ||
| 282 | ; | ||
| 283 | else { | ||
| 284 | init(); | ||
| 285 | atomic_store(&state->done, 1); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | #else /* no atomics */ | ||
| 291 | |||
| 292 | #warning zlib not thread-safe | ||
| 293 | |||
| 294 | typedef struct z_once_s { | ||
| 276 | volatile int begun; | 295 | volatile int begun; |
| 277 | volatile int done; | 296 | volatile int done; |
| 278 | }; | 297 | } z_once_t; |
| 279 | #define Z_ONCE_INIT {0, 0} | 298 | #define Z_ONCE_INIT {0, 0} |
| 280 | #endif | 299 | |
| 281 | #endif | 300 | /* Test and set. Alas, not atomic, but tries to limit the period of |
| 301 | vulnerability. */ | ||
| 302 | local int test_and_set(int volatile *flag) { | ||
| 303 | int was; | ||
| 304 | |||
| 305 | was = *flag; | ||
| 306 | *flag = 1; | ||
| 307 | return was; | ||
| 308 | } | ||
| 309 | |||
| 310 | /* Run the provided init() function once. This is not thread-safe. */ | ||
| 311 | local void z_once(z_once_t *state, void (*init)(void)) { | ||
| 312 | if (!state->done) { | ||
| 313 | if (test_and_set(&state->begun)) | ||
| 314 | while (!state->done) | ||
| 315 | ; | ||
| 316 | else { | ||
| 317 | init(); | ||
| 318 | state->done = 1; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | #endif /* ?atomics */ | ||
| 324 | |||
| 325 | #endif /* Z_ONCE */ | ||
| 282 | 326 | ||
| 283 | #endif /* ZUTIL_H */ | 327 | #endif /* ZUTIL_H */ |
