| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105 | 
							- /* Locking in multithreaded situations.
 
-    Copyright (C) 2005-2007 Free Software Foundation, Inc.
 
-    This program is free software; you can redistribute it and/or modify it
 
-    under the terms of the GNU Library General Public License as published
 
-    by the Free Software Foundation; either version 2, or (at your option)
 
-    any later version.
 
-    This program is distributed in the hope that it will be useful,
 
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
-    Library General Public License for more details.
 
-    You should have received a copy of the GNU Library General Public
 
-    License along with this program; if not, write to the Free Software
 
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
-    USA.  */
 
- /* Written by Bruno Haible <bruno@clisp.org>, 2005.
 
-    Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
 
-    gthr-win32.h.  */
 
- /* This file contains locking primitives for use with a given thread library.
 
-    It does not contain primitives for creating threads or for other
 
-    synchronization primitives.
 
-    Normal (non-recursive) locks:
 
-      Type:                gl_lock_t
 
-      Declaration:         gl_lock_define(extern, name)
 
-      Initializer:         gl_lock_define_initialized(, name)
 
-      Initialization:      gl_lock_init (name);
 
-      Taking the lock:     gl_lock_lock (name);
 
-      Releasing the lock:  gl_lock_unlock (name);
 
-      De-initialization:   gl_lock_destroy (name);
 
-    Read-Write (non-recursive) locks:
 
-      Type:                gl_rwlock_t
 
-      Declaration:         gl_rwlock_define(extern, name)
 
-      Initializer:         gl_rwlock_define_initialized(, name)
 
-      Initialization:      gl_rwlock_init (name);
 
-      Taking the lock:     gl_rwlock_rdlock (name);
 
-                           gl_rwlock_wrlock (name);
 
-      Releasing the lock:  gl_rwlock_unlock (name);
 
-      De-initialization:   gl_rwlock_destroy (name);
 
-    Recursive locks:
 
-      Type:                gl_recursive_lock_t
 
-      Declaration:         gl_recursive_lock_define(extern, name)
 
-      Initializer:         gl_recursive_lock_define_initialized(, name)
 
-      Initialization:      gl_recursive_lock_init (name);
 
-      Taking the lock:     gl_recursive_lock_lock (name);
 
-      Releasing the lock:  gl_recursive_lock_unlock (name);
 
-      De-initialization:   gl_recursive_lock_destroy (name);
 
-   Once-only execution:
 
-      Type:                gl_once_t
 
-      Initializer:         gl_once_define(extern, name)
 
-      Execution:           gl_once (name, initfunction);
 
- */
 
- #ifndef _LOCK_H
 
- #define _LOCK_H
 
- /* ========================================================================= */
 
- #if USE_POSIX_THREADS
 
- /* Use the POSIX threads library.  */
 
- # include <pthread.h>
 
- # include <stdlib.h>
 
- # ifdef __cplusplus
 
- extern "C" {
 
- # endif
 
- # if PTHREAD_IN_USE_DETECTION_HARD
 
- /* The pthread_in_use() detection needs to be done at runtime.  */
 
- #  define pthread_in_use() \
 
-      glthread_in_use ()
 
- extern int glthread_in_use (void);
 
- # endif
 
- # if USE_POSIX_THREADS_WEAK
 
- /* Use weak references to the POSIX threads library.  */
 
- /* Weak references avoid dragging in external libraries if the other parts
 
-    of the program don't use them.  Here we use them, because we don't want
 
-    every program that uses libintl to depend on libpthread.  This assumes
 
-    that libpthread would not be loaded after libintl; i.e. if libintl is
 
-    loaded first, by an executable that does not depend on libpthread, and
 
-    then a module is dynamically loaded that depends on libpthread, libintl
 
-    will not be multithread-safe.  */
 
- /* The way to test at runtime whether libpthread is present is to test
 
-    whether a function pointer's value, such as &pthread_mutex_init, is
 
-    non-NULL.  However, some versions of GCC have a bug through which, in
 
-    PIC mode, &foo != NULL always evaluates to true if there is a direct
 
-    call to foo(...) in the same function.  To avoid this, we test the
 
-    address of a function in libpthread that we don't use.  */
 
- #  pragma weak pthread_mutex_init
 
- #  pragma weak pthread_mutex_lock
 
- #  pragma weak pthread_mutex_unlock
 
- #  pragma weak pthread_mutex_destroy
 
- #  pragma weak pthread_rwlock_init
 
- #  pragma weak pthread_rwlock_rdlock
 
- #  pragma weak pthread_rwlock_wrlock
 
- #  pragma weak pthread_rwlock_unlock
 
- #  pragma weak pthread_rwlock_destroy
 
- #  pragma weak pthread_once
 
- #  pragma weak pthread_cond_init
 
- #  pragma weak pthread_cond_wait
 
- #  pragma weak pthread_cond_signal
 
- #  pragma weak pthread_cond_broadcast
 
- #  pragma weak pthread_cond_destroy
 
- #  pragma weak pthread_mutexattr_init
 
- #  pragma weak pthread_mutexattr_settype
 
- #  pragma weak pthread_mutexattr_destroy
 
- #  ifndef pthread_self
 
- #   pragma weak pthread_self
 
- #  endif
 
- #  if !PTHREAD_IN_USE_DETECTION_HARD
 
- #   pragma weak pthread_cancel
 
- #   define pthread_in_use() (pthread_cancel != NULL)
 
- #  endif
 
- # else
 
- #  if !PTHREAD_IN_USE_DETECTION_HARD
 
- #   define pthread_in_use() 1
 
- #  endif
 
- # endif
 
- /* -------------------------- gl_lock_t datatype -------------------------- */
 
- typedef pthread_mutex_t gl_lock_t;
 
- # define gl_lock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS pthread_mutex_t NAME;
 
- # define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
 
- # define gl_lock_initializer \
 
-     PTHREAD_MUTEX_INITIALIZER
 
- # define gl_lock_init(NAME) \
 
-     do                                                                  \
 
-       {                                                                 \
 
-         if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) \
 
-           abort ();                                                     \
 
-       }                                                                 \
 
-     while (0)
 
- # define gl_lock_lock(NAME) \
 
-     do                                                            \
 
-       {                                                           \
 
-         if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) \
 
-           abort ();                                               \
 
-       }                                                           \
 
-     while (0)
 
- # define gl_lock_unlock(NAME) \
 
-     do                                                              \
 
-       {                                                             \
 
-         if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) \
 
-           abort ();                                                 \
 
-       }                                                             \
 
-     while (0)
 
- # define gl_lock_destroy(NAME) \
 
-     do                                                               \
 
-       {                                                              \
 
-         if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) \
 
-           abort ();                                                  \
 
-       }                                                              \
 
-     while (0)
 
- /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
- # if HAVE_PTHREAD_RWLOCK
 
- #  ifdef PTHREAD_RWLOCK_INITIALIZER
 
- typedef pthread_rwlock_t gl_rwlock_t;
 
- #   define gl_rwlock_define(STORAGECLASS, NAME) \
 
-       STORAGECLASS pthread_rwlock_t NAME;
 
- #   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
-       STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
 
- #   define gl_rwlock_initializer \
 
-       PTHREAD_RWLOCK_INITIALIZER
 
- #   define gl_rwlock_init(NAME) \
 
-       do                                                                   \
 
-         {                                                                  \
 
-           if (pthread_in_use () && pthread_rwlock_init (&NAME, NULL) != 0) \
 
-             abort ();                                                      \
 
-         }                                                                  \
 
-       while (0)
 
- #   define gl_rwlock_rdlock(NAME) \
 
-       do                                                               \
 
-         {                                                              \
 
-           if (pthread_in_use () && pthread_rwlock_rdlock (&NAME) != 0) \
 
-             abort ();                                                  \
 
-         }                                                              \
 
-       while (0)
 
- #   define gl_rwlock_wrlock(NAME) \
 
-       do                                                               \
 
-         {                                                              \
 
-           if (pthread_in_use () && pthread_rwlock_wrlock (&NAME) != 0) \
 
-             abort ();                                                  \
 
-         }                                                              \
 
-       while (0)
 
- #   define gl_rwlock_unlock(NAME) \
 
-       do                                                               \
 
-         {                                                              \
 
-           if (pthread_in_use () && pthread_rwlock_unlock (&NAME) != 0) \
 
-             abort ();                                                  \
 
-         }                                                              \
 
-       while (0)
 
- #   define gl_rwlock_destroy(NAME) \
 
-       do                                                                \
 
-         {                                                               \
 
-           if (pthread_in_use () && pthread_rwlock_destroy (&NAME) != 0) \
 
-             abort ();                                                   \
 
-         }                                                               \
 
-       while (0)
 
- #  else
 
- typedef struct
 
-         {
 
-           int initialized;
 
-           pthread_mutex_t guard;   /* protects the initialization */
 
-           pthread_rwlock_t rwlock; /* read-write lock */
 
-         }
 
-         gl_rwlock_t;
 
- #   define gl_rwlock_define(STORAGECLASS, NAME) \
 
-       STORAGECLASS gl_rwlock_t NAME;
 
- #   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
-       STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 
- #   define gl_rwlock_initializer \
 
-       { 0, PTHREAD_MUTEX_INITIALIZER }
 
- #   define gl_rwlock_init(NAME) \
 
-       do                                  \
 
-         {                                 \
 
-           if (pthread_in_use ())          \
 
-             glthread_rwlock_init (&NAME); \
 
-         }                                 \
 
-       while (0)
 
- #   define gl_rwlock_rdlock(NAME) \
 
-       do                                    \
 
-         {                                   \
 
-           if (pthread_in_use ())            \
 
-             glthread_rwlock_rdlock (&NAME); \
 
-         }                                   \
 
-       while (0)
 
- #   define gl_rwlock_wrlock(NAME) \
 
-       do                                    \
 
-         {                                   \
 
-           if (pthread_in_use ())            \
 
-             glthread_rwlock_wrlock (&NAME); \
 
-         }                                   \
 
-       while (0)
 
- #   define gl_rwlock_unlock(NAME) \
 
-       do                                    \
 
-         {                                   \
 
-           if (pthread_in_use ())            \
 
-             glthread_rwlock_unlock (&NAME); \
 
-         }                                   \
 
-       while (0)
 
- #   define gl_rwlock_destroy(NAME) \
 
-       do                                     \
 
-         {                                    \
 
-           if (pthread_in_use ())             \
 
-             glthread_rwlock_destroy (&NAME); \
 
-         }                                    \
 
-       while (0)
 
- extern void glthread_rwlock_init (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
 
- #  endif
 
- # else
 
- typedef struct
 
-         {
 
-           pthread_mutex_t lock; /* protects the remaining fields */
 
-           pthread_cond_t waiting_readers; /* waiting readers */
 
-           pthread_cond_t waiting_writers; /* waiting writers */
 
-           unsigned int waiting_writers_count; /* number of waiting writers */
 
-           int runcount; /* number of readers running, or -1 when a writer runs */
 
-         }
 
-         gl_rwlock_t;
 
- # define gl_rwlock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_rwlock_t NAME;
 
- # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 
- # define gl_rwlock_initializer \
 
-     { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
 
- # define gl_rwlock_init(NAME) \
 
-     do                                  \
 
-       {                                 \
 
-         if (pthread_in_use ())          \
 
-           glthread_rwlock_init (&NAME); \
 
-       }                                 \
 
-     while (0)
 
- # define gl_rwlock_rdlock(NAME) \
 
-     do                                    \
 
-       {                                   \
 
-         if (pthread_in_use ())            \
 
-           glthread_rwlock_rdlock (&NAME); \
 
-       }                                   \
 
-     while (0)
 
- # define gl_rwlock_wrlock(NAME) \
 
-     do                                    \
 
-       {                                   \
 
-         if (pthread_in_use ())            \
 
-           glthread_rwlock_wrlock (&NAME); \
 
-       }                                   \
 
-     while (0)
 
- # define gl_rwlock_unlock(NAME) \
 
-     do                                    \
 
-       {                                   \
 
-         if (pthread_in_use ())            \
 
-           glthread_rwlock_unlock (&NAME); \
 
-       }                                   \
 
-     while (0)
 
- # define gl_rwlock_destroy(NAME) \
 
-     do                                     \
 
-       {                                    \
 
-         if (pthread_in_use ())             \
 
-           glthread_rwlock_destroy (&NAME); \
 
-       }                                    \
 
-     while (0)
 
- extern void glthread_rwlock_init (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
 
- # endif
 
- /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
- # if HAVE_PTHREAD_MUTEX_RECURSIVE
 
- #  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
- typedef pthread_mutex_t gl_recursive_lock_t;
 
- #   define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
-       STORAGECLASS pthread_mutex_t NAME;
 
- #   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
-       STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
 
- #   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
 
- #    define gl_recursive_lock_initializer \
 
-        PTHREAD_RECURSIVE_MUTEX_INITIALIZER
 
- #   else
 
- #    define gl_recursive_lock_initializer \
 
-        PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
- #   endif
 
- #   define gl_recursive_lock_init(NAME) \
 
-       do                                                                  \
 
-         {                                                                 \
 
-           if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) \
 
-             abort ();                                                     \
 
-         }                                                                 \
 
-       while (0)
 
- #   define gl_recursive_lock_lock(NAME) \
 
-       do                                                            \
 
-         {                                                           \
 
-           if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) \
 
-             abort ();                                               \
 
-         }                                                           \
 
-       while (0)
 
- #   define gl_recursive_lock_unlock(NAME) \
 
-       do                                                              \
 
-         {                                                             \
 
-           if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) \
 
-             abort ();                                                 \
 
-         }                                                             \
 
-       while (0)
 
- #   define gl_recursive_lock_destroy(NAME) \
 
-       do                                                               \
 
-         {                                                              \
 
-           if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) \
 
-             abort ();                                                  \
 
-         }                                                              \
 
-       while (0)
 
- #  else
 
- typedef struct
 
-         {
 
-           pthread_mutex_t recmutex; /* recursive mutex */
 
-           pthread_mutex_t guard;    /* protects the initialization */
 
-           int initialized;
 
-         }
 
-         gl_recursive_lock_t;
 
- #   define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
-       STORAGECLASS gl_recursive_lock_t NAME;
 
- #   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
-       STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
- #   define gl_recursive_lock_initializer \
 
-       { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
 
- #   define gl_recursive_lock_init(NAME) \
 
-       do                                          \
 
-         {                                         \
 
-           if (pthread_in_use ())                  \
 
-             glthread_recursive_lock_init (&NAME); \
 
-         }                                         \
 
-       while (0)
 
- #   define gl_recursive_lock_lock(NAME) \
 
-       do                                          \
 
-         {                                         \
 
-           if (pthread_in_use ())                  \
 
-             glthread_recursive_lock_lock (&NAME); \
 
-         }                                         \
 
-       while (0)
 
- #   define gl_recursive_lock_unlock(NAME) \
 
-       do                                            \
 
-         {                                           \
 
-           if (pthread_in_use ())                    \
 
-             glthread_recursive_lock_unlock (&NAME); \
 
-         }                                           \
 
-       while (0)
 
- #   define gl_recursive_lock_destroy(NAME) \
 
-       do                                             \
 
-         {                                            \
 
-           if (pthread_in_use ())                     \
 
-             glthread_recursive_lock_destroy (&NAME); \
 
-         }                                            \
 
-       while (0)
 
- extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
- #  endif
 
- # else
 
- /* Old versions of POSIX threads on Solaris did not have recursive locks.
 
-    We have to implement them ourselves.  */
 
- typedef struct
 
-         {
 
-           pthread_mutex_t mutex;
 
-           pthread_t owner;
 
-           unsigned long depth;
 
-         }
 
-         gl_recursive_lock_t;
 
- #  define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
-      STORAGECLASS gl_recursive_lock_t NAME;
 
- #  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
-      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
- #  define gl_recursive_lock_initializer \
 
-      { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
 
- #  define gl_recursive_lock_init(NAME) \
 
-      do                                          \
 
-        {                                         \
 
-          if (pthread_in_use ())                  \
 
-            glthread_recursive_lock_init (&NAME); \
 
-        }                                         \
 
-      while (0)
 
- #  define gl_recursive_lock_lock(NAME) \
 
-      do                                          \
 
-        {                                         \
 
-          if (pthread_in_use ())                  \
 
-            glthread_recursive_lock_lock (&NAME); \
 
-        }                                         \
 
-      while (0)
 
- #  define gl_recursive_lock_unlock(NAME) \
 
-      do                                            \
 
-        {                                           \
 
-          if (pthread_in_use ())                    \
 
-            glthread_recursive_lock_unlock (&NAME); \
 
-        }                                           \
 
-      while (0)
 
- #  define gl_recursive_lock_destroy(NAME) \
 
-      do                                             \
 
-        {                                            \
 
-          if (pthread_in_use ())                     \
 
-            glthread_recursive_lock_destroy (&NAME); \
 
-        }                                            \
 
-      while (0)
 
- extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
- # endif
 
- /* -------------------------- gl_once_t datatype -------------------------- */
 
- typedef pthread_once_t gl_once_t;
 
- # define gl_once_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
 
- # define gl_once(NAME, INITFUNCTION) \
 
-     do                                                   \
 
-       {                                                  \
 
-         if (pthread_in_use ())                           \
 
-           {                                              \
 
-             if (pthread_once (&NAME, INITFUNCTION) != 0) \
 
-               abort ();                                  \
 
-           }                                              \
 
-         else                                             \
 
-           {                                              \
 
-             if (glthread_once_singlethreaded (&NAME))    \
 
-               INITFUNCTION ();                           \
 
-           }                                              \
 
-       }                                                  \
 
-     while (0)
 
- extern int glthread_once_singlethreaded (pthread_once_t *once_control);
 
- # ifdef __cplusplus
 
- }
 
- # endif
 
- #endif
 
- /* ========================================================================= */
 
- #if USE_PTH_THREADS
 
- /* Use the GNU Pth threads library.  */
 
- # include <pth.h>
 
- # include <stdlib.h>
 
- # ifdef __cplusplus
 
- extern "C" {
 
- # endif
 
- # if USE_PTH_THREADS_WEAK
 
- /* Use weak references to the GNU Pth threads library.  */
 
- #  pragma weak pth_mutex_init
 
- #  pragma weak pth_mutex_acquire
 
- #  pragma weak pth_mutex_release
 
- #  pragma weak pth_rwlock_init
 
- #  pragma weak pth_rwlock_acquire
 
- #  pragma weak pth_rwlock_release
 
- #  pragma weak pth_once
 
- #  pragma weak pth_cancel
 
- #  define pth_in_use() (pth_cancel != NULL)
 
- # else
 
- #  define pth_in_use() 1
 
- # endif
 
- /* -------------------------- gl_lock_t datatype -------------------------- */
 
- typedef pth_mutex_t gl_lock_t;
 
- # define gl_lock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS pth_mutex_t NAME;
 
- # define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
 
- # define gl_lock_initializer \
 
-     PTH_MUTEX_INIT
 
- # define gl_lock_init(NAME) \
 
-     do                                               \
 
-       {                                              \
 
-         if (pth_in_use() && !pth_mutex_init (&NAME)) \
 
-           abort ();                                  \
 
-       }                                              \
 
-     while (0)
 
- # define gl_lock_lock(NAME) \
 
-     do                                                           \
 
-       {                                                          \
 
-         if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) \
 
-           abort ();                                              \
 
-       }                                                          \
 
-     while (0)
 
- # define gl_lock_unlock(NAME) \
 
-     do                                                  \
 
-       {                                                 \
 
-         if (pth_in_use() && !pth_mutex_release (&NAME)) \
 
-           abort ();                                     \
 
-       }                                                 \
 
-     while (0)
 
- # define gl_lock_destroy(NAME) \
 
-     (void)(&NAME)
 
- /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
- typedef pth_rwlock_t gl_rwlock_t;
 
- #  define gl_rwlock_define(STORAGECLASS, NAME) \
 
-      STORAGECLASS pth_rwlock_t NAME;
 
- #  define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
-      STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
 
- #  define gl_rwlock_initializer \
 
-      PTH_RWLOCK_INIT
 
- #  define gl_rwlock_init(NAME) \
 
-      do                                                \
 
-        {                                               \
 
-          if (pth_in_use() && !pth_rwlock_init (&NAME)) \
 
-            abort ();                                   \
 
-        }                                               \
 
-      while (0)
 
- #  define gl_rwlock_rdlock(NAME) \
 
-      do                                                              \
 
-        {                                                             \
 
-          if (pth_in_use()                                            \
 
-              && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) \
 
-            abort ();                                                 \
 
-        }                                                             \
 
-      while (0)
 
- #  define gl_rwlock_wrlock(NAME) \
 
-      do                                                              \
 
-        {                                                             \
 
-          if (pth_in_use()                                            \
 
-              && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) \
 
-            abort ();                                                 \
 
-        }                                                             \
 
-      while (0)
 
- #  define gl_rwlock_unlock(NAME) \
 
-      do                                                   \
 
-        {                                                  \
 
-          if (pth_in_use() && !pth_rwlock_release (&NAME)) \
 
-            abort ();                                      \
 
-        }                                                  \
 
-      while (0)
 
- #  define gl_rwlock_destroy(NAME) \
 
-      (void)(&NAME)
 
- /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
- /* In Pth, mutexes are recursive by default.  */
 
- typedef pth_mutex_t gl_recursive_lock_t;
 
- #  define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
-      STORAGECLASS pth_mutex_t NAME;
 
- #  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
-      STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
 
- #  define gl_recursive_lock_initializer \
 
-      PTH_MUTEX_INIT
 
- #  define gl_recursive_lock_init(NAME) \
 
-      do                                               \
 
-        {                                              \
 
-          if (pth_in_use() && !pth_mutex_init (&NAME)) \
 
-            abort ();                                  \
 
-        }                                              \
 
-      while (0)
 
- #  define gl_recursive_lock_lock(NAME) \
 
-      do                                                           \
 
-        {                                                          \
 
-          if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) \
 
-            abort ();                                              \
 
-        }                                                          \
 
-      while (0)
 
- #  define gl_recursive_lock_unlock(NAME) \
 
-      do                                                  \
 
-        {                                                 \
 
-          if (pth_in_use() && !pth_mutex_release (&NAME)) \
 
-            abort ();                                     \
 
-        }                                                 \
 
-      while (0)
 
- #  define gl_recursive_lock_destroy(NAME) \
 
-      (void)(&NAME)
 
- /* -------------------------- gl_once_t datatype -------------------------- */
 
- typedef pth_once_t gl_once_t;
 
- # define gl_once_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
 
- # define gl_once(NAME, INITFUNCTION) \
 
-     do                                                                \
 
-       {                                                               \
 
-         if (pth_in_use ())                                            \
 
-           {                                                           \
 
-             void (*gl_once_temp) (void) = INITFUNCTION;               \
 
-             if (!pth_once (&NAME, glthread_once_call, &gl_once_temp)) \
 
-               abort ();                                               \
 
-           }                                                           \
 
-         else                                                          \
 
-           {                                                           \
 
-             if (glthread_once_singlethreaded (&NAME))                 \
 
-               INITFUNCTION ();                                        \
 
-           }                                                           \
 
-       }                                                               \
 
-     while (0)
 
- extern void glthread_once_call (void *arg);
 
- extern int glthread_once_singlethreaded (pth_once_t *once_control);
 
- # ifdef __cplusplus
 
- }
 
- # endif
 
- #endif
 
- /* ========================================================================= */
 
- #if USE_SOLARIS_THREADS
 
- /* Use the old Solaris threads library.  */
 
- # include <thread.h>
 
- # include <synch.h>
 
- # include <stdlib.h>
 
- # ifdef __cplusplus
 
- extern "C" {
 
- # endif
 
- # if USE_SOLARIS_THREADS_WEAK
 
- /* Use weak references to the old Solaris threads library.  */
 
- #  pragma weak mutex_init
 
- #  pragma weak mutex_lock
 
- #  pragma weak mutex_unlock
 
- #  pragma weak mutex_destroy
 
- #  pragma weak rwlock_init
 
- #  pragma weak rw_rdlock
 
- #  pragma weak rw_wrlock
 
- #  pragma weak rw_unlock
 
- #  pragma weak rwlock_destroy
 
- #  pragma weak thr_self
 
- #  pragma weak thr_suspend
 
- #  define thread_in_use() (thr_suspend != NULL)
 
- # else
 
- #  define thread_in_use() 1
 
- # endif
 
- /* -------------------------- gl_lock_t datatype -------------------------- */
 
- typedef mutex_t gl_lock_t;
 
- # define gl_lock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS mutex_t NAME;
 
- # define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS mutex_t NAME = gl_lock_initializer;
 
- # define gl_lock_initializer \
 
-     DEFAULTMUTEX
 
- # define gl_lock_init(NAME) \
 
-     do                                                                       \
 
-       {                                                                      \
 
-         if (thread_in_use () && mutex_init (&NAME, USYNC_THREAD, NULL) != 0) \
 
-           abort ();                                                          \
 
-       }                                                                      \
 
-     while (0)
 
- # define gl_lock_lock(NAME) \
 
-     do                                                   \
 
-       {                                                  \
 
-         if (thread_in_use () && mutex_lock (&NAME) != 0) \
 
-           abort ();                                      \
 
-       }                                                  \
 
-     while (0)
 
- # define gl_lock_unlock(NAME) \
 
-     do                                                     \
 
-       {                                                    \
 
-         if (thread_in_use () && mutex_unlock (&NAME) != 0) \
 
-           abort ();                                        \
 
-       }                                                    \
 
-     while (0)
 
- # define gl_lock_destroy(NAME) \
 
-     do                                                      \
 
-       {                                                     \
 
-         if (thread_in_use () && mutex_destroy (&NAME) != 0) \
 
-           abort ();                                         \
 
-       }                                                     \
 
-     while (0)
 
- /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
- typedef rwlock_t gl_rwlock_t;
 
- # define gl_rwlock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS rwlock_t NAME;
 
- # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
 
- # define gl_rwlock_initializer \
 
-     DEFAULTRWLOCK
 
- # define gl_rwlock_init(NAME) \
 
-     do                                                                        \
 
-       {                                                                       \
 
-         if (thread_in_use () && rwlock_init (&NAME, USYNC_THREAD, NULL) != 0) \
 
-           abort ();                                                           \
 
-       }                                                                       \
 
-     while (0)
 
- # define gl_rwlock_rdlock(NAME) \
 
-     do                                                  \
 
-       {                                                 \
 
-         if (thread_in_use () && rw_rdlock (&NAME) != 0) \
 
-           abort ();                                     \
 
-       }                                                 \
 
-     while (0)
 
- # define gl_rwlock_wrlock(NAME) \
 
-     do                                                  \
 
-       {                                                 \
 
-         if (thread_in_use () && rw_wrlock (&NAME) != 0) \
 
-           abort ();                                     \
 
-       }                                                 \
 
-     while (0)
 
- # define gl_rwlock_unlock(NAME) \
 
-     do                                                  \
 
-       {                                                 \
 
-         if (thread_in_use () && rw_unlock (&NAME) != 0) \
 
-           abort ();                                     \
 
-       }                                                 \
 
-     while (0)
 
- # define gl_rwlock_destroy(NAME) \
 
-     do                                                       \
 
-       {                                                      \
 
-         if (thread_in_use () && rwlock_destroy (&NAME) != 0) \
 
-           abort ();                                          \
 
-       }                                                      \
 
-     while (0)
 
- /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
- /* Old Solaris threads did not have recursive locks.
 
-    We have to implement them ourselves.  */
 
- typedef struct
 
-         {
 
-           mutex_t mutex;
 
-           thread_t owner;
 
-           unsigned long depth;
 
-         }
 
-         gl_recursive_lock_t;
 
- # define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_recursive_lock_t NAME;
 
- # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
- # define gl_recursive_lock_initializer \
 
-     { DEFAULTMUTEX, (thread_t) 0, 0 }
 
- # define gl_recursive_lock_init(NAME) \
 
-     do                                          \
 
-       {                                         \
 
-         if (thread_in_use ())                   \
 
-           glthread_recursive_lock_init (&NAME); \
 
-       }                                         \
 
-     while (0)
 
- # define gl_recursive_lock_lock(NAME) \
 
-     do                                          \
 
-       {                                         \
 
-         if (thread_in_use ())                   \
 
-           glthread_recursive_lock_lock (&NAME); \
 
-       }                                         \
 
-     while (0)
 
- # define gl_recursive_lock_unlock(NAME) \
 
-     do                                            \
 
-       {                                           \
 
-         if (thread_in_use ())                     \
 
-           glthread_recursive_lock_unlock (&NAME); \
 
-       }                                           \
 
-     while (0)
 
- # define gl_recursive_lock_destroy(NAME) \
 
-     do                                             \
 
-       {                                            \
 
-         if (thread_in_use ())                      \
 
-           glthread_recursive_lock_destroy (&NAME); \
 
-       }                                            \
 
-     while (0)
 
- extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
- /* -------------------------- gl_once_t datatype -------------------------- */
 
- typedef struct
 
-         {
 
-           volatile int inited;
 
-           mutex_t mutex;
 
-         }
 
-         gl_once_t;
 
- # define gl_once_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
 
- # define gl_once(NAME, INITFUNCTION) \
 
-     do                                                \
 
-       {                                               \
 
-         if (thread_in_use ())                         \
 
-           {                                           \
 
-             glthread_once (&NAME, INITFUNCTION);      \
 
-           }                                           \
 
-         else                                          \
 
-           {                                           \
 
-             if (glthread_once_singlethreaded (&NAME)) \
 
-               INITFUNCTION ();                        \
 
-           }                                           \
 
-       }                                               \
 
-     while (0)
 
- extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
 
- extern int glthread_once_singlethreaded (gl_once_t *once_control);
 
- # ifdef __cplusplus
 
- }
 
- # endif
 
- #endif
 
- /* ========================================================================= */
 
- #if USE_WIN32_THREADS
 
- # include <windows.h>
 
- # ifdef __cplusplus
 
- extern "C" {
 
- # endif
 
- /* We can use CRITICAL_SECTION directly, rather than the Win32 Event, Mutex,
 
-    Semaphore types, because
 
-      - we need only to synchronize inside a single process (address space),
 
-        not inter-process locking,
 
-      - we don't need to support trylock operations.  (TryEnterCriticalSection
 
-        does not work on Windows 95/98/ME.  Packages that need trylock usually
 
-        define their own mutex type.)  */
 
- /* There is no way to statically initialize a CRITICAL_SECTION.  It needs
 
-    to be done lazily, once only.  For this we need spinlocks.  */
 
- typedef struct { volatile int done; volatile long started; } gl_spinlock_t;
 
- /* -------------------------- gl_lock_t datatype -------------------------- */
 
- typedef struct
 
-         {
 
-           gl_spinlock_t guard; /* protects the initialization */
 
-           CRITICAL_SECTION lock;
 
-         }
 
-         gl_lock_t;
 
- # define gl_lock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_lock_t NAME;
 
- # define gl_lock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
 
- # define gl_lock_initializer \
 
-     { { 0, -1 } }
 
- # define gl_lock_init(NAME) \
 
-     glthread_lock_init (&NAME)
 
- # define gl_lock_lock(NAME) \
 
-     glthread_lock_lock (&NAME)
 
- # define gl_lock_unlock(NAME) \
 
-     glthread_lock_unlock (&NAME)
 
- # define gl_lock_destroy(NAME) \
 
-     glthread_lock_destroy (&NAME)
 
- extern void glthread_lock_init (gl_lock_t *lock);
 
- extern void glthread_lock_lock (gl_lock_t *lock);
 
- extern void glthread_lock_unlock (gl_lock_t *lock);
 
- extern void glthread_lock_destroy (gl_lock_t *lock);
 
- /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
- /* It is impossible to implement read-write locks using plain locks, without
 
-    introducing an extra thread dedicated to managing read-write locks.
 
-    Therefore here we need to use the low-level Event type.  */
 
- typedef struct
 
-         {
 
-           HANDLE *array; /* array of waiting threads, each represented by an event */
 
-           unsigned int count; /* number of waiting threads */
 
-           unsigned int alloc; /* length of allocated array */
 
-           unsigned int offset; /* index of first waiting thread in array */
 
-         }
 
-         gl_waitqueue_t;
 
- typedef struct
 
-         {
 
-           gl_spinlock_t guard; /* protects the initialization */
 
-           CRITICAL_SECTION lock; /* protects the remaining fields */
 
-           gl_waitqueue_t waiting_readers; /* waiting readers */
 
-           gl_waitqueue_t waiting_writers; /* waiting writers */
 
-           int runcount; /* number of readers running, or -1 when a writer runs */
 
-         }
 
-         gl_rwlock_t;
 
- # define gl_rwlock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_rwlock_t NAME;
 
- # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 
- # define gl_rwlock_initializer \
 
-     { { 0, -1 } }
 
- # define gl_rwlock_init(NAME) \
 
-     glthread_rwlock_init (&NAME)
 
- # define gl_rwlock_rdlock(NAME) \
 
-     glthread_rwlock_rdlock (&NAME)
 
- # define gl_rwlock_wrlock(NAME) \
 
-     glthread_rwlock_wrlock (&NAME)
 
- # define gl_rwlock_unlock(NAME) \
 
-     glthread_rwlock_unlock (&NAME)
 
- # define gl_rwlock_destroy(NAME) \
 
-     glthread_rwlock_destroy (&NAME)
 
- extern void glthread_rwlock_init (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
 
- extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
 
- /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
- /* The Win32 documentation says that CRITICAL_SECTION already implements a
 
-    recursive lock.  But we need not rely on it: It's easy to implement a
 
-    recursive lock without this assumption.  */
 
- typedef struct
 
-         {
 
-           gl_spinlock_t guard; /* protects the initialization */
 
-           DWORD owner;
 
-           unsigned long depth;
 
-           CRITICAL_SECTION lock;
 
-         }
 
-         gl_recursive_lock_t;
 
- # define gl_recursive_lock_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_recursive_lock_t NAME;
 
- # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 
- # define gl_recursive_lock_initializer \
 
-     { { 0, -1 }, 0, 0 }
 
- # define gl_recursive_lock_init(NAME) \
 
-     glthread_recursive_lock_init (&NAME)
 
- # define gl_recursive_lock_lock(NAME) \
 
-     glthread_recursive_lock_lock (&NAME)
 
- # define gl_recursive_lock_unlock(NAME) \
 
-     glthread_recursive_lock_unlock (&NAME)
 
- # define gl_recursive_lock_destroy(NAME) \
 
-     glthread_recursive_lock_destroy (&NAME)
 
- extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
 
- extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
- /* -------------------------- gl_once_t datatype -------------------------- */
 
- typedef struct
 
-         {
 
-           volatile int inited;
 
-           volatile long started;
 
-           CRITICAL_SECTION lock;
 
-         }
 
-         gl_once_t;
 
- # define gl_once_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_once_t NAME = { -1, -1 };
 
- # define gl_once(NAME, INITFUNCTION) \
 
-     glthread_once (&NAME, INITFUNCTION)
 
- extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
 
- # ifdef __cplusplus
 
- }
 
- # endif
 
- #endif
 
- /* ========================================================================= */
 
- #if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS)
 
- /* Provide dummy implementation if threads are not supported.  */
 
- /* -------------------------- gl_lock_t datatype -------------------------- */
 
- typedef int gl_lock_t;
 
- # define gl_lock_define(STORAGECLASS, NAME)
 
- # define gl_lock_define_initialized(STORAGECLASS, NAME)
 
- # define gl_lock_init(NAME)
 
- # define gl_lock_lock(NAME)
 
- # define gl_lock_unlock(NAME)
 
- /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
- typedef int gl_rwlock_t;
 
- # define gl_rwlock_define(STORAGECLASS, NAME)
 
- # define gl_rwlock_define_initialized(STORAGECLASS, NAME)
 
- # define gl_rwlock_init(NAME)
 
- # define gl_rwlock_rdlock(NAME)
 
- # define gl_rwlock_wrlock(NAME)
 
- # define gl_rwlock_unlock(NAME)
 
- /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
- typedef int gl_recursive_lock_t;
 
- # define gl_recursive_lock_define(STORAGECLASS, NAME)
 
- # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
 
- # define gl_recursive_lock_init(NAME)
 
- # define gl_recursive_lock_lock(NAME)
 
- # define gl_recursive_lock_unlock(NAME)
 
- /* -------------------------- gl_once_t datatype -------------------------- */
 
- typedef int gl_once_t;
 
- # define gl_once_define(STORAGECLASS, NAME) \
 
-     STORAGECLASS gl_once_t NAME = 0;
 
- # define gl_once(NAME, INITFUNCTION) \
 
-     do                       \
 
-       {                      \
 
-         if (NAME == 0)       \
 
-           {                  \
 
-             NAME = ~ 0;      \
 
-             INITFUNCTION (); \
 
-           }                  \
 
-       }                      \
 
-     while (0)
 
- #endif
 
- /* ========================================================================= */
 
- #endif /* _LOCK_H */
 
 
  |