~ldgoodridge95/ubuntu/vivid/upstart/rm-libjson0-dev

« back to all changes in this revision

Viewing changes to intl/lock.h

Tags: upstream-1.7
ImportĀ upstreamĀ versionĀ 1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Locking in multithreaded situations.
 
2
   Copyright (C) 2005-2007 Free Software Foundation, Inc.
 
3
 
 
4
   This program is free software; you can redistribute it and/or modify it
 
5
   under the terms of the GNU Library General Public License as published
 
6
   by the Free Software Foundation; either version 2, or (at your option)
 
7
   any later version.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
   Library General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU Library General Public
 
15
   License along with this program; if not, write to the Free Software
 
16
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
17
   USA.  */
 
18
 
 
19
/* Written by Bruno Haible <bruno@clisp.org>, 2005.
 
20
   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
 
21
   gthr-win32.h.  */
 
22
 
 
23
/* This file contains locking primitives for use with a given thread library.
 
24
   It does not contain primitives for creating threads or for other
 
25
   synchronization primitives.
 
26
 
 
27
   Normal (non-recursive) locks:
 
28
     Type:                gl_lock_t
 
29
     Declaration:         gl_lock_define(extern, name)
 
30
     Initializer:         gl_lock_define_initialized(, name)
 
31
     Initialization:      gl_lock_init (name);
 
32
     Taking the lock:     gl_lock_lock (name);
 
33
     Releasing the lock:  gl_lock_unlock (name);
 
34
     De-initialization:   gl_lock_destroy (name);
 
35
 
 
36
   Read-Write (non-recursive) locks:
 
37
     Type:                gl_rwlock_t
 
38
     Declaration:         gl_rwlock_define(extern, name)
 
39
     Initializer:         gl_rwlock_define_initialized(, name)
 
40
     Initialization:      gl_rwlock_init (name);
 
41
     Taking the lock:     gl_rwlock_rdlock (name);
 
42
                          gl_rwlock_wrlock (name);
 
43
     Releasing the lock:  gl_rwlock_unlock (name);
 
44
     De-initialization:   gl_rwlock_destroy (name);
 
45
 
 
46
   Recursive locks:
 
47
     Type:                gl_recursive_lock_t
 
48
     Declaration:         gl_recursive_lock_define(extern, name)
 
49
     Initializer:         gl_recursive_lock_define_initialized(, name)
 
50
     Initialization:      gl_recursive_lock_init (name);
 
51
     Taking the lock:     gl_recursive_lock_lock (name);
 
52
     Releasing the lock:  gl_recursive_lock_unlock (name);
 
53
     De-initialization:   gl_recursive_lock_destroy (name);
 
54
 
 
55
  Once-only execution:
 
56
     Type:                gl_once_t
 
57
     Initializer:         gl_once_define(extern, name)
 
58
     Execution:           gl_once (name, initfunction);
 
59
*/
 
60
 
 
61
 
 
62
#ifndef _LOCK_H
 
63
#define _LOCK_H
 
64
 
 
65
/* ========================================================================= */
 
66
 
 
67
#if USE_POSIX_THREADS
 
68
 
 
69
/* Use the POSIX threads library.  */
 
70
 
 
71
# include <pthread.h>
 
72
# include <stdlib.h>
 
73
 
 
74
# ifdef __cplusplus
 
75
extern "C" {
 
76
# endif
 
77
 
 
78
# if PTHREAD_IN_USE_DETECTION_HARD
 
79
 
 
80
/* The pthread_in_use() detection needs to be done at runtime.  */
 
81
#  define pthread_in_use() \
 
82
     glthread_in_use ()
 
83
extern int glthread_in_use (void);
 
84
 
 
85
# endif
 
86
 
 
87
# if USE_POSIX_THREADS_WEAK
 
88
 
 
89
/* Use weak references to the POSIX threads library.  */
 
90
 
 
91
/* Weak references avoid dragging in external libraries if the other parts
 
92
   of the program don't use them.  Here we use them, because we don't want
 
93
   every program that uses libintl to depend on libpthread.  This assumes
 
94
   that libpthread would not be loaded after libintl; i.e. if libintl is
 
95
   loaded first, by an executable that does not depend on libpthread, and
 
96
   then a module is dynamically loaded that depends on libpthread, libintl
 
97
   will not be multithread-safe.  */
 
98
 
 
99
/* The way to test at runtime whether libpthread is present is to test
 
100
   whether a function pointer's value, such as &pthread_mutex_init, is
 
101
   non-NULL.  However, some versions of GCC have a bug through which, in
 
102
   PIC mode, &foo != NULL always evaluates to true if there is a direct
 
103
   call to foo(...) in the same function.  To avoid this, we test the
 
104
   address of a function in libpthread that we don't use.  */
 
105
 
 
106
#  pragma weak pthread_mutex_init
 
107
#  pragma weak pthread_mutex_lock
 
108
#  pragma weak pthread_mutex_unlock
 
109
#  pragma weak pthread_mutex_destroy
 
110
#  pragma weak pthread_rwlock_init
 
111
#  pragma weak pthread_rwlock_rdlock
 
112
#  pragma weak pthread_rwlock_wrlock
 
113
#  pragma weak pthread_rwlock_unlock
 
114
#  pragma weak pthread_rwlock_destroy
 
115
#  pragma weak pthread_once
 
116
#  pragma weak pthread_cond_init
 
117
#  pragma weak pthread_cond_wait
 
118
#  pragma weak pthread_cond_signal
 
119
#  pragma weak pthread_cond_broadcast
 
120
#  pragma weak pthread_cond_destroy
 
121
#  pragma weak pthread_mutexattr_init
 
122
#  pragma weak pthread_mutexattr_settype
 
123
#  pragma weak pthread_mutexattr_destroy
 
124
#  ifndef pthread_self
 
125
#   pragma weak pthread_self
 
126
#  endif
 
127
 
 
128
#  if !PTHREAD_IN_USE_DETECTION_HARD
 
129
#   pragma weak pthread_cancel
 
130
#   define pthread_in_use() (pthread_cancel != NULL)
 
131
#  endif
 
132
 
 
133
# else
 
134
 
 
135
#  if !PTHREAD_IN_USE_DETECTION_HARD
 
136
#   define pthread_in_use() 1
 
137
#  endif
 
138
 
 
139
# endif
 
140
 
 
141
/* -------------------------- gl_lock_t datatype -------------------------- */
 
142
 
 
143
typedef pthread_mutex_t gl_lock_t;
 
144
# define gl_lock_define(STORAGECLASS, NAME) \
 
145
    STORAGECLASS pthread_mutex_t NAME;
 
146
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
147
    STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
 
148
# define gl_lock_initializer \
 
149
    PTHREAD_MUTEX_INITIALIZER
 
150
# define gl_lock_init(NAME) \
 
151
    do                                                                  \
 
152
      {                                                                 \
 
153
        if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) \
 
154
          abort ();                                                     \
 
155
      }                                                                 \
 
156
    while (0)
 
157
# define gl_lock_lock(NAME) \
 
158
    do                                                            \
 
159
      {                                                           \
 
160
        if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) \
 
161
          abort ();                                               \
 
162
      }                                                           \
 
163
    while (0)
 
164
# define gl_lock_unlock(NAME) \
 
165
    do                                                              \
 
166
      {                                                             \
 
167
        if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) \
 
168
          abort ();                                                 \
 
169
      }                                                             \
 
170
    while (0)
 
171
# define gl_lock_destroy(NAME) \
 
172
    do                                                               \
 
173
      {                                                              \
 
174
        if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) \
 
175
          abort ();                                                  \
 
176
      }                                                              \
 
177
    while (0)
 
178
 
 
179
/* ------------------------- gl_rwlock_t datatype ------------------------- */
 
180
 
 
181
# if HAVE_PTHREAD_RWLOCK
 
182
 
 
183
#  ifdef PTHREAD_RWLOCK_INITIALIZER
 
184
 
 
185
typedef pthread_rwlock_t gl_rwlock_t;
 
186
#   define gl_rwlock_define(STORAGECLASS, NAME) \
 
187
      STORAGECLASS pthread_rwlock_t NAME;
 
188
#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
189
      STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
 
190
#   define gl_rwlock_initializer \
 
191
      PTHREAD_RWLOCK_INITIALIZER
 
192
#   define gl_rwlock_init(NAME) \
 
193
      do                                                                   \
 
194
        {                                                                  \
 
195
          if (pthread_in_use () && pthread_rwlock_init (&NAME, NULL) != 0) \
 
196
            abort ();                                                      \
 
197
        }                                                                  \
 
198
      while (0)
 
199
#   define gl_rwlock_rdlock(NAME) \
 
200
      do                                                               \
 
201
        {                                                              \
 
202
          if (pthread_in_use () && pthread_rwlock_rdlock (&NAME) != 0) \
 
203
            abort ();                                                  \
 
204
        }                                                              \
 
205
      while (0)
 
206
#   define gl_rwlock_wrlock(NAME) \
 
207
      do                                                               \
 
208
        {                                                              \
 
209
          if (pthread_in_use () && pthread_rwlock_wrlock (&NAME) != 0) \
 
210
            abort ();                                                  \
 
211
        }                                                              \
 
212
      while (0)
 
213
#   define gl_rwlock_unlock(NAME) \
 
214
      do                                                               \
 
215
        {                                                              \
 
216
          if (pthread_in_use () && pthread_rwlock_unlock (&NAME) != 0) \
 
217
            abort ();                                                  \
 
218
        }                                                              \
 
219
      while (0)
 
220
#   define gl_rwlock_destroy(NAME) \
 
221
      do                                                                \
 
222
        {                                                               \
 
223
          if (pthread_in_use () && pthread_rwlock_destroy (&NAME) != 0) \
 
224
            abort ();                                                   \
 
225
        }                                                               \
 
226
      while (0)
 
227
 
 
228
#  else
 
229
 
 
230
typedef struct
 
231
        {
 
232
          int initialized;
 
233
          pthread_mutex_t guard;   /* protects the initialization */
 
234
          pthread_rwlock_t rwlock; /* read-write lock */
 
235
        }
 
236
        gl_rwlock_t;
 
237
#   define gl_rwlock_define(STORAGECLASS, NAME) \
 
238
      STORAGECLASS gl_rwlock_t NAME;
 
239
#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
240
      STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 
241
#   define gl_rwlock_initializer \
 
242
      { 0, PTHREAD_MUTEX_INITIALIZER }
 
243
#   define gl_rwlock_init(NAME) \
 
244
      do                                  \
 
245
        {                                 \
 
246
          if (pthread_in_use ())          \
 
247
            glthread_rwlock_init (&NAME); \
 
248
        }                                 \
 
249
      while (0)
 
250
#   define gl_rwlock_rdlock(NAME) \
 
251
      do                                    \
 
252
        {                                   \
 
253
          if (pthread_in_use ())            \
 
254
            glthread_rwlock_rdlock (&NAME); \
 
255
        }                                   \
 
256
      while (0)
 
257
#   define gl_rwlock_wrlock(NAME) \
 
258
      do                                    \
 
259
        {                                   \
 
260
          if (pthread_in_use ())            \
 
261
            glthread_rwlock_wrlock (&NAME); \
 
262
        }                                   \
 
263
      while (0)
 
264
#   define gl_rwlock_unlock(NAME) \
 
265
      do                                    \
 
266
        {                                   \
 
267
          if (pthread_in_use ())            \
 
268
            glthread_rwlock_unlock (&NAME); \
 
269
        }                                   \
 
270
      while (0)
 
271
#   define gl_rwlock_destroy(NAME) \
 
272
      do                                     \
 
273
        {                                    \
 
274
          if (pthread_in_use ())             \
 
275
            glthread_rwlock_destroy (&NAME); \
 
276
        }                                    \
 
277
      while (0)
 
278
extern void glthread_rwlock_init (gl_rwlock_t *lock);
 
279
extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
 
280
extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
 
281
extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
 
282
extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
 
283
 
 
284
#  endif
 
285
 
 
286
# else
 
287
 
 
288
typedef struct
 
289
        {
 
290
          pthread_mutex_t lock; /* protects the remaining fields */
 
291
          pthread_cond_t waiting_readers; /* waiting readers */
 
292
          pthread_cond_t waiting_writers; /* waiting writers */
 
293
          unsigned int waiting_writers_count; /* number of waiting writers */
 
294
          int runcount; /* number of readers running, or -1 when a writer runs */
 
295
        }
 
296
        gl_rwlock_t;
 
297
# define gl_rwlock_define(STORAGECLASS, NAME) \
 
298
    STORAGECLASS gl_rwlock_t NAME;
 
299
# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
300
    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 
301
# define gl_rwlock_initializer \
 
302
    { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
 
303
# define gl_rwlock_init(NAME) \
 
304
    do                                  \
 
305
      {                                 \
 
306
        if (pthread_in_use ())          \
 
307
          glthread_rwlock_init (&NAME); \
 
308
      }                                 \
 
309
    while (0)
 
310
# define gl_rwlock_rdlock(NAME) \
 
311
    do                                    \
 
312
      {                                   \
 
313
        if (pthread_in_use ())            \
 
314
          glthread_rwlock_rdlock (&NAME); \
 
315
      }                                   \
 
316
    while (0)
 
317
# define gl_rwlock_wrlock(NAME) \
 
318
    do                                    \
 
319
      {                                   \
 
320
        if (pthread_in_use ())            \
 
321
          glthread_rwlock_wrlock (&NAME); \
 
322
      }                                   \
 
323
    while (0)
 
324
# define gl_rwlock_unlock(NAME) \
 
325
    do                                    \
 
326
      {                                   \
 
327
        if (pthread_in_use ())            \
 
328
          glthread_rwlock_unlock (&NAME); \
 
329
      }                                   \
 
330
    while (0)
 
331
# define gl_rwlock_destroy(NAME) \
 
332
    do                                     \
 
333
      {                                    \
 
334
        if (pthread_in_use ())             \
 
335
          glthread_rwlock_destroy (&NAME); \
 
336
      }                                    \
 
337
    while (0)
 
338
extern void glthread_rwlock_init (gl_rwlock_t *lock);
 
339
extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
 
340
extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
 
341
extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
 
342
extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
 
343
 
 
344
# endif
 
345
 
 
346
/* --------------------- gl_recursive_lock_t datatype --------------------- */
 
347
 
 
348
# if HAVE_PTHREAD_MUTEX_RECURSIVE
 
349
 
 
350
#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
351
 
 
352
typedef pthread_mutex_t gl_recursive_lock_t;
 
353
#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
354
      STORAGECLASS pthread_mutex_t NAME;
 
355
#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
356
      STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
 
357
#   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
 
358
#    define gl_recursive_lock_initializer \
 
359
       PTHREAD_RECURSIVE_MUTEX_INITIALIZER
 
360
#   else
 
361
#    define gl_recursive_lock_initializer \
 
362
       PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
363
#   endif
 
364
#   define gl_recursive_lock_init(NAME) \
 
365
      do                                                                  \
 
366
        {                                                                 \
 
367
          if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) \
 
368
            abort ();                                                     \
 
369
        }                                                                 \
 
370
      while (0)
 
371
#   define gl_recursive_lock_lock(NAME) \
 
372
      do                                                            \
 
373
        {                                                           \
 
374
          if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) \
 
375
            abort ();                                               \
 
376
        }                                                           \
 
377
      while (0)
 
378
#   define gl_recursive_lock_unlock(NAME) \
 
379
      do                                                              \
 
380
        {                                                             \
 
381
          if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) \
 
382
            abort ();                                                 \
 
383
        }                                                             \
 
384
      while (0)
 
385
#   define gl_recursive_lock_destroy(NAME) \
 
386
      do                                                               \
 
387
        {                                                              \
 
388
          if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) \
 
389
            abort ();                                                  \
 
390
        }                                                              \
 
391
      while (0)
 
392
 
 
393
#  else
 
394
 
 
395
typedef struct
 
396
        {
 
397
          pthread_mutex_t recmutex; /* recursive mutex */
 
398
          pthread_mutex_t guard;    /* protects the initialization */
 
399
          int initialized;
 
400
        }
 
401
        gl_recursive_lock_t;
 
402
#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
403
      STORAGECLASS gl_recursive_lock_t NAME;
 
404
#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
405
      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
406
#   define gl_recursive_lock_initializer \
 
407
      { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
 
408
#   define gl_recursive_lock_init(NAME) \
 
409
      do                                          \
 
410
        {                                         \
 
411
          if (pthread_in_use ())                  \
 
412
            glthread_recursive_lock_init (&NAME); \
 
413
        }                                         \
 
414
      while (0)
 
415
#   define gl_recursive_lock_lock(NAME) \
 
416
      do                                          \
 
417
        {                                         \
 
418
          if (pthread_in_use ())                  \
 
419
            glthread_recursive_lock_lock (&NAME); \
 
420
        }                                         \
 
421
      while (0)
 
422
#   define gl_recursive_lock_unlock(NAME) \
 
423
      do                                            \
 
424
        {                                           \
 
425
          if (pthread_in_use ())                    \
 
426
            glthread_recursive_lock_unlock (&NAME); \
 
427
        }                                           \
 
428
      while (0)
 
429
#   define gl_recursive_lock_destroy(NAME) \
 
430
      do                                             \
 
431
        {                                            \
 
432
          if (pthread_in_use ())                     \
 
433
            glthread_recursive_lock_destroy (&NAME); \
 
434
        }                                            \
 
435
      while (0)
 
436
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
437
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
438
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
439
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
440
 
 
441
#  endif
 
442
 
 
443
# else
 
444
 
 
445
/* Old versions of POSIX threads on Solaris did not have recursive locks.
 
446
   We have to implement them ourselves.  */
 
447
 
 
448
typedef struct
 
449
        {
 
450
          pthread_mutex_t mutex;
 
451
          pthread_t owner;
 
452
          unsigned long depth;
 
453
        }
 
454
        gl_recursive_lock_t;
 
455
#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
456
     STORAGECLASS gl_recursive_lock_t NAME;
 
457
#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
458
     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
459
#  define gl_recursive_lock_initializer \
 
460
     { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
 
461
#  define gl_recursive_lock_init(NAME) \
 
462
     do                                          \
 
463
       {                                         \
 
464
         if (pthread_in_use ())                  \
 
465
           glthread_recursive_lock_init (&NAME); \
 
466
       }                                         \
 
467
     while (0)
 
468
#  define gl_recursive_lock_lock(NAME) \
 
469
     do                                          \
 
470
       {                                         \
 
471
         if (pthread_in_use ())                  \
 
472
           glthread_recursive_lock_lock (&NAME); \
 
473
       }                                         \
 
474
     while (0)
 
475
#  define gl_recursive_lock_unlock(NAME) \
 
476
     do                                            \
 
477
       {                                           \
 
478
         if (pthread_in_use ())                    \
 
479
           glthread_recursive_lock_unlock (&NAME); \
 
480
       }                                           \
 
481
     while (0)
 
482
#  define gl_recursive_lock_destroy(NAME) \
 
483
     do                                             \
 
484
       {                                            \
 
485
         if (pthread_in_use ())                     \
 
486
           glthread_recursive_lock_destroy (&NAME); \
 
487
       }                                            \
 
488
     while (0)
 
489
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
490
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
491
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
492
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
493
 
 
494
# endif
 
495
 
 
496
/* -------------------------- gl_once_t datatype -------------------------- */
 
497
 
 
498
typedef pthread_once_t gl_once_t;
 
499
# define gl_once_define(STORAGECLASS, NAME) \
 
500
    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
 
501
# define gl_once(NAME, INITFUNCTION) \
 
502
    do                                                   \
 
503
      {                                                  \
 
504
        if (pthread_in_use ())                           \
 
505
          {                                              \
 
506
            if (pthread_once (&NAME, INITFUNCTION) != 0) \
 
507
              abort ();                                  \
 
508
          }                                              \
 
509
        else                                             \
 
510
          {                                              \
 
511
            if (glthread_once_singlethreaded (&NAME))    \
 
512
              INITFUNCTION ();                           \
 
513
          }                                              \
 
514
      }                                                  \
 
515
    while (0)
 
516
extern int glthread_once_singlethreaded (pthread_once_t *once_control);
 
517
 
 
518
# ifdef __cplusplus
 
519
}
 
520
# endif
 
521
 
 
522
#endif
 
523
 
 
524
/* ========================================================================= */
 
525
 
 
526
#if USE_PTH_THREADS
 
527
 
 
528
/* Use the GNU Pth threads library.  */
 
529
 
 
530
# include <pth.h>
 
531
# include <stdlib.h>
 
532
 
 
533
# ifdef __cplusplus
 
534
extern "C" {
 
535
# endif
 
536
 
 
537
# if USE_PTH_THREADS_WEAK
 
538
 
 
539
/* Use weak references to the GNU Pth threads library.  */
 
540
 
 
541
#  pragma weak pth_mutex_init
 
542
#  pragma weak pth_mutex_acquire
 
543
#  pragma weak pth_mutex_release
 
544
#  pragma weak pth_rwlock_init
 
545
#  pragma weak pth_rwlock_acquire
 
546
#  pragma weak pth_rwlock_release
 
547
#  pragma weak pth_once
 
548
 
 
549
#  pragma weak pth_cancel
 
550
#  define pth_in_use() (pth_cancel != NULL)
 
551
 
 
552
# else
 
553
 
 
554
#  define pth_in_use() 1
 
555
 
 
556
# endif
 
557
 
 
558
/* -------------------------- gl_lock_t datatype -------------------------- */
 
559
 
 
560
typedef pth_mutex_t gl_lock_t;
 
561
# define gl_lock_define(STORAGECLASS, NAME) \
 
562
    STORAGECLASS pth_mutex_t NAME;
 
563
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
564
    STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
 
565
# define gl_lock_initializer \
 
566
    PTH_MUTEX_INIT
 
567
# define gl_lock_init(NAME) \
 
568
    do                                               \
 
569
      {                                              \
 
570
        if (pth_in_use() && !pth_mutex_init (&NAME)) \
 
571
          abort ();                                  \
 
572
      }                                              \
 
573
    while (0)
 
574
# define gl_lock_lock(NAME) \
 
575
    do                                                           \
 
576
      {                                                          \
 
577
        if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) \
 
578
          abort ();                                              \
 
579
      }                                                          \
 
580
    while (0)
 
581
# define gl_lock_unlock(NAME) \
 
582
    do                                                  \
 
583
      {                                                 \
 
584
        if (pth_in_use() && !pth_mutex_release (&NAME)) \
 
585
          abort ();                                     \
 
586
      }                                                 \
 
587
    while (0)
 
588
# define gl_lock_destroy(NAME) \
 
589
    (void)(&NAME)
 
590
 
 
591
/* ------------------------- gl_rwlock_t datatype ------------------------- */
 
592
 
 
593
typedef pth_rwlock_t gl_rwlock_t;
 
594
#  define gl_rwlock_define(STORAGECLASS, NAME) \
 
595
     STORAGECLASS pth_rwlock_t NAME;
 
596
#  define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
597
     STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
 
598
#  define gl_rwlock_initializer \
 
599
     PTH_RWLOCK_INIT
 
600
#  define gl_rwlock_init(NAME) \
 
601
     do                                                \
 
602
       {                                               \
 
603
         if (pth_in_use() && !pth_rwlock_init (&NAME)) \
 
604
           abort ();                                   \
 
605
       }                                               \
 
606
     while (0)
 
607
#  define gl_rwlock_rdlock(NAME) \
 
608
     do                                                              \
 
609
       {                                                             \
 
610
         if (pth_in_use()                                            \
 
611
             && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) \
 
612
           abort ();                                                 \
 
613
       }                                                             \
 
614
     while (0)
 
615
#  define gl_rwlock_wrlock(NAME) \
 
616
     do                                                              \
 
617
       {                                                             \
 
618
         if (pth_in_use()                                            \
 
619
             && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) \
 
620
           abort ();                                                 \
 
621
       }                                                             \
 
622
     while (0)
 
623
#  define gl_rwlock_unlock(NAME) \
 
624
     do                                                   \
 
625
       {                                                  \
 
626
         if (pth_in_use() && !pth_rwlock_release (&NAME)) \
 
627
           abort ();                                      \
 
628
       }                                                  \
 
629
     while (0)
 
630
#  define gl_rwlock_destroy(NAME) \
 
631
     (void)(&NAME)
 
632
 
 
633
/* --------------------- gl_recursive_lock_t datatype --------------------- */
 
634
 
 
635
/* In Pth, mutexes are recursive by default.  */
 
636
typedef pth_mutex_t gl_recursive_lock_t;
 
637
#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
638
     STORAGECLASS pth_mutex_t NAME;
 
639
#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
640
     STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
 
641
#  define gl_recursive_lock_initializer \
 
642
     PTH_MUTEX_INIT
 
643
#  define gl_recursive_lock_init(NAME) \
 
644
     do                                               \
 
645
       {                                              \
 
646
         if (pth_in_use() && !pth_mutex_init (&NAME)) \
 
647
           abort ();                                  \
 
648
       }                                              \
 
649
     while (0)
 
650
#  define gl_recursive_lock_lock(NAME) \
 
651
     do                                                           \
 
652
       {                                                          \
 
653
         if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) \
 
654
           abort ();                                              \
 
655
       }                                                          \
 
656
     while (0)
 
657
#  define gl_recursive_lock_unlock(NAME) \
 
658
     do                                                  \
 
659
       {                                                 \
 
660
         if (pth_in_use() && !pth_mutex_release (&NAME)) \
 
661
           abort ();                                     \
 
662
       }                                                 \
 
663
     while (0)
 
664
#  define gl_recursive_lock_destroy(NAME) \
 
665
     (void)(&NAME)
 
666
 
 
667
/* -------------------------- gl_once_t datatype -------------------------- */
 
668
 
 
669
typedef pth_once_t gl_once_t;
 
670
# define gl_once_define(STORAGECLASS, NAME) \
 
671
    STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
 
672
# define gl_once(NAME, INITFUNCTION) \
 
673
    do                                                                \
 
674
      {                                                               \
 
675
        if (pth_in_use ())                                            \
 
676
          {                                                           \
 
677
            void (*gl_once_temp) (void) = INITFUNCTION;               \
 
678
            if (!pth_once (&NAME, glthread_once_call, &gl_once_temp)) \
 
679
              abort ();                                               \
 
680
          }                                                           \
 
681
        else                                                          \
 
682
          {                                                           \
 
683
            if (glthread_once_singlethreaded (&NAME))                 \
 
684
              INITFUNCTION ();                                        \
 
685
          }                                                           \
 
686
      }                                                               \
 
687
    while (0)
 
688
extern void glthread_once_call (void *arg);
 
689
extern int glthread_once_singlethreaded (pth_once_t *once_control);
 
690
 
 
691
# ifdef __cplusplus
 
692
}
 
693
# endif
 
694
 
 
695
#endif
 
696
 
 
697
/* ========================================================================= */
 
698
 
 
699
#if USE_SOLARIS_THREADS
 
700
 
 
701
/* Use the old Solaris threads library.  */
 
702
 
 
703
# include <thread.h>
 
704
# include <synch.h>
 
705
# include <stdlib.h>
 
706
 
 
707
# ifdef __cplusplus
 
708
extern "C" {
 
709
# endif
 
710
 
 
711
# if USE_SOLARIS_THREADS_WEAK
 
712
 
 
713
/* Use weak references to the old Solaris threads library.  */
 
714
 
 
715
#  pragma weak mutex_init
 
716
#  pragma weak mutex_lock
 
717
#  pragma weak mutex_unlock
 
718
#  pragma weak mutex_destroy
 
719
#  pragma weak rwlock_init
 
720
#  pragma weak rw_rdlock
 
721
#  pragma weak rw_wrlock
 
722
#  pragma weak rw_unlock
 
723
#  pragma weak rwlock_destroy
 
724
#  pragma weak thr_self
 
725
 
 
726
#  pragma weak thr_suspend
 
727
#  define thread_in_use() (thr_suspend != NULL)
 
728
 
 
729
# else
 
730
 
 
731
#  define thread_in_use() 1
 
732
 
 
733
# endif
 
734
 
 
735
/* -------------------------- gl_lock_t datatype -------------------------- */
 
736
 
 
737
typedef mutex_t gl_lock_t;
 
738
# define gl_lock_define(STORAGECLASS, NAME) \
 
739
    STORAGECLASS mutex_t NAME;
 
740
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
741
    STORAGECLASS mutex_t NAME = gl_lock_initializer;
 
742
# define gl_lock_initializer \
 
743
    DEFAULTMUTEX
 
744
# define gl_lock_init(NAME) \
 
745
    do                                                                       \
 
746
      {                                                                      \
 
747
        if (thread_in_use () && mutex_init (&NAME, USYNC_THREAD, NULL) != 0) \
 
748
          abort ();                                                          \
 
749
      }                                                                      \
 
750
    while (0)
 
751
# define gl_lock_lock(NAME) \
 
752
    do                                                   \
 
753
      {                                                  \
 
754
        if (thread_in_use () && mutex_lock (&NAME) != 0) \
 
755
          abort ();                                      \
 
756
      }                                                  \
 
757
    while (0)
 
758
# define gl_lock_unlock(NAME) \
 
759
    do                                                     \
 
760
      {                                                    \
 
761
        if (thread_in_use () && mutex_unlock (&NAME) != 0) \
 
762
          abort ();                                        \
 
763
      }                                                    \
 
764
    while (0)
 
765
# define gl_lock_destroy(NAME) \
 
766
    do                                                      \
 
767
      {                                                     \
 
768
        if (thread_in_use () && mutex_destroy (&NAME) != 0) \
 
769
          abort ();                                         \
 
770
      }                                                     \
 
771
    while (0)
 
772
 
 
773
/* ------------------------- gl_rwlock_t datatype ------------------------- */
 
774
 
 
775
typedef rwlock_t gl_rwlock_t;
 
776
# define gl_rwlock_define(STORAGECLASS, NAME) \
 
777
    STORAGECLASS rwlock_t NAME;
 
778
# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
779
    STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
 
780
# define gl_rwlock_initializer \
 
781
    DEFAULTRWLOCK
 
782
# define gl_rwlock_init(NAME) \
 
783
    do                                                                        \
 
784
      {                                                                       \
 
785
        if (thread_in_use () && rwlock_init (&NAME, USYNC_THREAD, NULL) != 0) \
 
786
          abort ();                                                           \
 
787
      }                                                                       \
 
788
    while (0)
 
789
# define gl_rwlock_rdlock(NAME) \
 
790
    do                                                  \
 
791
      {                                                 \
 
792
        if (thread_in_use () && rw_rdlock (&NAME) != 0) \
 
793
          abort ();                                     \
 
794
      }                                                 \
 
795
    while (0)
 
796
# define gl_rwlock_wrlock(NAME) \
 
797
    do                                                  \
 
798
      {                                                 \
 
799
        if (thread_in_use () && rw_wrlock (&NAME) != 0) \
 
800
          abort ();                                     \
 
801
      }                                                 \
 
802
    while (0)
 
803
# define gl_rwlock_unlock(NAME) \
 
804
    do                                                  \
 
805
      {                                                 \
 
806
        if (thread_in_use () && rw_unlock (&NAME) != 0) \
 
807
          abort ();                                     \
 
808
      }                                                 \
 
809
    while (0)
 
810
# define gl_rwlock_destroy(NAME) \
 
811
    do                                                       \
 
812
      {                                                      \
 
813
        if (thread_in_use () && rwlock_destroy (&NAME) != 0) \
 
814
          abort ();                                          \
 
815
      }                                                      \
 
816
    while (0)
 
817
 
 
818
/* --------------------- gl_recursive_lock_t datatype --------------------- */
 
819
 
 
820
/* Old Solaris threads did not have recursive locks.
 
821
   We have to implement them ourselves.  */
 
822
 
 
823
typedef struct
 
824
        {
 
825
          mutex_t mutex;
 
826
          thread_t owner;
 
827
          unsigned long depth;
 
828
        }
 
829
        gl_recursive_lock_t;
 
830
# define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
831
    STORAGECLASS gl_recursive_lock_t NAME;
 
832
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
833
    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
834
# define gl_recursive_lock_initializer \
 
835
    { DEFAULTMUTEX, (thread_t) 0, 0 }
 
836
# define gl_recursive_lock_init(NAME) \
 
837
    do                                          \
 
838
      {                                         \
 
839
        if (thread_in_use ())                   \
 
840
          glthread_recursive_lock_init (&NAME); \
 
841
      }                                         \
 
842
    while (0)
 
843
# define gl_recursive_lock_lock(NAME) \
 
844
    do                                          \
 
845
      {                                         \
 
846
        if (thread_in_use ())                   \
 
847
          glthread_recursive_lock_lock (&NAME); \
 
848
      }                                         \
 
849
    while (0)
 
850
# define gl_recursive_lock_unlock(NAME) \
 
851
    do                                            \
 
852
      {                                           \
 
853
        if (thread_in_use ())                     \
 
854
          glthread_recursive_lock_unlock (&NAME); \
 
855
      }                                           \
 
856
    while (0)
 
857
# define gl_recursive_lock_destroy(NAME) \
 
858
    do                                             \
 
859
      {                                            \
 
860
        if (thread_in_use ())                      \
 
861
          glthread_recursive_lock_destroy (&NAME); \
 
862
      }                                            \
 
863
    while (0)
 
864
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
865
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
866
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
867
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
868
 
 
869
/* -------------------------- gl_once_t datatype -------------------------- */
 
870
 
 
871
typedef struct
 
872
        {
 
873
          volatile int inited;
 
874
          mutex_t mutex;
 
875
        }
 
876
        gl_once_t;
 
877
# define gl_once_define(STORAGECLASS, NAME) \
 
878
    STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
 
879
# define gl_once(NAME, INITFUNCTION) \
 
880
    do                                                \
 
881
      {                                               \
 
882
        if (thread_in_use ())                         \
 
883
          {                                           \
 
884
            glthread_once (&NAME, INITFUNCTION);      \
 
885
          }                                           \
 
886
        else                                          \
 
887
          {                                           \
 
888
            if (glthread_once_singlethreaded (&NAME)) \
 
889
              INITFUNCTION ();                        \
 
890
          }                                           \
 
891
      }                                               \
 
892
    while (0)
 
893
extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
 
894
extern int glthread_once_singlethreaded (gl_once_t *once_control);
 
895
 
 
896
# ifdef __cplusplus
 
897
}
 
898
# endif
 
899
 
 
900
#endif
 
901
 
 
902
/* ========================================================================= */
 
903
 
 
904
#if USE_WIN32_THREADS
 
905
 
 
906
# include <windows.h>
 
907
 
 
908
# ifdef __cplusplus
 
909
extern "C" {
 
910
# endif
 
911
 
 
912
/* We can use CRITICAL_SECTION directly, rather than the Win32 Event, Mutex,
 
913
   Semaphore types, because
 
914
     - we need only to synchronize inside a single process (address space),
 
915
       not inter-process locking,
 
916
     - we don't need to support trylock operations.  (TryEnterCriticalSection
 
917
       does not work on Windows 95/98/ME.  Packages that need trylock usually
 
918
       define their own mutex type.)  */
 
919
 
 
920
/* There is no way to statically initialize a CRITICAL_SECTION.  It needs
 
921
   to be done lazily, once only.  For this we need spinlocks.  */
 
922
 
 
923
typedef struct { volatile int done; volatile long started; } gl_spinlock_t;
 
924
 
 
925
/* -------------------------- gl_lock_t datatype -------------------------- */
 
926
 
 
927
typedef struct
 
928
        {
 
929
          gl_spinlock_t guard; /* protects the initialization */
 
930
          CRITICAL_SECTION lock;
 
931
        }
 
932
        gl_lock_t;
 
933
# define gl_lock_define(STORAGECLASS, NAME) \
 
934
    STORAGECLASS gl_lock_t NAME;
 
935
# define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
936
    STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
 
937
# define gl_lock_initializer \
 
938
    { { 0, -1 } }
 
939
# define gl_lock_init(NAME) \
 
940
    glthread_lock_init (&NAME)
 
941
# define gl_lock_lock(NAME) \
 
942
    glthread_lock_lock (&NAME)
 
943
# define gl_lock_unlock(NAME) \
 
944
    glthread_lock_unlock (&NAME)
 
945
# define gl_lock_destroy(NAME) \
 
946
    glthread_lock_destroy (&NAME)
 
947
extern void glthread_lock_init (gl_lock_t *lock);
 
948
extern void glthread_lock_lock (gl_lock_t *lock);
 
949
extern void glthread_lock_unlock (gl_lock_t *lock);
 
950
extern void glthread_lock_destroy (gl_lock_t *lock);
 
951
 
 
952
/* ------------------------- gl_rwlock_t datatype ------------------------- */
 
953
 
 
954
/* It is impossible to implement read-write locks using plain locks, without
 
955
   introducing an extra thread dedicated to managing read-write locks.
 
956
   Therefore here we need to use the low-level Event type.  */
 
957
 
 
958
typedef struct
 
959
        {
 
960
          HANDLE *array; /* array of waiting threads, each represented by an event */
 
961
          unsigned int count; /* number of waiting threads */
 
962
          unsigned int alloc; /* length of allocated array */
 
963
          unsigned int offset; /* index of first waiting thread in array */
 
964
        }
 
965
        gl_waitqueue_t;
 
966
typedef struct
 
967
        {
 
968
          gl_spinlock_t guard; /* protects the initialization */
 
969
          CRITICAL_SECTION lock; /* protects the remaining fields */
 
970
          gl_waitqueue_t waiting_readers; /* waiting readers */
 
971
          gl_waitqueue_t waiting_writers; /* waiting writers */
 
972
          int runcount; /* number of readers running, or -1 when a writer runs */
 
973
        }
 
974
        gl_rwlock_t;
 
975
# define gl_rwlock_define(STORAGECLASS, NAME) \
 
976
    STORAGECLASS gl_rwlock_t NAME;
 
977
# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
978
    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 
979
# define gl_rwlock_initializer \
 
980
    { { 0, -1 } }
 
981
# define gl_rwlock_init(NAME) \
 
982
    glthread_rwlock_init (&NAME)
 
983
# define gl_rwlock_rdlock(NAME) \
 
984
    glthread_rwlock_rdlock (&NAME)
 
985
# define gl_rwlock_wrlock(NAME) \
 
986
    glthread_rwlock_wrlock (&NAME)
 
987
# define gl_rwlock_unlock(NAME) \
 
988
    glthread_rwlock_unlock (&NAME)
 
989
# define gl_rwlock_destroy(NAME) \
 
990
    glthread_rwlock_destroy (&NAME)
 
991
extern void glthread_rwlock_init (gl_rwlock_t *lock);
 
992
extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
 
993
extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
 
994
extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
 
995
extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
 
996
 
 
997
/* --------------------- gl_recursive_lock_t datatype --------------------- */
 
998
 
 
999
/* The Win32 documentation says that CRITICAL_SECTION already implements a
 
1000
   recursive lock.  But we need not rely on it: It's easy to implement a
 
1001
   recursive lock without this assumption.  */
 
1002
 
 
1003
typedef struct
 
1004
        {
 
1005
          gl_spinlock_t guard; /* protects the initialization */
 
1006
          DWORD owner;
 
1007
          unsigned long depth;
 
1008
          CRITICAL_SECTION lock;
 
1009
        }
 
1010
        gl_recursive_lock_t;
 
1011
# define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
1012
    STORAGECLASS gl_recursive_lock_t NAME;
 
1013
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
1014
    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
1015
# define gl_recursive_lock_initializer \
 
1016
    { { 0, -1 }, 0, 0 }
 
1017
# define gl_recursive_lock_init(NAME) \
 
1018
    glthread_recursive_lock_init (&NAME)
 
1019
# define gl_recursive_lock_lock(NAME) \
 
1020
    glthread_recursive_lock_lock (&NAME)
 
1021
# define gl_recursive_lock_unlock(NAME) \
 
1022
    glthread_recursive_lock_unlock (&NAME)
 
1023
# define gl_recursive_lock_destroy(NAME) \
 
1024
    glthread_recursive_lock_destroy (&NAME)
 
1025
extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
1026
extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
1027
extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
1028
extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
1029
 
 
1030
/* -------------------------- gl_once_t datatype -------------------------- */
 
1031
 
 
1032
typedef struct
 
1033
        {
 
1034
          volatile int inited;
 
1035
          volatile long started;
 
1036
          CRITICAL_SECTION lock;
 
1037
        }
 
1038
        gl_once_t;
 
1039
# define gl_once_define(STORAGECLASS, NAME) \
 
1040
    STORAGECLASS gl_once_t NAME = { -1, -1 };
 
1041
# define gl_once(NAME, INITFUNCTION) \
 
1042
    glthread_once (&NAME, INITFUNCTION)
 
1043
extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
 
1044
 
 
1045
# ifdef __cplusplus
 
1046
}
 
1047
# endif
 
1048
 
 
1049
#endif
 
1050
 
 
1051
/* ========================================================================= */
 
1052
 
 
1053
#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS)
 
1054
 
 
1055
/* Provide dummy implementation if threads are not supported.  */
 
1056
 
 
1057
/* -------------------------- gl_lock_t datatype -------------------------- */
 
1058
 
 
1059
typedef int gl_lock_t;
 
1060
# define gl_lock_define(STORAGECLASS, NAME)
 
1061
# define gl_lock_define_initialized(STORAGECLASS, NAME)
 
1062
# define gl_lock_init(NAME)
 
1063
# define gl_lock_lock(NAME)
 
1064
# define gl_lock_unlock(NAME)
 
1065
 
 
1066
/* ------------------------- gl_rwlock_t datatype ------------------------- */
 
1067
 
 
1068
typedef int gl_rwlock_t;
 
1069
# define gl_rwlock_define(STORAGECLASS, NAME)
 
1070
# define gl_rwlock_define_initialized(STORAGECLASS, NAME)
 
1071
# define gl_rwlock_init(NAME)
 
1072
# define gl_rwlock_rdlock(NAME)
 
1073
# define gl_rwlock_wrlock(NAME)
 
1074
# define gl_rwlock_unlock(NAME)
 
1075
 
 
1076
/* --------------------- gl_recursive_lock_t datatype --------------------- */
 
1077
 
 
1078
typedef int gl_recursive_lock_t;
 
1079
# define gl_recursive_lock_define(STORAGECLASS, NAME)
 
1080
# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
 
1081
# define gl_recursive_lock_init(NAME)
 
1082
# define gl_recursive_lock_lock(NAME)
 
1083
# define gl_recursive_lock_unlock(NAME)
 
1084
 
 
1085
/* -------------------------- gl_once_t datatype -------------------------- */
 
1086
 
 
1087
typedef int gl_once_t;
 
1088
# define gl_once_define(STORAGECLASS, NAME) \
 
1089
    STORAGECLASS gl_once_t NAME = 0;
 
1090
# define gl_once(NAME, INITFUNCTION) \
 
1091
    do                       \
 
1092
      {                      \
 
1093
        if (NAME == 0)       \
 
1094
          {                  \
 
1095
            NAME = ~ 0;      \
 
1096
            INITFUNCTION (); \
 
1097
          }                  \
 
1098
      }                      \
 
1099
    while (0)
 
1100
 
 
1101
#endif
 
1102
 
 
1103
/* ========================================================================= */
 
1104
 
 
1105
#endif /* _LOCK_H */