|
7ef7284…
|
drh
|
1 |
/* zutil.h -- internal interface and configuration of the compression library |
|
6ea30fb…
|
florian
|
2 |
* Copyright (C) 1995-2026 Jean-loup Gailly, Mark Adler |
|
7ef7284…
|
drh
|
3 |
* For conditions of distribution and use, see copyright notice in zlib.h |
|
7ef7284…
|
drh
|
4 |
*/ |
|
7ef7284…
|
drh
|
5 |
|
|
7ef7284…
|
drh
|
6 |
/* WARNING: this file should *not* be used by applications. It is |
|
7ef7284…
|
drh
|
7 |
part of the implementation of the compression library and is |
|
7ef7284…
|
drh
|
8 |
subject to change. Applications should only use zlib.h. |
|
7ef7284…
|
drh
|
9 |
*/ |
|
7ef7284…
|
drh
|
10 |
|
|
7ef7284…
|
drh
|
11 |
/* @(#) $Id$ */ |
|
7ef7284…
|
drh
|
12 |
|
|
7ef7284…
|
drh
|
13 |
#ifndef ZUTIL_H |
|
7ef7284…
|
drh
|
14 |
#define ZUTIL_H |
|
7ef7284…
|
drh
|
15 |
|
|
7ef7284…
|
drh
|
16 |
#ifdef HAVE_HIDDEN |
|
7ef7284…
|
drh
|
17 |
# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) |
|
7ef7284…
|
drh
|
18 |
#else |
|
7ef7284…
|
drh
|
19 |
# define ZLIB_INTERNAL |
|
7ef7284…
|
drh
|
20 |
#endif |
|
7ef7284…
|
drh
|
21 |
|
|
7ef7284…
|
drh
|
22 |
#include "zlib.h" |
|
7ef7284…
|
drh
|
23 |
|
|
7ef7284…
|
drh
|
24 |
#if defined(STDC) && !defined(Z_SOLO) |
|
7ef7284…
|
drh
|
25 |
# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) |
|
7ef7284…
|
drh
|
26 |
# include <stddef.h> |
|
7ef7284…
|
drh
|
27 |
# endif |
|
7ef7284…
|
drh
|
28 |
# include <string.h> |
|
7ef7284…
|
drh
|
29 |
# include <stdlib.h> |
|
7ef7284…
|
drh
|
30 |
#endif |
|
7ef7284…
|
drh
|
31 |
|
|
7ef7284…
|
drh
|
32 |
#ifndef local |
|
7ef7284…
|
drh
|
33 |
# define local static |
|
7ef7284…
|
drh
|
34 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
35 |
/* since "static" is used to mean two completely different things in C, we |
|
e38d5e1…
|
jan.nijtmans
|
36 |
define "local" for the non-static meaning of "static", for readability |
|
e38d5e1…
|
jan.nijtmans
|
37 |
(compile with -Dlocal if your debugger can't find static symbols) */ |
|
adb9e8e…
|
drh
|
38 |
|
|
6ea30fb…
|
florian
|
39 |
extern const char deflate_copyright[]; |
|
6ea30fb…
|
florian
|
40 |
extern const char inflate_copyright[]; |
|
6ea30fb…
|
florian
|
41 |
extern const char inflate9_copyright[]; |
|
6ea30fb…
|
florian
|
42 |
|
|
7ef7284…
|
drh
|
43 |
typedef unsigned char uch; |
|
7ef7284…
|
drh
|
44 |
typedef uch FAR uchf; |
|
7ef7284…
|
drh
|
45 |
typedef unsigned short ush; |
|
7ef7284…
|
drh
|
46 |
typedef ush FAR ushf; |
|
7ef7284…
|
drh
|
47 |
typedef unsigned long ulg; |
|
7ef7284…
|
drh
|
48 |
|
|
adb9e8e…
|
drh
|
49 |
#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) |
|
adb9e8e…
|
drh
|
50 |
# include <limits.h> |
|
adb9e8e…
|
drh
|
51 |
# if (ULONG_MAX == 0xffffffffffffffff) |
|
adb9e8e…
|
drh
|
52 |
# define Z_U8 unsigned long |
|
adb9e8e…
|
drh
|
53 |
# elif (ULLONG_MAX == 0xffffffffffffffff) |
|
6ea30fb…
|
florian
|
54 |
# define Z_U8 unsigned long long |
|
6ea30fb…
|
florian
|
55 |
# elif (ULONG_LONG_MAX == 0xffffffffffffffff) |
|
64ce68d…
|
drh
|
56 |
# define Z_U8 unsigned long long |
|
adb9e8e…
|
drh
|
57 |
# elif (UINT_MAX == 0xffffffffffffffff) |
|
adb9e8e…
|
drh
|
58 |
# define Z_U8 unsigned |
|
adb9e8e…
|
drh
|
59 |
# endif |
|
adb9e8e…
|
drh
|
60 |
#endif |
|
adb9e8e…
|
drh
|
61 |
|
|
bb4776e…
|
jan.nijtmans
|
62 |
extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ |
|
7ef7284…
|
drh
|
63 |
/* (size given to avoid silly warnings with Visual C++) */ |
|
7ef7284…
|
drh
|
64 |
|
|
64ce68d…
|
drh
|
65 |
#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] |
|
7ef7284…
|
drh
|
66 |
|
|
7ef7284…
|
drh
|
67 |
#define ERR_RETURN(strm,err) \ |
|
bb4776e…
|
jan.nijtmans
|
68 |
return (strm->msg = ERR_MSG(err), (err)) |
|
7ef7284…
|
drh
|
69 |
/* To be used only when the state is known to be valid */ |
|
7ef7284…
|
drh
|
70 |
|
|
7ef7284…
|
drh
|
71 |
/* common constants */ |
|
6ea30fb…
|
florian
|
72 |
#if MAX_WBITS < 9 || MAX_WBITS > 15 |
|
6ea30fb…
|
florian
|
73 |
# error MAX_WBITS must be in 9..15 |
|
6ea30fb…
|
florian
|
74 |
#endif |
|
7ef7284…
|
drh
|
75 |
#ifndef DEF_WBITS |
|
7ef7284…
|
drh
|
76 |
# define DEF_WBITS MAX_WBITS |
|
7ef7284…
|
drh
|
77 |
#endif |
|
7ef7284…
|
drh
|
78 |
/* default windowBits for decompression. MAX_WBITS is for compression only */ |
|
7ef7284…
|
drh
|
79 |
|
|
7ef7284…
|
drh
|
80 |
#if MAX_MEM_LEVEL >= 8 |
|
7ef7284…
|
drh
|
81 |
# define DEF_MEM_LEVEL 8 |
|
7ef7284…
|
drh
|
82 |
#else |
|
7ef7284…
|
drh
|
83 |
# define DEF_MEM_LEVEL MAX_MEM_LEVEL |
|
7ef7284…
|
drh
|
84 |
#endif |
|
7ef7284…
|
drh
|
85 |
/* default memLevel */ |
|
7ef7284…
|
drh
|
86 |
|
|
7ef7284…
|
drh
|
87 |
#define STORED_BLOCK 0 |
|
7ef7284…
|
drh
|
88 |
#define STATIC_TREES 1 |
|
7ef7284…
|
drh
|
89 |
#define DYN_TREES 2 |
|
7ef7284…
|
drh
|
90 |
/* The three kinds of block type */ |
|
7ef7284…
|
drh
|
91 |
|
|
7ef7284…
|
drh
|
92 |
#define MIN_MATCH 3 |
|
7ef7284…
|
drh
|
93 |
#define MAX_MATCH 258 |
|
7ef7284…
|
drh
|
94 |
/* The minimum and maximum match lengths */ |
|
7ef7284…
|
drh
|
95 |
|
|
7ef7284…
|
drh
|
96 |
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ |
|
7ef7284…
|
drh
|
97 |
|
|
7ef7284…
|
drh
|
98 |
/* target dependencies */ |
|
7ef7284…
|
drh
|
99 |
|
|
7ef7284…
|
drh
|
100 |
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) |
|
7ef7284…
|
drh
|
101 |
# define OS_CODE 0x00 |
|
7ef7284…
|
drh
|
102 |
# ifndef Z_SOLO |
|
7ef7284…
|
drh
|
103 |
# if defined(__TURBOC__) || defined(__BORLANDC__) |
|
7ef7284…
|
drh
|
104 |
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) |
|
7ef7284…
|
drh
|
105 |
/* Allow compilation with ANSI keywords only enabled */ |
|
7ef7284…
|
drh
|
106 |
void _Cdecl farfree( void *block ); |
|
7ef7284…
|
drh
|
107 |
void *_Cdecl farmalloc( unsigned long nbytes ); |
|
7ef7284…
|
drh
|
108 |
# else |
|
7ef7284…
|
drh
|
109 |
# include <alloc.h> |
|
7ef7284…
|
drh
|
110 |
# endif |
|
7ef7284…
|
drh
|
111 |
# else /* MSC or DJGPP */ |
|
7ef7284…
|
drh
|
112 |
# include <malloc.h> |
|
7ef7284…
|
drh
|
113 |
# endif |
|
7ef7284…
|
drh
|
114 |
# endif |
|
7ef7284…
|
drh
|
115 |
#endif |
|
7ef7284…
|
drh
|
116 |
|
|
7ef7284…
|
drh
|
117 |
#ifdef AMIGA |
|
e38d5e1…
|
jan.nijtmans
|
118 |
# define OS_CODE 1 |
|
7ef7284…
|
drh
|
119 |
#endif |
|
7ef7284…
|
drh
|
120 |
|
|
7ef7284…
|
drh
|
121 |
#if defined(VAXC) || defined(VMS) |
|
e38d5e1…
|
jan.nijtmans
|
122 |
# define OS_CODE 2 |
|
7ef7284…
|
drh
|
123 |
# define F_OPEN(name, mode) \ |
|
7ef7284…
|
drh
|
124 |
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") |
|
7ef7284…
|
drh
|
125 |
#endif |
|
7ef7284…
|
drh
|
126 |
|
|
e38d5e1…
|
jan.nijtmans
|
127 |
#ifdef __370__ |
|
e38d5e1…
|
jan.nijtmans
|
128 |
# if __TARGET_LIB__ < 0x20000000 |
|
e38d5e1…
|
jan.nijtmans
|
129 |
# define OS_CODE 4 |
|
e38d5e1…
|
jan.nijtmans
|
130 |
# elif __TARGET_LIB__ < 0x40000000 |
|
e38d5e1…
|
jan.nijtmans
|
131 |
# define OS_CODE 11 |
|
e38d5e1…
|
jan.nijtmans
|
132 |
# else |
|
e38d5e1…
|
jan.nijtmans
|
133 |
# define OS_CODE 8 |
|
e38d5e1…
|
jan.nijtmans
|
134 |
# endif |
|
e38d5e1…
|
jan.nijtmans
|
135 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
136 |
|
|
7ef7284…
|
drh
|
137 |
#if defined(ATARI) || defined(atarist) |
|
e38d5e1…
|
jan.nijtmans
|
138 |
# define OS_CODE 5 |
|
7ef7284…
|
drh
|
139 |
#endif |
|
7ef7284…
|
drh
|
140 |
|
|
7ef7284…
|
drh
|
141 |
#ifdef OS2 |
|
e38d5e1…
|
jan.nijtmans
|
142 |
# define OS_CODE 6 |
|
7ef7284…
|
drh
|
143 |
# if defined(M_I86) && !defined(Z_SOLO) |
|
7ef7284…
|
drh
|
144 |
# include <malloc.h> |
|
7ef7284…
|
drh
|
145 |
# endif |
|
7ef7284…
|
drh
|
146 |
#endif |
|
7ef7284…
|
drh
|
147 |
|
|
64ce68d…
|
drh
|
148 |
#if defined(MACOS) |
|
e38d5e1…
|
jan.nijtmans
|
149 |
# define OS_CODE 7 |
|
e38d5e1…
|
jan.nijtmans
|
150 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
151 |
|
|
6ea30fb…
|
florian
|
152 |
#if defined(__acorn) || defined(__riscos) |
|
e38d5e1…
|
jan.nijtmans
|
153 |
# define OS_CODE 13 |
|
e38d5e1…
|
jan.nijtmans
|
154 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
155 |
|
|
e38d5e1…
|
jan.nijtmans
|
156 |
#if defined(WIN32) && !defined(__CYGWIN__) |
|
e38d5e1…
|
jan.nijtmans
|
157 |
# define OS_CODE 10 |
|
e38d5e1…
|
jan.nijtmans
|
158 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
159 |
|
|
e38d5e1…
|
jan.nijtmans
|
160 |
#ifdef _BEOS_ |
|
e38d5e1…
|
jan.nijtmans
|
161 |
# define OS_CODE 16 |
|
e38d5e1…
|
jan.nijtmans
|
162 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
163 |
|
|
e38d5e1…
|
jan.nijtmans
|
164 |
#ifdef __TOS_OS400__ |
|
e38d5e1…
|
jan.nijtmans
|
165 |
# define OS_CODE 18 |
|
e38d5e1…
|
jan.nijtmans
|
166 |
#endif |
|
e38d5e1…
|
jan.nijtmans
|
167 |
|
|
e38d5e1…
|
jan.nijtmans
|
168 |
#ifdef __APPLE__ |
|
e38d5e1…
|
jan.nijtmans
|
169 |
# define OS_CODE 19 |
|
7ef7284…
|
drh
|
170 |
#endif |
|
7ef7284…
|
drh
|
171 |
|
|
7ef7284…
|
drh
|
172 |
#if defined(__BORLANDC__) && !defined(MSDOS) |
|
7ef7284…
|
drh
|
173 |
#pragma warn -8004 |
|
7ef7284…
|
drh
|
174 |
#pragma warn -8008 |
|
7ef7284…
|
drh
|
175 |
#pragma warn -8066 |
|
7ef7284…
|
drh
|
176 |
#endif |
|
7ef7284…
|
drh
|
177 |
|
|
7ef7284…
|
drh
|
178 |
/* provide prototypes for these when building zlib without LFS */ |
|
6ea30fb…
|
florian
|
179 |
#ifndef Z_LARGE64 |
|
6ea30fb…
|
florian
|
180 |
ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); |
|
6ea30fb…
|
florian
|
181 |
ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); |
|
6ea30fb…
|
florian
|
182 |
ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); |
|
7ef7284…
|
drh
|
183 |
#endif |
|
7ef7284…
|
drh
|
184 |
|
|
7ef7284…
|
drh
|
185 |
/* common defaults */ |
|
7ef7284…
|
drh
|
186 |
|
|
7ef7284…
|
drh
|
187 |
#ifndef OS_CODE |
|
e38d5e1…
|
jan.nijtmans
|
188 |
# define OS_CODE 3 /* assume Unix */ |
|
7ef7284…
|
drh
|
189 |
#endif |
|
7ef7284…
|
drh
|
190 |
|
|
7ef7284…
|
drh
|
191 |
#ifndef F_OPEN |
|
7ef7284…
|
drh
|
192 |
# define F_OPEN(name, mode) fopen((name), (mode)) |
|
7ef7284…
|
drh
|
193 |
#endif |
|
7ef7284…
|
drh
|
194 |
|
|
7ef7284…
|
drh
|
195 |
/* functions */ |
|
7ef7284…
|
drh
|
196 |
|
|
7ef7284…
|
drh
|
197 |
#if defined(pyr) || defined(Z_SOLO) |
|
7ef7284…
|
drh
|
198 |
# define NO_MEMCPY |
|
7ef7284…
|
drh
|
199 |
#endif |
|
7ef7284…
|
drh
|
200 |
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) |
|
7ef7284…
|
drh
|
201 |
/* Use our own functions for small and medium model with MSC <= 5.0. |
|
7ef7284…
|
drh
|
202 |
* You may have to use the same strategy for Borland C (untested). |
|
7ef7284…
|
drh
|
203 |
* The __SC__ check is for Symantec. |
|
7ef7284…
|
drh
|
204 |
*/ |
|
7ef7284…
|
drh
|
205 |
# define NO_MEMCPY |
|
7ef7284…
|
drh
|
206 |
#endif |
|
7ef7284…
|
drh
|
207 |
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) |
|
7ef7284…
|
drh
|
208 |
# define HAVE_MEMCPY |
|
7ef7284…
|
drh
|
209 |
#endif |
|
7ef7284…
|
drh
|
210 |
#ifdef HAVE_MEMCPY |
|
7ef7284…
|
drh
|
211 |
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ |
|
7ef7284…
|
drh
|
212 |
# define zmemcpy _fmemcpy |
|
7ef7284…
|
drh
|
213 |
# define zmemcmp _fmemcmp |
|
7ef7284…
|
drh
|
214 |
# define zmemzero(dest, len) _fmemset(dest, 0, len) |
|
7ef7284…
|
drh
|
215 |
# else |
|
7ef7284…
|
drh
|
216 |
# define zmemcpy memcpy |
|
7ef7284…
|
drh
|
217 |
# define zmemcmp memcmp |
|
7ef7284…
|
drh
|
218 |
# define zmemzero(dest, len) memset(dest, 0, len) |
|
7ef7284…
|
drh
|
219 |
# endif |
|
7ef7284…
|
drh
|
220 |
#else |
|
6ea30fb…
|
florian
|
221 |
void ZLIB_INTERNAL zmemcpy(void FAR *, const void FAR *, z_size_t); |
|
6ea30fb…
|
florian
|
222 |
int ZLIB_INTERNAL zmemcmp(const void FAR *, const void FAR *, z_size_t); |
|
6ea30fb…
|
florian
|
223 |
void ZLIB_INTERNAL zmemzero(void FAR *, z_size_t); |
|
7ef7284…
|
drh
|
224 |
#endif |
|
7ef7284…
|
drh
|
225 |
|
|
7ef7284…
|
drh
|
226 |
/* Diagnostic functions */ |
|
e38d5e1…
|
jan.nijtmans
|
227 |
#ifdef ZLIB_DEBUG |
|
7ef7284…
|
drh
|
228 |
# include <stdio.h> |
|
7ef7284…
|
drh
|
229 |
extern int ZLIB_INTERNAL z_verbose; |
|
f1f1d6c…
|
drh
|
230 |
extern void ZLIB_INTERNAL z_error(char *m); |
|
7ef7284…
|
drh
|
231 |
# define Assert(cond,msg) {if(!(cond)) z_error(msg);} |
|
7ef7284…
|
drh
|
232 |
# define Trace(x) {if (z_verbose>=0) fprintf x ;} |
|
7ef7284…
|
drh
|
233 |
# define Tracev(x) {if (z_verbose>0) fprintf x ;} |
|
7ef7284…
|
drh
|
234 |
# define Tracevv(x) {if (z_verbose>1) fprintf x ;} |
|
7ef7284…
|
drh
|
235 |
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} |
|
7ef7284…
|
drh
|
236 |
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} |
|
7ef7284…
|
drh
|
237 |
#else |
|
7ef7284…
|
drh
|
238 |
# define Assert(cond,msg) |
|
7ef7284…
|
drh
|
239 |
# define Trace(x) |
|
7ef7284…
|
drh
|
240 |
# define Tracev(x) |
|
7ef7284…
|
drh
|
241 |
# define Tracevv(x) |
|
7ef7284…
|
drh
|
242 |
# define Tracec(c,x) |
|
7ef7284…
|
drh
|
243 |
# define Tracecv(c,x) |
|
7ef7284…
|
drh
|
244 |
#endif |
|
7ef7284…
|
drh
|
245 |
|
|
7ef7284…
|
drh
|
246 |
#ifndef Z_SOLO |
|
f1f1d6c…
|
drh
|
247 |
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, |
|
f1f1d6c…
|
drh
|
248 |
unsigned size); |
|
f1f1d6c…
|
drh
|
249 |
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); |
|
7ef7284…
|
drh
|
250 |
#endif |
|
7ef7284…
|
drh
|
251 |
|
|
7ef7284…
|
drh
|
252 |
#define ZALLOC(strm, items, size) \ |
|
7ef7284…
|
drh
|
253 |
(*((strm)->zalloc))((strm)->opaque, (items), (size)) |
|
7ef7284…
|
drh
|
254 |
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) |
|
7ef7284…
|
drh
|
255 |
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} |
|
7ef7284…
|
drh
|
256 |
|
|
7ef7284…
|
drh
|
257 |
/* Reverse the bytes in a 32-bit value */ |
|
7ef7284…
|
drh
|
258 |
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ |
|
7ef7284…
|
drh
|
259 |
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) |
|
6ea30fb…
|
florian
|
260 |
|
|
6ea30fb…
|
florian
|
261 |
#ifdef Z_ONCE |
|
6ea30fb…
|
florian
|
262 |
/* |
|
6ea30fb…
|
florian
|
263 |
Create a local z_once() function depending on the availability of atomics. |
|
6ea30fb…
|
florian
|
264 |
*/ |
|
6ea30fb…
|
florian
|
265 |
|
|
6ea30fb…
|
florian
|
266 |
/* Check for the availability of atomics. */ |
|
6ea30fb…
|
florian
|
267 |
#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ |
|
6ea30fb…
|
florian
|
268 |
!defined(__STDC_NO_ATOMICS__) |
|
6ea30fb…
|
florian
|
269 |
|
|
6ea30fb…
|
florian
|
270 |
#include <stdatomic.h> |
|
6ea30fb…
|
florian
|
271 |
typedef struct { |
|
6ea30fb…
|
florian
|
272 |
atomic_flag begun; |
|
6ea30fb…
|
florian
|
273 |
atomic_int done; |
|
6ea30fb…
|
florian
|
274 |
} z_once_t; |
|
6ea30fb…
|
florian
|
275 |
#define Z_ONCE_INIT {ATOMIC_FLAG_INIT, 0} |
|
6ea30fb…
|
florian
|
276 |
|
|
6ea30fb…
|
florian
|
277 |
/* |
|
6ea30fb…
|
florian
|
278 |
Run the provided init() function exactly once, even if multiple threads |
|
6ea30fb…
|
florian
|
279 |
invoke once() at the same time. The state must be a once_t initialized with |
|
6ea30fb…
|
florian
|
280 |
Z_ONCE_INIT. |
|
6ea30fb…
|
florian
|
281 |
*/ |
|
6ea30fb…
|
florian
|
282 |
local void z_once(z_once_t *state, void (*init)(void)) { |
|
6ea30fb…
|
florian
|
283 |
if (!atomic_load(&state->done)) { |
|
6ea30fb…
|
florian
|
284 |
if (atomic_flag_test_and_set(&state->begun)) |
|
6ea30fb…
|
florian
|
285 |
while (!atomic_load(&state->done)) |
|
6ea30fb…
|
florian
|
286 |
; |
|
6ea30fb…
|
florian
|
287 |
else { |
|
6ea30fb…
|
florian
|
288 |
init(); |
|
6ea30fb…
|
florian
|
289 |
atomic_store(&state->done, 1); |
|
6ea30fb…
|
florian
|
290 |
} |
|
6ea30fb…
|
florian
|
291 |
} |
|
6ea30fb…
|
florian
|
292 |
} |
|
6ea30fb…
|
florian
|
293 |
|
|
6ea30fb…
|
florian
|
294 |
#else /* no atomics */ |
|
6ea30fb…
|
florian
|
295 |
|
|
6ea30fb…
|
florian
|
296 |
#warning zlib not thread-safe |
|
6ea30fb…
|
florian
|
297 |
|
|
6ea30fb…
|
florian
|
298 |
typedef struct z_once_s { |
|
6ea30fb…
|
florian
|
299 |
volatile int begun; |
|
6ea30fb…
|
florian
|
300 |
volatile int done; |
|
6ea30fb…
|
florian
|
301 |
} z_once_t; |
|
6ea30fb…
|
florian
|
302 |
#define Z_ONCE_INIT {0, 0} |
|
6ea30fb…
|
florian
|
303 |
|
|
6ea30fb…
|
florian
|
304 |
/* Test and set. Alas, not atomic, but tries to limit the period of |
|
6ea30fb…
|
florian
|
305 |
vulnerability. */ |
|
6ea30fb…
|
florian
|
306 |
local int test_and_set(int volatile *flag) { |
|
6ea30fb…
|
florian
|
307 |
int was; |
|
6ea30fb…
|
florian
|
308 |
|
|
6ea30fb…
|
florian
|
309 |
was = *flag; |
|
6ea30fb…
|
florian
|
310 |
*flag = 1; |
|
6ea30fb…
|
florian
|
311 |
return was; |
|
6ea30fb…
|
florian
|
312 |
} |
|
6ea30fb…
|
florian
|
313 |
|
|
6ea30fb…
|
florian
|
314 |
/* Run the provided init() function once. This is not thread-safe. */ |
|
6ea30fb…
|
florian
|
315 |
local void z_once(z_once_t *state, void (*init)(void)) { |
|
6ea30fb…
|
florian
|
316 |
if (!state->done) { |
|
6ea30fb…
|
florian
|
317 |
if (test_and_set(&state->begun)) |
|
6ea30fb…
|
florian
|
318 |
while (!state->done) |
|
6ea30fb…
|
florian
|
319 |
; |
|
6ea30fb…
|
florian
|
320 |
else { |
|
6ea30fb…
|
florian
|
321 |
init(); |
|
6ea30fb…
|
florian
|
322 |
state->done = 1; |
|
6ea30fb…
|
florian
|
323 |
} |
|
6ea30fb…
|
florian
|
324 |
} |
|
6ea30fb…
|
florian
|
325 |
} |
|
6ea30fb…
|
florian
|
326 |
|
|
6ea30fb…
|
florian
|
327 |
#endif /* ?atomics */ |
|
6ea30fb…
|
florian
|
328 |
|
|
6ea30fb…
|
florian
|
329 |
#endif /* Z_ONCE */ |
|
7ef7284…
|
drh
|
330 |
|
|
7ef7284…
|
drh
|
331 |
#endif /* ZUTIL_H */ |