"Fossies" - the Fresh Open Source Software Archive

Member "nano-4.5/lib/glthread/lock.h" (4 Oct 2019, 26673 Bytes) of package /linux/misc/nano-4.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lock.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 4.3_vs_4.4.

    1 /* Locking in multithreaded situations.
    2    Copyright (C) 2005-2019 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 3, 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, see <https://www.gnu.org/licenses/>.  */
   16 
   17 /* Written by Bruno Haible <bruno@clisp.org>, 2005.
   18    Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h.  */
   19 
   20 /* This file contains locking primitives for use with a given thread library.
   21    It does not contain primitives for creating threads or for other
   22    synchronization primitives.
   23 
   24    Normal (non-recursive) locks:
   25      Type:                gl_lock_t
   26      Declaration:         gl_lock_define(extern, name)
   27      Initializer:         gl_lock_define_initialized(, name)
   28      Initialization:      gl_lock_init (name);
   29      Taking the lock:     gl_lock_lock (name);
   30      Releasing the lock:  gl_lock_unlock (name);
   31      De-initialization:   gl_lock_destroy (name);
   32    Equivalent functions with control of error handling:
   33      Initialization:      err = glthread_lock_init (&name);
   34      Taking the lock:     err = glthread_lock_lock (&name);
   35      Releasing the lock:  err = glthread_lock_unlock (&name);
   36      De-initialization:   err = glthread_lock_destroy (&name);
   37 
   38    Read-Write (non-recursive) locks:
   39      Type:                gl_rwlock_t
   40      Declaration:         gl_rwlock_define(extern, name)
   41      Initializer:         gl_rwlock_define_initialized(, name)
   42      Initialization:      gl_rwlock_init (name);
   43      Taking the lock:     gl_rwlock_rdlock (name);
   44                           gl_rwlock_wrlock (name);
   45      Releasing the lock:  gl_rwlock_unlock (name);
   46      De-initialization:   gl_rwlock_destroy (name);
   47    Equivalent functions with control of error handling:
   48      Initialization:      err = glthread_rwlock_init (&name);
   49      Taking the lock:     err = glthread_rwlock_rdlock (&name);
   50                           err = glthread_rwlock_wrlock (&name);
   51      Releasing the lock:  err = glthread_rwlock_unlock (&name);
   52      De-initialization:   err = glthread_rwlock_destroy (&name);
   53 
   54    Recursive locks:
   55      Type:                gl_recursive_lock_t
   56      Declaration:         gl_recursive_lock_define(extern, name)
   57      Initializer:         gl_recursive_lock_define_initialized(, name)
   58      Initialization:      gl_recursive_lock_init (name);
   59      Taking the lock:     gl_recursive_lock_lock (name);
   60      Releasing the lock:  gl_recursive_lock_unlock (name);
   61      De-initialization:   gl_recursive_lock_destroy (name);
   62    Equivalent functions with control of error handling:
   63      Initialization:      err = glthread_recursive_lock_init (&name);
   64      Taking the lock:     err = glthread_recursive_lock_lock (&name);
   65      Releasing the lock:  err = glthread_recursive_lock_unlock (&name);
   66      De-initialization:   err = glthread_recursive_lock_destroy (&name);
   67 
   68   Once-only execution:
   69      Type:                gl_once_t
   70      Initializer:         gl_once_define(extern, name)
   71      Execution:           gl_once (name, initfunction);
   72    Equivalent functions with control of error handling:
   73      Execution:           err = glthread_once (&name, initfunction);
   74 */
   75 
   76 
   77 #ifndef _LOCK_H
   78 #define _LOCK_H
   79 
   80 #include <errno.h>
   81 #include <stdlib.h>
   82 
   83 #if !defined c11_threads_in_use
   84 # if HAVE_THREADS_H && USE_POSIX_THREADS_WEAK
   85 #  include <threads.h>
   86 #  pragma weak thrd_exit
   87 #  define c11_threads_in_use() (thrd_exit != NULL)
   88 # else
   89 #  define c11_threads_in_use() 0
   90 # endif
   91 #endif
   92 
   93 /* ========================================================================= */
   94 
   95 #if USE_POSIX_THREADS
   96 
   97 /* Use the POSIX threads library.  */
   98 
   99 # include <pthread.h>
  100 
  101 # ifdef __cplusplus
  102 extern "C" {
  103 # endif
  104 
  105 # if PTHREAD_IN_USE_DETECTION_HARD
  106 
  107 /* The pthread_in_use() detection needs to be done at runtime.  */
  108 #  define pthread_in_use() \
  109      glthread_in_use ()
  110 extern int glthread_in_use (void);
  111 
  112 # endif
  113 
  114 # if USE_POSIX_THREADS_WEAK
  115 
  116 /* Use weak references to the POSIX threads library.  */
  117 
  118 /* Weak references avoid dragging in external libraries if the other parts
  119    of the program don't use them.  Here we use them, because we don't want
  120    every program that uses libintl to depend on libpthread.  This assumes
  121    that libpthread would not be loaded after libintl; i.e. if libintl is
  122    loaded first, by an executable that does not depend on libpthread, and
  123    then a module is dynamically loaded that depends on libpthread, libintl
  124    will not be multithread-safe.  */
  125 
  126 /* The way to test at runtime whether libpthread is present is to test
  127    whether a function pointer's value, such as &pthread_mutex_init, is
  128    non-NULL.  However, some versions of GCC have a bug through which, in
  129    PIC mode, &foo != NULL always evaluates to true if there is a direct
  130    call to foo(...) in the same function.  To avoid this, we test the
  131    address of a function in libpthread that we don't use.  */
  132 
  133 #  pragma weak pthread_mutex_init
  134 #  pragma weak pthread_mutex_lock
  135 #  pragma weak pthread_mutex_unlock
  136 #  pragma weak pthread_mutex_destroy
  137 #  pragma weak pthread_rwlock_init
  138 #  pragma weak pthread_rwlock_rdlock
  139 #  pragma weak pthread_rwlock_wrlock
  140 #  pragma weak pthread_rwlock_unlock
  141 #  pragma weak pthread_rwlock_destroy
  142 #  pragma weak pthread_once
  143 #  pragma weak pthread_cond_init
  144 #  pragma weak pthread_cond_wait
  145 #  pragma weak pthread_cond_signal
  146 #  pragma weak pthread_cond_broadcast
  147 #  pragma weak pthread_cond_destroy
  148 #  pragma weak pthread_mutexattr_init
  149 #  pragma weak pthread_mutexattr_settype
  150 #  pragma weak pthread_mutexattr_destroy
  151 #  pragma weak pthread_rwlockattr_init
  152 #  if __GNU_LIBRARY__ > 1
  153 #   pragma weak pthread_rwlockattr_setkind_np
  154 #  endif
  155 #  pragma weak pthread_rwlockattr_destroy
  156 #  ifndef pthread_self
  157 #   pragma weak pthread_self
  158 #  endif
  159 
  160 #  if !PTHREAD_IN_USE_DETECTION_HARD
  161     /* Considering all platforms with USE_POSIX_THREADS_WEAK, only few symbols
  162        can be used to determine whether libpthread is in use.  These are:
  163          pthread_mutexattr_gettype
  164          pthread_rwlockattr_destroy
  165          pthread_rwlockattr_init
  166      */
  167 #   pragma weak pthread_mutexattr_gettype
  168 #   define pthread_in_use() \
  169       (pthread_mutexattr_gettype != NULL || c11_threads_in_use ())
  170 #  endif
  171 
  172 # else
  173 
  174 #  if !PTHREAD_IN_USE_DETECTION_HARD
  175 #   define pthread_in_use() 1
  176 #  endif
  177 
  178 # endif
  179 
  180 /* -------------------------- gl_lock_t datatype -------------------------- */
  181 
  182 typedef pthread_mutex_t gl_lock_t;
  183 # define gl_lock_define(STORAGECLASS, NAME) \
  184     STORAGECLASS pthread_mutex_t NAME;
  185 # define gl_lock_define_initialized(STORAGECLASS, NAME) \
  186     STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
  187 # define gl_lock_initializer \
  188     PTHREAD_MUTEX_INITIALIZER
  189 # define glthread_lock_init(LOCK) \
  190     (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
  191 # define glthread_lock_lock(LOCK) \
  192     (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
  193 # define glthread_lock_unlock(LOCK) \
  194     (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
  195 # define glthread_lock_destroy(LOCK) \
  196     (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
  197 
  198 /* ------------------------- gl_rwlock_t datatype ------------------------- */
  199 
  200 # if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1)))
  201 
  202 #  ifdef PTHREAD_RWLOCK_INITIALIZER
  203 
  204 typedef pthread_rwlock_t gl_rwlock_t;
  205 #   define gl_rwlock_define(STORAGECLASS, NAME) \
  206       STORAGECLASS pthread_rwlock_t NAME;
  207 #   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
  208       STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
  209 #   if HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER
  210 #    define gl_rwlock_initializer \
  211        PTHREAD_RWLOCK_INITIALIZER
  212 #    define glthread_rwlock_init(LOCK) \
  213        (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
  214 #   else /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */
  215 #    define gl_rwlock_initializer \
  216        PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
  217 #    define glthread_rwlock_init(LOCK) \
  218        (pthread_in_use () ? glthread_rwlock_init_for_glibc (LOCK) : 0)
  219 extern int glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock);
  220 #   endif
  221 #   define glthread_rwlock_rdlock(LOCK) \
  222       (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
  223 #   define glthread_rwlock_wrlock(LOCK) \
  224       (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
  225 #   define glthread_rwlock_unlock(LOCK) \
  226       (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
  227 #   define glthread_rwlock_destroy(LOCK) \
  228       (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)
  229 
  230 #  else
  231 
  232 typedef struct
  233         {
  234           int initialized;
  235           pthread_mutex_t guard;   /* protects the initialization */
  236           pthread_rwlock_t rwlock; /* read-write lock */
  237         }
  238         gl_rwlock_t;
  239 #   define gl_rwlock_define(STORAGECLASS, NAME) \
  240       STORAGECLASS gl_rwlock_t NAME;
  241 #   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
  242       STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
  243 #   define gl_rwlock_initializer \
  244       { 0, PTHREAD_MUTEX_INITIALIZER }
  245 #   define glthread_rwlock_init(LOCK) \
  246       (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
  247 #   define glthread_rwlock_rdlock(LOCK) \
  248       (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
  249 #   define glthread_rwlock_wrlock(LOCK) \
  250       (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
  251 #   define glthread_rwlock_unlock(LOCK) \
  252       (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
  253 #   define glthread_rwlock_destroy(LOCK) \
  254       (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
  255 extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
  256 extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
  257 extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
  258 extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
  259 extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
  260 
  261 #  endif
  262 
  263 # else
  264 
  265 typedef struct
  266         {
  267           pthread_mutex_t lock; /* protects the remaining fields */
  268           pthread_cond_t waiting_readers; /* waiting readers */
  269           pthread_cond_t waiting_writers; /* waiting writers */
  270           unsigned int waiting_writers_count; /* number of waiting writers */
  271           int runcount; /* number of readers running, or -1 when a writer runs */
  272         }
  273         gl_rwlock_t;
  274 # define gl_rwlock_define(STORAGECLASS, NAME) \
  275     STORAGECLASS gl_rwlock_t NAME;
  276 # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
  277     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
  278 # define gl_rwlock_initializer \
  279     { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
  280 # define glthread_rwlock_init(LOCK) \
  281     (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
  282 # define glthread_rwlock_rdlock(LOCK) \
  283     (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
  284 # define glthread_rwlock_wrlock(LOCK) \
  285     (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
  286 # define glthread_rwlock_unlock(LOCK) \
  287     (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
  288 # define glthread_rwlock_destroy(LOCK) \
  289     (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
  290 extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
  291 extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
  292 extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
  293 extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
  294 extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
  295 
  296 # endif
  297 
  298 /* --------------------- gl_recursive_lock_t datatype --------------------- */
  299 
  300 # if HAVE_PTHREAD_MUTEX_RECURSIVE
  301 
  302 #  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
  303 
  304 typedef pthread_mutex_t gl_recursive_lock_t;
  305 #   define gl_recursive_lock_define(STORAGECLASS, NAME) \
  306       STORAGECLASS pthread_mutex_t NAME;
  307 #   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
  308       STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
  309 #   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
  310 #    define gl_recursive_lock_initializer \
  311        PTHREAD_RECURSIVE_MUTEX_INITIALIZER
  312 #   else
  313 #    define gl_recursive_lock_initializer \
  314        PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
  315 #   endif
  316 #   define glthread_recursive_lock_init(LOCK) \
  317       (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
  318 #   define glthread_recursive_lock_lock(LOCK) \
  319       (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
  320 #   define glthread_recursive_lock_unlock(LOCK) \
  321       (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
  322 #   define glthread_recursive_lock_destroy(LOCK) \
  323       (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
  324 extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
  325 
  326 #  else
  327 
  328 typedef struct
  329         {
  330           pthread_mutex_t recmutex; /* recursive mutex */
  331           pthread_mutex_t guard;    /* protects the initialization */
  332           int initialized;
  333         }
  334         gl_recursive_lock_t;
  335 #   define gl_recursive_lock_define(STORAGECLASS, NAME) \
  336       STORAGECLASS gl_recursive_lock_t NAME;
  337 #   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
  338       STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
  339 #   define gl_recursive_lock_initializer \
  340       { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
  341 #   define glthread_recursive_lock_init(LOCK) \
  342       (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
  343 #   define glthread_recursive_lock_lock(LOCK) \
  344       (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
  345 #   define glthread_recursive_lock_unlock(LOCK) \
  346       (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
  347 #   define glthread_recursive_lock_destroy(LOCK) \
  348       (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
  349 extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
  350 extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
  351 extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
  352 extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
  353 
  354 #  endif
  355 
  356 # else
  357 
  358 /* Old versions of POSIX threads on Solaris did not have recursive locks.
  359    We have to implement them ourselves.  */
  360 
  361 typedef struct
  362         {
  363           pthread_mutex_t mutex;
  364           pthread_t owner;
  365           unsigned long depth;
  366         }
  367         gl_recursive_lock_t;
  368 #  define gl_recursive_lock_define(STORAGECLASS, NAME) \
  369      STORAGECLASS gl_recursive_lock_t NAME;
  370 #  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
  371      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
  372 #  define gl_recursive_lock_initializer \
  373      { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
  374 #  define glthread_recursive_lock_init(LOCK) \
  375      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
  376 #  define glthread_recursive_lock_lock(LOCK) \
  377      (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
  378 #  define glthread_recursive_lock_unlock(LOCK) \
  379      (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
  380 #  define glthread_recursive_lock_destroy(LOCK) \
  381      (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
  382 extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
  383 extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
  384 extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
  385 extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
  386 
  387 # endif
  388 
  389 /* -------------------------- gl_once_t datatype -------------------------- */
  390 
  391 typedef pthread_once_t gl_once_t;
  392 # define gl_once_define(STORAGECLASS, NAME) \
  393     STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
  394 # define glthread_once(ONCE_CONTROL, INITFUNCTION) \
  395     (pthread_in_use ()                                                         \
  396      ? pthread_once (ONCE_CONTROL, INITFUNCTION)                               \
  397      : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
  398 extern int glthread_once_singlethreaded (pthread_once_t *once_control);
  399 
  400 # ifdef __cplusplus
  401 }
  402 # endif
  403 
  404 #endif
  405 
  406 /* ========================================================================= */
  407 
  408 #if USE_WINDOWS_THREADS
  409 
  410 # define WIN32_LEAN_AND_MEAN  /* avoid including junk */
  411 # include <windows.h>
  412 
  413 # include "windows-mutex.h"
  414 # include "windows-rwlock.h"
  415 # include "windows-recmutex.h"
  416 # include "windows-once.h"
  417 
  418 # ifdef __cplusplus
  419 extern "C" {
  420 # endif
  421 
  422 /* We can use CRITICAL_SECTION directly, rather than the native Windows Event,
  423    Mutex, Semaphore types, because
  424      - we need only to synchronize inside a single process (address space),
  425        not inter-process locking,
  426      - we don't need to support trylock operations.  (TryEnterCriticalSection
  427        does not work on Windows 95/98/ME.  Packages that need trylock usually
  428        define their own mutex type.)  */
  429 
  430 /* There is no way to statically initialize a CRITICAL_SECTION.  It needs
  431    to be done lazily, once only.  For this we need spinlocks.  */
  432 
  433 /* -------------------------- gl_lock_t datatype -------------------------- */
  434 
  435 typedef glwthread_mutex_t gl_lock_t;
  436 # define gl_lock_define(STORAGECLASS, NAME) \
  437     STORAGECLASS gl_lock_t NAME;
  438 # define gl_lock_define_initialized(STORAGECLASS, NAME) \
  439     STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
  440 # define gl_lock_initializer \
  441     GLWTHREAD_MUTEX_INIT
  442 # define glthread_lock_init(LOCK) \
  443     (glwthread_mutex_init (LOCK), 0)
  444 # define glthread_lock_lock(LOCK) \
  445     glwthread_mutex_lock (LOCK)
  446 # define glthread_lock_unlock(LOCK) \
  447     glwthread_mutex_unlock (LOCK)
  448 # define glthread_lock_destroy(LOCK) \
  449     glwthread_mutex_destroy (LOCK)
  450 
  451 /* ------------------------- gl_rwlock_t datatype ------------------------- */
  452 
  453 typedef glwthread_rwlock_t gl_rwlock_t;
  454 # define gl_rwlock_define(STORAGECLASS, NAME) \
  455     STORAGECLASS gl_rwlock_t NAME;
  456 # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
  457     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
  458 # define gl_rwlock_initializer \
  459     GLWTHREAD_RWLOCK_INIT
  460 # define glthread_rwlock_init(LOCK) \
  461     (glwthread_rwlock_init (LOCK), 0)
  462 # define glthread_rwlock_rdlock(LOCK) \
  463     glwthread_rwlock_rdlock (LOCK)
  464 # define glthread_rwlock_wrlock(LOCK) \
  465     glwthread_rwlock_wrlock (LOCK)
  466 # define glthread_rwlock_unlock(LOCK) \
  467     glwthread_rwlock_unlock (LOCK)
  468 # define glthread_rwlock_destroy(LOCK) \
  469     glwthread_rwlock_destroy (LOCK)
  470 
  471 /* --------------------- gl_recursive_lock_t datatype --------------------- */
  472 
  473 typedef glwthread_recmutex_t gl_recursive_lock_t;
  474 # define gl_recursive_lock_define(STORAGECLASS, NAME) \
  475     STORAGECLASS gl_recursive_lock_t NAME;
  476 # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
  477     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
  478 # define gl_recursive_lock_initializer \
  479     GLWTHREAD_RECMUTEX_INIT
  480 # define glthread_recursive_lock_init(LOCK) \
  481     (glwthread_recmutex_init (LOCK), 0)
  482 # define glthread_recursive_lock_lock(LOCK) \
  483     glwthread_recmutex_lock (LOCK)
  484 # define glthread_recursive_lock_unlock(LOCK) \
  485     glwthread_recmutex_unlock (LOCK)
  486 # define glthread_recursive_lock_destroy(LOCK) \
  487     glwthread_recmutex_destroy (LOCK)
  488 
  489 /* -------------------------- gl_once_t datatype -------------------------- */
  490 
  491 typedef glwthread_once_t gl_once_t;
  492 # define gl_once_define(STORAGECLASS, NAME) \
  493     STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT;
  494 # define glthread_once(ONCE_CONTROL, INITFUNCTION) \
  495     (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0)
  496 
  497 # ifdef __cplusplus
  498 }
  499 # endif
  500 
  501 #endif
  502 
  503 /* ========================================================================= */
  504 
  505 #if !(USE_POSIX_THREADS || USE_WINDOWS_THREADS)
  506 
  507 /* Provide dummy implementation if threads are not supported.  */
  508 
  509 /* -------------------------- gl_lock_t datatype -------------------------- */
  510 
  511 typedef int gl_lock_t;
  512 # define gl_lock_define(STORAGECLASS, NAME)
  513 # define gl_lock_define_initialized(STORAGECLASS, NAME)
  514 # define glthread_lock_init(NAME) 0
  515 # define glthread_lock_lock(NAME) 0
  516 # define glthread_lock_unlock(NAME) 0
  517 # define glthread_lock_destroy(NAME) 0
  518 
  519 /* ------------------------- gl_rwlock_t datatype ------------------------- */
  520 
  521 typedef int gl_rwlock_t;
  522 # define gl_rwlock_define(STORAGECLASS, NAME)
  523 # define gl_rwlock_define_initialized(STORAGECLASS, NAME)
  524 # define glthread_rwlock_init(NAME) 0
  525 # define glthread_rwlock_rdlock(NAME) 0
  526 # define glthread_rwlock_wrlock(NAME) 0
  527 # define glthread_rwlock_unlock(NAME) 0
  528 # define glthread_rwlock_destroy(NAME) 0
  529 
  530 /* --------------------- gl_recursive_lock_t datatype --------------------- */
  531 
  532 typedef int gl_recursive_lock_t;
  533 # define gl_recursive_lock_define(STORAGECLASS, NAME)
  534 # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
  535 # define glthread_recursive_lock_init(NAME) 0
  536 # define glthread_recursive_lock_lock(NAME) 0
  537 # define glthread_recursive_lock_unlock(NAME) 0
  538 # define glthread_recursive_lock_destroy(NAME) 0
  539 
  540 /* -------------------------- gl_once_t datatype -------------------------- */
  541 
  542 typedef int gl_once_t;
  543 # define gl_once_define(STORAGECLASS, NAME) \
  544     STORAGECLASS gl_once_t NAME = 0;
  545 # define glthread_once(ONCE_CONTROL, INITFUNCTION) \
  546     (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
  547 
  548 #endif
  549 
  550 /* ========================================================================= */
  551 
  552 /* Macros with built-in error handling.  */
  553 
  554 /* -------------------------- gl_lock_t datatype -------------------------- */
  555 
  556 #define gl_lock_init(NAME) \
  557    do                                  \
  558      {                                 \
  559        if (glthread_lock_init (&NAME)) \
  560          abort ();                     \
  561      }                                 \
  562    while (0)
  563 #define gl_lock_lock(NAME) \
  564    do                                  \
  565      {                                 \
  566        if (glthread_lock_lock (&NAME)) \
  567          abort ();                     \
  568      }                                 \
  569    while (0)
  570 #define gl_lock_unlock(NAME) \
  571    do                                    \
  572      {                                   \
  573        if (glthread_lock_unlock (&NAME)) \
  574          abort ();                       \
  575      }                                   \
  576    while (0)
  577 #define gl_lock_destroy(NAME) \
  578    do                                     \
  579      {                                    \
  580        if (glthread_lock_destroy (&NAME)) \
  581          abort ();                        \
  582      }                                    \
  583    while (0)
  584 
  585 /* ------------------------- gl_rwlock_t datatype ------------------------- */
  586 
  587 #define gl_rwlock_init(NAME) \
  588    do                                    \
  589      {                                   \
  590        if (glthread_rwlock_init (&NAME)) \
  591          abort ();                       \
  592      }                                   \
  593    while (0)
  594 #define gl_rwlock_rdlock(NAME) \
  595    do                                      \
  596      {                                     \
  597        if (glthread_rwlock_rdlock (&NAME)) \
  598          abort ();                         \
  599      }                                     \
  600    while (0)
  601 #define gl_rwlock_wrlock(NAME) \
  602    do                                      \
  603      {                                     \
  604        if (glthread_rwlock_wrlock (&NAME)) \
  605          abort ();                         \
  606      }                                     \
  607    while (0)
  608 #define gl_rwlock_unlock(NAME) \
  609    do                                      \
  610      {                                     \
  611        if (glthread_rwlock_unlock (&NAME)) \
  612          abort ();                         \
  613      }                                     \
  614    while (0)
  615 #define gl_rwlock_destroy(NAME) \
  616    do                                       \
  617      {                                      \
  618        if (glthread_rwlock_destroy (&NAME)) \
  619          abort ();                          \
  620      }                                      \
  621    while (0)
  622 
  623 /* --------------------- gl_recursive_lock_t datatype --------------------- */
  624 
  625 #define gl_recursive_lock_init(NAME) \
  626    do                                            \
  627      {                                           \
  628        if (glthread_recursive_lock_init (&NAME)) \
  629          abort ();                               \
  630      }                                           \
  631    while (0)
  632 #define gl_recursive_lock_lock(NAME) \
  633    do                                            \
  634      {                                           \
  635        if (glthread_recursive_lock_lock (&NAME)) \
  636          abort ();                               \
  637      }                                           \
  638    while (0)
  639 #define gl_recursive_lock_unlock(NAME) \
  640    do                                              \
  641      {                                             \
  642        if (glthread_recursive_lock_unlock (&NAME)) \
  643          abort ();                                 \
  644      }                                             \
  645    while (0)
  646 #define gl_recursive_lock_destroy(NAME) \
  647    do                                               \
  648      {                                              \
  649        if (glthread_recursive_lock_destroy (&NAME)) \
  650          abort ();                                  \
  651      }                                              \
  652    while (0)
  653 
  654 /* -------------------------- gl_once_t datatype -------------------------- */
  655 
  656 #define gl_once(NAME, INITFUNCTION) \
  657    do                                           \
  658      {                                          \
  659        if (glthread_once (&NAME, INITFUNCTION)) \
  660          abort ();                              \
  661      }                                          \
  662    while (0)
  663 
  664 /* ========================================================================= */
  665 
  666 #endif /* _LOCK_H */