~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

Viewing changes to gettext-tools/libgettextpo/lock.h

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

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