105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Locking in multithreaded situations.
205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Copyright (C) 2005-2012 Free Software Foundation, Inc.
305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is free software; you can redistribute it and/or modify
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   it under the terms of the GNU General Public License as published by
605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the Free Software Foundation; either version 3, or (at your option)
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   any later version.
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is distributed in the hope that it will be useful,
1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   but WITHOUT ANY WARRANTY; without even the implied warranty of
1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   GNU General Public License for more details.
1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   You should have received a copy of the GNU General Public License
1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Written by Bruno Haible <bruno@clisp.org>, 2005.
1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h,
1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   gthr-win32.h.  */
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* This file contains locking primitives for use with a given thread library.
2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   It does not contain primitives for creating threads or for other
2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   synchronization primitives.
2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Normal (non-recursive) locks:
2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Type:                gl_lock_t
2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Declaration:         gl_lock_define(extern, name)
2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initializer:         gl_lock_define_initialized(, name)
2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initialization:      gl_lock_init (name);
3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Taking the lock:     gl_lock_lock (name);
3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Releasing the lock:  gl_lock_unlock (name);
3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     De-initialization:   gl_lock_destroy (name);
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Equivalent functions with control of error handling:
3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initialization:      err = glthread_lock_init (&name);
3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Taking the lock:     err = glthread_lock_lock (&name);
3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Releasing the lock:  err = glthread_lock_unlock (&name);
3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     De-initialization:   err = glthread_lock_destroy (&name);
3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Read-Write (non-recursive) locks:
4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Type:                gl_rwlock_t
4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Declaration:         gl_rwlock_define(extern, name)
4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initializer:         gl_rwlock_define_initialized(, name)
4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initialization:      gl_rwlock_init (name);
4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Taking the lock:     gl_rwlock_rdlock (name);
4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          gl_rwlock_wrlock (name);
4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Releasing the lock:  gl_rwlock_unlock (name);
4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     De-initialization:   gl_rwlock_destroy (name);
4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Equivalent functions with control of error handling:
4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initialization:      err = glthread_rwlock_init (&name);
5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Taking the lock:     err = glthread_rwlock_rdlock (&name);
5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang                          err = glthread_rwlock_wrlock (&name);
5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Releasing the lock:  err = glthread_rwlock_unlock (&name);
5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     De-initialization:   err = glthread_rwlock_destroy (&name);
5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Recursive locks:
5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Type:                gl_recursive_lock_t
5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Declaration:         gl_recursive_lock_define(extern, name)
5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initializer:         gl_recursive_lock_define_initialized(, name)
5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initialization:      gl_recursive_lock_init (name);
6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Taking the lock:     gl_recursive_lock_lock (name);
6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Releasing the lock:  gl_recursive_lock_unlock (name);
6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     De-initialization:   gl_recursive_lock_destroy (name);
6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Equivalent functions with control of error handling:
6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initialization:      err = glthread_recursive_lock_init (&name);
6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Taking the lock:     err = glthread_recursive_lock_lock (&name);
6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Releasing the lock:  err = glthread_recursive_lock_unlock (&name);
6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     De-initialization:   err = glthread_recursive_lock_destroy (&name);
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  Once-only execution:
7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Type:                gl_once_t
7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Initializer:         gl_once_define(extern, name)
7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Execution:           gl_once (name, initfunction);
7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Equivalent functions with control of error handling:
7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     Execution:           err = glthread_once (&name, initfunction);
7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang*/
7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef _LOCK_H
7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define _LOCK_H
8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <errno.h>
8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stdlib.h>
8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_POSIX_THREADS
8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the POSIX threads library.  */
8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <pthread.h>
9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
9305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" {
9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if PTHREAD_IN_USE_DETECTION_HARD
9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The pthread_in_use() detection needs to be done at runtime.  */
9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define pthread_in_use() \
10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     glthread_in_use ()
10105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_in_use (void);
10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if USE_POSIX_THREADS_WEAK
10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use weak references to the POSIX threads library.  */
10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Weak references avoid dragging in external libraries if the other parts
11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   of the program don't use them.  Here we use them, because we don't want
11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   every program that uses libintl to depend on libpthread.  This assumes
11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   that libpthread would not be loaded after libintl; i.e. if libintl is
11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   loaded first, by an executable that does not depend on libpthread, and
11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   then a module is dynamically loaded that depends on libpthread, libintl
11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   will not be multithread-safe.  */
11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The way to test at runtime whether libpthread is present is to test
11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   whether a function pointer's value, such as &pthread_mutex_init, is
11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   non-NULL.  However, some versions of GCC have a bug through which, in
12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   PIC mode, &foo != NULL always evaluates to true if there is a direct
12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   call to foo(...) in the same function.  To avoid this, we test the
12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   address of a function in libpthread that we don't use.  */
12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutex_init
12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutex_lock
12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutex_unlock
12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutex_destroy
12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_rwlock_init
12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_rwlock_rdlock
13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_rwlock_wrlock
13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_rwlock_unlock
13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_rwlock_destroy
13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_once
13405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_cond_init
13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_cond_wait
13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_cond_signal
13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_cond_broadcast
13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_cond_destroy
13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutexattr_init
14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutexattr_settype
14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pthread_mutexattr_destroy
14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  ifndef pthread_self
14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   pragma weak pthread_self
14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  if !PTHREAD_IN_USE_DETECTION_HARD
14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   pragma weak pthread_cancel
14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define pthread_in_use() (pthread_cancel != NULL)
14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  if !PTHREAD_IN_USE_DETECTION_HARD
15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define pthread_in_use() 1
15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */
16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
16105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_mutex_t gl_lock_t;
16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \
16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS pthread_mutex_t NAME;
16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \
16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \
16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    PTHREAD_MUTEX_INITIALIZER
16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \
16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \
17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \
17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \
17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
17605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
17705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */
17805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
17905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if HAVE_PTHREAD_RWLOCK
18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  ifdef PTHREAD_RWLOCK_INITIALIZER
18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
18305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_rwlock_t gl_rwlock_t;
18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_rwlock_define(STORAGECLASS, NAME) \
18505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS pthread_rwlock_t NAME;
18605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
18805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_rwlock_initializer \
18905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      PTHREAD_RWLOCK_INITIALIZER
19005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_init(LOCK) \
19105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
19205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_rdlock(LOCK) \
19305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
19405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_wrlock(LOCK) \
19505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
19605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_unlock(LOCK) \
19705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
19805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_destroy(LOCK) \
19905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)
20005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
20105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  else
20205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
20305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
20405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
20505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          int initialized;
20605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_mutex_t guard;   /* protects the initialization */
20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_rwlock_t rwlock; /* read-write lock */
20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_rwlock_t;
21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_rwlock_define(STORAGECLASS, NAME) \
21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS gl_rwlock_t NAME;
21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_rwlock_initializer \
21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      { 0, PTHREAD_MUTEX_INITIALIZER }
21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_init(LOCK) \
21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_rdlock(LOCK) \
21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_wrlock(LOCK) \
22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_unlock(LOCK) \
22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_rwlock_destroy(LOCK) \
22505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
22605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
22705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
22805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
22905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
23005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
23105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
23205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
23305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
23505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
23605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
23705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_mutex_t lock; /* protects the remaining fields */
23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_cond_t waiting_readers; /* waiting readers */
24005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_cond_t waiting_writers; /* waiting writers */
24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned int waiting_writers_count; /* number of waiting writers */
24205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          int runcount; /* number of readers running, or -1 when a writer runs */
24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_rwlock_t;
24505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \
24605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_rwlock_t NAME;
24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
24805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
24905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \
25005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
25105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \
25205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
25305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \
25405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \
25605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
25705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \
25805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
25905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \
26005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
26105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
26205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
26305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
26405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
26505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
26605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
26805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */
27005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if HAVE_PTHREAD_MUTEX_RECURSIVE
27205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
27305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
27405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
27505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_mutex_t gl_recursive_lock_t;
27605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
27705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS pthread_mutex_t NAME;
27805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
27905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer;
28005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
28105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#    define gl_recursive_lock_initializer \
28205436638acc7c010349a69c3395f1a57c642dc62Ying Wang       PTHREAD_RECURSIVE_MUTEX_INITIALIZER
28305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   else
28405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#    define gl_recursive_lock_initializer \
28505436638acc7c010349a69c3395f1a57c642dc62Ying Wang       PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   endif
28705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_init(LOCK) \
28805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
28905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_lock(LOCK) \
29005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
29105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_unlock(LOCK) \
29205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
29305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_destroy(LOCK) \
29405436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
29505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
29605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
29705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  else
29805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
29905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
30005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
30105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_mutex_t recmutex; /* recursive mutex */
30205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_mutex_t guard;    /* protects the initialization */
30305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          int initialized;
30405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
30505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_recursive_lock_t;
30605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_recursive_lock_define(STORAGECLASS, NAME) \
30705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS gl_recursive_lock_t NAME;
30805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
30905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
31005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define gl_recursive_lock_initializer \
31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
31205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_init(LOCK) \
31305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
31405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_lock(LOCK) \
31505436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
31605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_unlock(LOCK) \
31705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
31805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   define glthread_recursive_lock_destroy(LOCK) \
31905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
32005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
32105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
32205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
32305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
32405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
32505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
32605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
32705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
32805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
32905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Old versions of POSIX threads on Solaris did not have recursive locks.
33005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   We have to implement them ourselves.  */
33105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
33205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
33305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
33405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_mutex_t mutex;
33505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          pthread_t owner;
33605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned long depth;
33705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
33805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_recursive_lock_t;
33905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
34005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     STORAGECLASS gl_recursive_lock_t NAME;
34105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
34205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
34305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_recursive_lock_initializer \
34405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
34505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_init(LOCK) \
34605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
34705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_lock(LOCK) \
34805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
34905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_unlock(LOCK) \
35005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
35105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_destroy(LOCK) \
35205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
35305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
35405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
35505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
35605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
35705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
35805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
35905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
36005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */
36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
36205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pthread_once_t gl_once_t;
36305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \
36405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
36505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
36605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pthread_in_use ()                                                         \
36705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     ? pthread_once (ONCE_CONTROL, INITFUNCTION)                               \
36805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
36905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_singlethreaded (pthread_once_t *once_control);
37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
37305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
37405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
37605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
37905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_PTH_THREADS
38005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the GNU Pth threads library.  */
38205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <pth.h>
38405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
38605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" {
38705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
38805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
38905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if USE_PTH_THREADS_WEAK
39005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
39105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use weak references to the GNU Pth threads library.  */
39205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
39305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_mutex_init
39405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_mutex_acquire
39505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_mutex_release
39605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_rwlock_init
39705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_rwlock_acquire
39805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_rwlock_release
39905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_once
40005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
40105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak pth_cancel
40205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define pth_in_use() (pth_cancel != NULL)
40305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
40405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
40505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
40605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define pth_in_use() 1
40705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
40805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
40905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
41005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */
41105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
41205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_mutex_t gl_lock_t;
41305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \
41405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS pth_mutex_t NAME;
41505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \
41605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
41705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \
41805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    PTH_MUTEX_INIT
41905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \
42005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
42105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \
42205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
42305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \
42405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
42505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \
42605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    ((void)(LOCK), 0)
42705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
42805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */
42905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
43005436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_rwlock_t gl_rwlock_t;
43105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_rwlock_define(STORAGECLASS, NAME) \
43205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     STORAGECLASS pth_rwlock_t NAME;
43305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
43405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
43505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_rwlock_initializer \
43605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     PTH_RWLOCK_INIT
43705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_rwlock_init(LOCK) \
43805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_rwlock_init (LOCK) ? errno : 0)
43905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_rwlock_rdlock(LOCK) \
44005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0)
44105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_rwlock_wrlock(LOCK) \
44205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0)
44305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_rwlock_unlock(LOCK) \
44405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_rwlock_release (LOCK) ? errno : 0)
44505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_rwlock_destroy(LOCK) \
44605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     ((void)(LOCK), 0)
44705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
44805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */
44905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
45005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* In Pth, mutexes are recursive by default.  */
45105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_mutex_t gl_recursive_lock_t;
45205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_recursive_lock_define(STORAGECLASS, NAME) \
45305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     STORAGECLASS pth_mutex_t NAME;
45405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
45505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
45605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define gl_recursive_lock_initializer \
45705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     PTH_MUTEX_INIT
45805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_init(LOCK) \
45905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_mutex_init (LOCK) ? errno : 0)
46005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_lock(LOCK) \
46105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
46205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_unlock(LOCK) \
46305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     (pth_in_use () && !pth_mutex_release (LOCK) ? errno : 0)
46405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define glthread_recursive_lock_destroy(LOCK) \
46505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     ((void)(LOCK), 0)
46605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
46705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */
46805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
46905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef pth_once_t gl_once_t;
47005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \
47105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
47205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
47305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (pth_in_use ()                                                             \
47405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
47505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
47605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void));
47705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_singlethreaded (pth_once_t *once_control);
47805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
47905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
48005436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
48105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
48205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
48305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
48405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
48505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
48605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
48705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_SOLARIS_THREADS
48805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
48905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use the old Solaris threads library.  */
49005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
49105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <thread.h>
49205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <synch.h>
49305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
49405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
49505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" {
49605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
49705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
49805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if USE_SOLARIS_THREADS_WEAK
49905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
50005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Use weak references to the old Solaris threads library.  */
50105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
50205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak mutex_init
50305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak mutex_lock
50405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak mutex_unlock
50505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak mutex_destroy
50605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak rwlock_init
50705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak rw_rdlock
50805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak rw_wrlock
50905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak rw_unlock
51005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak rwlock_destroy
51105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak thr_self
51205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
51305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  pragma weak thr_suspend
51405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define thread_in_use() (thr_suspend != NULL)
51505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
51605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
51705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
51805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define thread_in_use() 1
51905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
52005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
52105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
52205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */
52305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
52405436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef mutex_t gl_lock_t;
52505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \
52605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS mutex_t NAME;
52705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \
52805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS mutex_t NAME = gl_lock_initializer;
52905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \
53005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    DEFAULTMUTEX
53105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \
53205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0)
53305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \
53405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? mutex_lock (LOCK) : 0)
53505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \
53605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? mutex_unlock (LOCK) : 0)
53705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \
53805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? mutex_destroy (LOCK) : 0)
53905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
54005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */
54105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
54205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef rwlock_t gl_rwlock_t;
54305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \
54405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS rwlock_t NAME;
54505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
54605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
54705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \
54805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    DEFAULTRWLOCK
54905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \
55005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0)
55105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \
55205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? rw_rdlock (LOCK) : 0)
55305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \
55405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? rw_wrlock (LOCK) : 0)
55505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \
55605436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? rw_unlock (LOCK) : 0)
55705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \
55805436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? rwlock_destroy (LOCK) : 0)
55905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
56005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */
56105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
56205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Old Solaris threads did not have recursive locks.
56305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   We have to implement them ourselves.  */
56405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
56505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
56605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
56705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          mutex_t mutex;
56805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          thread_t owner;
56905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned long depth;
57005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
57105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_recursive_lock_t;
57205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \
57305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_recursive_lock_t NAME;
57405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
57505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
57605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \
57705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { DEFAULTMUTEX, (thread_t) 0, 0 }
57805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \
57905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
58005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \
58105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
58205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \
58305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
58405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \
58505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
58605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
58705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
58805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
58905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
59005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
59105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */
59205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
59305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
59405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
59505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          volatile int inited;
59605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          mutex_t mutex;
59705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
59805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_once_t;
59905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \
60005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
60105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
60205436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (thread_in_use ()                                                          \
60305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
60405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
60505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void));
60605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_once_singlethreaded (gl_once_t *once_control);
60705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
60805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
60905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
61005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
61105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
61205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
61305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
61405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
61505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
61605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if USE_WINDOWS_THREADS
61705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
61805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define WIN32_LEAN_AND_MEAN  /* avoid including junk */
61905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <windows.h>
62005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
62105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
62205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern "C" {
62305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
62405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
62505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* We can use CRITICAL_SECTION directly, rather than the native Windows Event,
62605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Mutex, Semaphore types, because
62705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     - we need only to synchronize inside a single process (address space),
62805436638acc7c010349a69c3395f1a57c642dc62Ying Wang       not inter-process locking,
62905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     - we don't need to support trylock operations.  (TryEnterCriticalSection
63005436638acc7c010349a69c3395f1a57c642dc62Ying Wang       does not work on Windows 95/98/ME.  Packages that need trylock usually
63105436638acc7c010349a69c3395f1a57c642dc62Ying Wang       define their own mutex type.)  */
63205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
63305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* There is no way to statically initialize a CRITICAL_SECTION.  It needs
63405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   to be done lazily, once only.  For this we need spinlocks.  */
63505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
63605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct { volatile int done; volatile long started; } gl_spinlock_t;
63705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
63805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */
63905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
64005436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
64105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
64205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          gl_spinlock_t guard; /* protects the initialization */
64305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          CRITICAL_SECTION lock;
64405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
64505436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_lock_t;
64605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME) \
64705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_lock_t NAME;
64805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME) \
64905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
65005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_initializer \
65105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { { 0, -1 } }
65205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(LOCK) \
65305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (glthread_lock_init_func (LOCK), 0)
65405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(LOCK) \
65505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_lock_lock_func (LOCK)
65605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(LOCK) \
65705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_lock_unlock_func (LOCK)
65805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(LOCK) \
65905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_lock_destroy_func (LOCK)
66005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_lock_init_func (gl_lock_t *lock);
66105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_lock_lock_func (gl_lock_t *lock);
66205436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_lock_unlock_func (gl_lock_t *lock);
66305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_lock_destroy_func (gl_lock_t *lock);
66405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
66505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */
66605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
66705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* It is impossible to implement read-write locks using plain locks, without
66805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   introducing an extra thread dedicated to managing read-write locks.
66905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Therefore here we need to use the low-level Event type.  */
67005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
67105436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
67205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
67305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          HANDLE *array; /* array of waiting threads, each represented by an event */
67405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned int count; /* number of waiting threads */
67505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned int alloc; /* length of allocated array */
67605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned int offset; /* index of first waiting thread in array */
67705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
67805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_carray_waitqueue_t;
67905436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
68005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
68105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          gl_spinlock_t guard; /* protects the initialization */
68205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          CRITICAL_SECTION lock; /* protects the remaining fields */
68305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          gl_carray_waitqueue_t waiting_readers; /* waiting readers */
68405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          gl_carray_waitqueue_t waiting_writers; /* waiting writers */
68505436638acc7c010349a69c3395f1a57c642dc62Ying Wang          int runcount; /* number of readers running, or -1 when a writer runs */
68605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
68705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_rwlock_t;
68805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME) \
68905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_rwlock_t NAME;
69005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
69105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
69205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_initializer \
69305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { { 0, -1 } }
69405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(LOCK) \
69505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (glthread_rwlock_init_func (LOCK), 0)
69605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(LOCK) \
69705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_rwlock_rdlock_func (LOCK)
69805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(LOCK) \
69905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_rwlock_wrlock_func (LOCK)
70005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(LOCK) \
70105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_rwlock_unlock_func (LOCK)
70205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(LOCK) \
70305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_rwlock_destroy_func (LOCK)
70405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_rwlock_init_func (gl_rwlock_t *lock);
70505436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_rdlock_func (gl_rwlock_t *lock);
70605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_wrlock_func (gl_rwlock_t *lock);
70705436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_unlock_func (gl_rwlock_t *lock);
70805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);
70905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
71005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */
71105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
71205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The native Windows documentation says that CRITICAL_SECTION already
71305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   implements a recursive lock.  But we need not rely on it: It's easy to
71405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   implement a recursive lock without this assumption.  */
71505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
71605436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
71705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
71805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          gl_spinlock_t guard; /* protects the initialization */
71905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          DWORD owner;
72005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          unsigned long depth;
72105436638acc7c010349a69c3395f1a57c642dc62Ying Wang          CRITICAL_SECTION lock;
72205436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
72305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_recursive_lock_t;
72405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME) \
72505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_recursive_lock_t NAME;
72605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
72705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
72805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_initializer \
72905436638acc7c010349a69c3395f1a57c642dc62Ying Wang    { { 0, -1 }, 0, 0 }
73005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(LOCK) \
73105436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (glthread_recursive_lock_init_func (LOCK), 0)
73205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(LOCK) \
73305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_recursive_lock_lock_func (LOCK)
73405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(LOCK) \
73505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_recursive_lock_unlock_func (LOCK)
73605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(LOCK) \
73705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    glthread_recursive_lock_destroy_func (LOCK)
73805436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock);
73905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock);
74005436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock);
74105436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock);
74205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
74305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */
74405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
74505436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct
74605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
74705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          volatile int inited;
74805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          volatile long started;
74905436638acc7c010349a69c3395f1a57c642dc62Ying Wang          CRITICAL_SECTION lock;
75005436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
75105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        gl_once_t;
75205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \
75305436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_once_t NAME = { -1, -1 };
75405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
75505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
75605436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));
75705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
75805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# ifdef __cplusplus
75905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
76005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
76105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
76205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
76305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
76405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
76505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
76605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS)
76705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
76805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Provide dummy implementation if threads are not supported.  */
76905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
77005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */
77105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
77205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_lock_t;
77305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define(STORAGECLASS, NAME)
77405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_lock_define_initialized(STORAGECLASS, NAME)
77505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_init(NAME) 0
77605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_lock(NAME) 0
77705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_unlock(NAME) 0
77805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_lock_destroy(NAME) 0
77905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
78005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */
78105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
78205436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_rwlock_t;
78305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define(STORAGECLASS, NAME)
78405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_rwlock_define_initialized(STORAGECLASS, NAME)
78505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_init(NAME) 0
78605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_rdlock(NAME) 0
78705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_wrlock(NAME) 0
78805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_unlock(NAME) 0
78905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_rwlock_destroy(NAME) 0
79005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
79105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */
79205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
79305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_recursive_lock_t;
79405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define(STORAGECLASS, NAME)
79505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
79605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_init(NAME) 0
79705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_lock(NAME) 0
79805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_unlock(NAME) 0
79905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_recursive_lock_destroy(NAME) 0
80005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
80105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */
80205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
80305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef int gl_once_t;
80405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define gl_once_define(STORAGECLASS, NAME) \
80505436638acc7c010349a69c3395f1a57c642dc62Ying Wang    STORAGECLASS gl_once_t NAME = 0;
80605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
80705436638acc7c010349a69c3395f1a57c642dc62Ying Wang    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
80805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
80905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
81005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
81105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
81205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
81305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Macros with built-in error handling.  */
81405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
81505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_lock_t datatype -------------------------- */
81605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
81705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_init(NAME) \
81805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                  \
81905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                 \
82005436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_lock_init (&NAME)) \
82105436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                     \
82205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                 \
82305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
82405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_lock(NAME) \
82505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                  \
82605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                 \
82705436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_lock_lock (&NAME)) \
82805436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                     \
82905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                 \
83005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
83105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_unlock(NAME) \
83205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                    \
83305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                   \
83405436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_lock_unlock (&NAME)) \
83505436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                       \
83605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                   \
83705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
83805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_lock_destroy(NAME) \
83905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                     \
84005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                    \
84105436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_lock_destroy (&NAME)) \
84205436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                        \
84305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                    \
84405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
84505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
84605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ------------------------- gl_rwlock_t datatype ------------------------- */
84705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
84805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_init(NAME) \
84905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                    \
85005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                   \
85105436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_rwlock_init (&NAME)) \
85205436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                       \
85305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                   \
85405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
85505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_rdlock(NAME) \
85605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                      \
85705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                     \
85805436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_rwlock_rdlock (&NAME)) \
85905436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                         \
86005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                     \
86105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
86205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_wrlock(NAME) \
86305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                      \
86405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                     \
86505436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_rwlock_wrlock (&NAME)) \
86605436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                         \
86705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                     \
86805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
86905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_unlock(NAME) \
87005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                      \
87105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                     \
87205436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_rwlock_unlock (&NAME)) \
87305436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                         \
87405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                     \
87505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
87605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_rwlock_destroy(NAME) \
87705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                       \
87805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                      \
87905436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_rwlock_destroy (&NAME)) \
88005436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                          \
88105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                      \
88205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
88305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
88405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* --------------------- gl_recursive_lock_t datatype --------------------- */
88505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
88605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_init(NAME) \
88705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                            \
88805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                           \
88905436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_recursive_lock_init (&NAME)) \
89005436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                               \
89105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                           \
89205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
89305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_lock(NAME) \
89405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                            \
89505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                           \
89605436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_recursive_lock_lock (&NAME)) \
89705436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                               \
89805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                           \
89905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
90005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_unlock(NAME) \
90105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                              \
90205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                             \
90305436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_recursive_lock_unlock (&NAME)) \
90405436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                                 \
90505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                             \
90605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
90705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_recursive_lock_destroy(NAME) \
90805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                               \
90905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                              \
91005436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_recursive_lock_destroy (&NAME)) \
91105436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                                  \
91205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                              \
91305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
91405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
91505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* -------------------------- gl_once_t datatype -------------------------- */
91605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
91705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define gl_once(NAME, INITFUNCTION) \
91805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   do                                           \
91905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     {                                          \
92005436638acc7c010349a69c3395f1a57c642dc62Ying Wang       if (glthread_once (&NAME, INITFUNCTION)) \
92105436638acc7c010349a69c3395f1a57c642dc62Ying Wang         abort ();                              \
92205436638acc7c010349a69c3395f1a57c642dc62Ying Wang     }                                          \
92305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   while (0)
92405436638acc7c010349a69c3395f1a57c642dc62Ying Wang
92505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* ========================================================================= */
92605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
92705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif /* _LOCK_H */
928