aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crc32.c7
-rw-r--r--inftrees.c9
-rw-r--r--zlib.map1
-rw-r--r--zutil.c58
-rw-r--r--zutil.h76
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 @@
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
diff --git a/inftrees.c b/inftrees.c
index c050f8bb..6b6f8dc4 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -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"
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 {
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
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) {
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 */
325void 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. */
343local 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. */
352void 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
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 */
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. */
264typedef struct z_once_s z_once_t;
265void 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>
269struct z_once_s { 267typedef 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
275struct 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 */
278local 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
294typedef 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. */
302local 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. */
311local 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 */