Blame gnulib/lib/glthread/lock.h

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