]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Additional non-aborting API for lock, from gnulib.
authorBruno Haible <bruno@clisp.org>
Sun, 3 Aug 2008 18:48:57 +0000 (18:48 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:15:45 +0000 (12:15 +0200)
gettext-runtime/intl/ChangeLog
gettext-runtime/intl/lock.c
gettext-runtime/intl/lock.h

index fd7f3b38ecfd714dbd47d1d268016c4c7c42017b..bab4c809b55deb7c135c8bc4fabfb2c6a0133b86 100644 (file)
@@ -1,3 +1,62 @@
+2008-08-03  Bruno Haible  <bruno@clisp.org>
+
+       Additional non-aborting API for lock.
+       * lib/lock.h: Include <errno.h>.
+       (glthread_lock_init): New macro/function.
+       (gl_lock_init): Define as wrapper around glthread_lock_init.
+       (glthread_lock_lock): New macro/function.
+       (gl_lock_lock): Define as wrapper around glthread_lock_lock.
+       (glthread_lock_unlock): New macro/function.
+       (gl_lock_unlock): Define as wrapper around glthread_lock_unlock.
+       (glthread_lock_destroy): New macro/function.
+       (gl_lock_destroy): Define as wrapper around glthread_lock_destroy.
+       (glthread_rwlock_init): New macro/function.
+       (gl_rwlock_init): Define as wrapper around glthread_rwlock_init.
+       (glthread_rwlock_rdlock): New macro/function.
+       (gl_rwlock_rdlock): Define as wrapper around glthread_rwlock_rdlock.
+       (glthread_rwlock_wrlock): New macro/function.
+       (gl_rwlock_wrlock): Define as wrapper around glthread_rwlock_wrlock.
+       (glthread_rwlock_unlock): New macro/function.
+       (gl_rwlock_unlock): Define as wrapper around glthread_rwlock_unlock.
+       (glthread_rwlock_destroy): New macro/function.
+       (gl_rwlock_destroy): Define as wrapper around glthread_rwlock_destroy.
+       (glthread_recursive_lock_init): New macro/function.
+       (gl_recursive_lock_init): Define as wrapper around
+       glthread_recursive_lock_init.
+       (glthread_recursive_lock_lock): New macro/function.
+       (gl_recursive_lock_lock): Define as wrapper around
+       glthread_recursive_lock_lock.
+       (glthread_recursive_lock_unlock): New macro/function.
+       (gl_recursive_lock_unlock): Define as wrapper around
+       glthread_recursive_lock_unlock.
+       (glthread_recursive_lock_destroy): New macro/function.
+       (gl_recursive_lock_destroy): Define as wrapper around
+       glthread_recursive_lock_destroy.
+       (glthread_once): New macro/function.
+       (gl_once): Define as wrapper around glthread_once.
+       Update function declarations.
+       * lib/lock.c (glthread_rwlock_init_multithreaded): Renamed from
+       glthread_rwlock_init. Return error code.
+       (glthread_rwlock_rdlock_multithreaded): Renamed from
+       glthread_rwlock_rdlock. Return error code.
+       (glthread_rwlock_wrlock_multithreaded): Renamed from
+       glthread_rwlock_wrlock. Return error code.
+       (glthread_rwlock_unlock_multithreaded): Renamed from
+       glthread_rwlock_unlock. Return error code.
+       (glthread_rwlock_destroy_multithreaded): Renamed from
+       glthread_rwlock_destroy. Return error code.
+       (glthread_recursive_lock_init_multithreaded): Renamed from
+       glthread_recursive_lock_init. Return error code.
+       (glthread_recursive_lock_lock_multithreaded): Renamed from
+       glthread_recursive_lock_lock. Return error code.
+       (glthread_recursive_lock_unlock_multithreaded): Renamed from
+       glthread_recursive_lock_unlock. Return error code.
+       (glthread_recursive_lock_destroy_multithreaded): Renamed from
+       glthread_recursive_lock_destroy. Return error code.
+       (glthread_once_call): Make static.
+       (glthread_once_multithreaded): Renamed from glthread_once.
+       Suggested by Yoann Vandoorselaere <yoann@prelude-ids.org>.
+
 2008-03-30  Ulrich Drepper  <drepper@redhat.com>
 
        [BZ #5443]
index 728bd7b5aa42bc87b142edbd181244c874a4d5ab..595af423d679408309080314bdd0526508d6fa1e 100644 (file)
@@ -1,5 +1,5 @@
 /* Locking in multithreaded situations.
-   Copyright (C) 2005-2007 Free Software Foundation, Inc.
+   Copyright (C) 2005-2008 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published
@@ -75,87 +75,123 @@ glthread_in_use (void)
 
 #  if !defined PTHREAD_RWLOCK_INITIALIZER
 
-void
-glthread_rwlock_init (gl_rwlock_t *lock)
+int
+glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
 {
-  if (pthread_rwlock_init (&lock->rwlock, NULL) != 0)
-    abort ();
+  int err;
+
+  err = pthread_rwlock_init (&lock->rwlock, NULL);
+  if (err != 0)
+    return err;
   lock->initialized = 1;
+  return 0;
 }
 
-void
-glthread_rwlock_rdlock (gl_rwlock_t *lock)
+int
+glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
 {
   if (!lock->initialized)
     {
-      if (pthread_mutex_lock (&lock->guard) != 0)
-       abort ();
+      int err;
+
+      err = pthread_mutex_lock (&lock->guard);
+      if (err != 0)
+       return err;
       if (!lock->initialized)
-       glthread_rwlock_init (lock);
-      if (pthread_mutex_unlock (&lock->guard) != 0)
-       abort ();
+       {
+         err = glthread_rwlock_init_multithreaded (lock);
+         if (err != 0)
+           {
+             pthread_mutex_unlock (&lock->guard);
+             return err;
+           }
+       }
+      err = pthread_mutex_unlock (&lock->guard);
+      if (err != 0)
+       return err;
     }
-  if (pthread_rwlock_rdlock (&lock->rwlock) != 0)
-    abort ();
+  return pthread_rwlock_rdlock (&lock->rwlock);
 }
 
-void
-glthread_rwlock_wrlock (gl_rwlock_t *lock)
+int
+glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
 {
   if (!lock->initialized)
     {
-      if (pthread_mutex_lock (&lock->guard) != 0)
-       abort ();
+      int err;
+
+      err = pthread_mutex_lock (&lock->guard);
+      if (err != 0)
+       return err;
       if (!lock->initialized)
-       glthread_rwlock_init (lock);
-      if (pthread_mutex_unlock (&lock->guard) != 0)
-       abort ();
+       {
+         err = glthread_rwlock_init_multithreaded (lock);
+         if (err != 0)
+           {
+             pthread_mutex_unlock (&lock->guard);
+             return err;
+           }
+       }
+      err = pthread_mutex_unlock (&lock->guard);
+      if (err != 0)
+       return err;
     }
-  if (pthread_rwlock_wrlock (&lock->rwlock) != 0)
-    abort ();
+  return pthread_rwlock_wrlock (&lock->rwlock);
 }
 
-void
-glthread_rwlock_unlock (gl_rwlock_t *lock)
+int
+glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
 {
   if (!lock->initialized)
-    abort ();
-  if (pthread_rwlock_unlock (&lock->rwlock) != 0)
-    abort ();
+    return EINVAL;
+  return pthread_rwlock_unlock (&lock->rwlock);
 }
 
-void
-glthread_rwlock_destroy (gl_rwlock_t *lock)
+int
+glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
 {
+  int err;
+
   if (!lock->initialized)
-    abort ();
-  if (pthread_rwlock_destroy (&lock->rwlock) != 0)
-    abort ();
+    return EINVAL;
+  err = pthread_rwlock_destroy (&lock->rwlock);
+  if (err != 0)
+    return err;
   lock->initialized = 0;
+  return 0;
 }
 
 #  endif
 
 # else
 
-void
-glthread_rwlock_init (gl_rwlock_t *lock)
-{
-  if (pthread_mutex_init (&lock->lock, NULL) != 0)
-    abort ();
-  if (pthread_cond_init (&lock->waiting_readers, NULL) != 0)
-    abort ();
-  if (pthread_cond_init (&lock->waiting_writers, NULL) != 0)
-    abort ();
+int
+glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
+{
+  int err;
+
+  err = pthread_mutex_init (&lock->lock, NULL);
+  if (err != 0)
+    return err;
+  err = pthread_cond_init (&lock->waiting_readers, NULL);
+  if (err != 0)
+    return err;
+  err = pthread_cond_init (&lock->waiting_writers, NULL);
+  if (err != 0)
+    return err;
   lock->waiting_writers_count = 0;
   lock->runcount = 0;
+  return 0;
 }
 
-void
-glthread_rwlock_rdlock (gl_rwlock_t *lock)
+int
+glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
 {
-  if (pthread_mutex_lock (&lock->lock) != 0)
-    abort ();
+  int err;
+
+  err = pthread_mutex_lock (&lock->lock);
+  if (err != 0)
+    return err;
   /* Test whether only readers are currently running, and whether the runcount
      field will not overflow.  */
   /* POSIX says: "It is implementation-defined whether the calling thread
@@ -166,51 +202,70 @@ glthread_rwlock_rdlock (gl_rwlock_t *lock)
     {
       /* This thread has to wait for a while.  Enqueue it among the
         waiting_readers.  */
-      if (pthread_cond_wait (&lock->waiting_readers, &lock->lock) != 0)
-       abort ();
+      err = pthread_cond_wait (&lock->waiting_readers, &lock->lock);
+      if (err != 0)
+       {
+         pthread_mutex_unlock (&lock->lock);
+         return err;
+       }
     }
   lock->runcount++;
-  if (pthread_mutex_unlock (&lock->lock) != 0)
-    abort ();
+  return pthread_mutex_unlock (&lock->lock);
 }
 
-void
-glthread_rwlock_wrlock (gl_rwlock_t *lock)
+int
+glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
 {
-  if (pthread_mutex_lock (&lock->lock) != 0)
-    abort ();
+  int err;
+
+  err = pthread_mutex_lock (&lock->lock);
+  if (err != 0)
+    return err;
   /* Test whether no readers or writers are currently running.  */
   while (!(lock->runcount == 0))
     {
       /* This thread has to wait for a while.  Enqueue it among the
         waiting_writers.  */
       lock->waiting_writers_count++;
-      if (pthread_cond_wait (&lock->waiting_writers, &lock->lock) != 0)
-       abort ();
+      err = pthread_cond_wait (&lock->waiting_writers, &lock->lock);
+      if (err != 0)
+       {
+         lock->waiting_writers_count--;
+         pthread_mutex_unlock (&lock->lock);
+         return err;
+       }
       lock->waiting_writers_count--;
     }
   lock->runcount--; /* runcount becomes -1 */
-  if (pthread_mutex_unlock (&lock->lock) != 0)
-    abort ();
+  return pthread_mutex_unlock (&lock->lock);
 }
 
-void
-glthread_rwlock_unlock (gl_rwlock_t *lock)
+int
+glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
 {
-  if (pthread_mutex_lock (&lock->lock) != 0)
-    abort ();
+  int err;
+
+  err = pthread_mutex_lock (&lock->lock);
+  if (err != 0)
+    return err;
   if (lock->runcount < 0)
     {
       /* Drop a writer lock.  */
       if (!(lock->runcount == -1))
-       abort ();
+       {
+         pthread_mutex_unlock (&lock->lock);
+         return EINVAL;
+       }
       lock->runcount = 0;
     }
   else
     {
       /* Drop a reader lock.  */
       if (!(lock->runcount > 0))
-       abort ();
+       {
+         pthread_mutex_unlock (&lock->lock);
+         return EINVAL;
+       }
       lock->runcount--;
     }
   if (lock->runcount == 0)
@@ -220,29 +275,42 @@ glthread_rwlock_unlock (gl_rwlock_t *lock)
       if (lock->waiting_writers_count > 0)
        {
          /* Wake up one of the waiting writers.  */
-         if (pthread_cond_signal (&lock->waiting_writers) != 0)
-           abort ();
+         err = pthread_cond_signal (&lock->waiting_writers);
+         if (err != 0)
+           {
+             pthread_mutex_unlock (&lock->lock);
+             return err;
+           }
        }
       else
        {
          /* Wake up all waiting readers.  */
-         if (pthread_cond_broadcast (&lock->waiting_readers) != 0)
-           abort ();
+         err = pthread_cond_broadcast (&lock->waiting_readers);
+         if (err != 0)
+           {
+             pthread_mutex_unlock (&lock->lock);
+             return err;
+           }
        }
     }
-  if (pthread_mutex_unlock (&lock->lock) != 0)
-    abort ();
+  return pthread_mutex_unlock (&lock->lock);
 }
 
-void
-glthread_rwlock_destroy (gl_rwlock_t *lock)
+int
+glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
 {
-  if (pthread_mutex_destroy (&lock->lock) != 0)
-    abort ();
-  if (pthread_cond_destroy (&lock->waiting_readers) != 0)
-    abort ();
-  if (pthread_cond_destroy (&lock->waiting_writers) != 0)
-    abort ();
+  int err;
+
+  err = pthread_mutex_destroy (&lock->lock);
+  if (err != 0)
+    return err;
+  err = pthread_cond_destroy (&lock->waiting_readers);
+  if (err != 0)
+    return err;
+  err = pthread_cond_destroy (&lock->waiting_writers);
+  if (err != 0)
+    return err;
+  return 0;
 }
 
 # endif
@@ -253,123 +321,171 @@ glthread_rwlock_destroy (gl_rwlock_t *lock)
 
 #  if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
-void
-glthread_recursive_lock_init (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
 {
   pthread_mutexattr_t attributes;
+  int err;
 
-  if (pthread_mutexattr_init (&attributes) != 0)
-    abort ();
-  if (pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE) != 0)
-    abort ();
-  if (pthread_mutex_init (lock, &attributes) != 0)
-    abort ();
-  if (pthread_mutexattr_destroy (&attributes) != 0)
-    abort ();
+  err = pthread_mutexattr_init (&attributes);
+  if (err != 0)
+    return err;
+  err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutex_init (lock, &attributes);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutexattr_destroy (&attributes);
+  if (err != 0)
+    return err;
+  return 0;
 }
 
 #  else
 
-void
-glthread_recursive_lock_init (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
 {
   pthread_mutexattr_t attributes;
+  int err;
 
-  if (pthread_mutexattr_init (&attributes) != 0)
-    abort ();
-  if (pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE) != 0)
-    abort ();
-  if (pthread_mutex_init (&lock->recmutex, &attributes) != 0)
-    abort ();
-  if (pthread_mutexattr_destroy (&attributes) != 0)
-    abort ();
+  err = pthread_mutexattr_init (&attributes);
+  if (err != 0)
+    return err;
+  err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutex_init (&lock->recmutex, &attributes);
+  if (err != 0)
+    {
+      pthread_mutexattr_destroy (&attributes);
+      return err;
+    }
+  err = pthread_mutexattr_destroy (&attributes);
+  if (err != 0)
+    return ret;
   lock->initialized = 1;
+  return 0;
 }
 
-void
-glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
 {
   if (!lock->initialized)
     {
-      if (pthread_mutex_lock (&lock->guard) != 0)
-       abort ();
+      int err;
+
+      err = pthread_mutex_lock (&lock->guard);
+      if (err != 0)
+       return err;
       if (!lock->initialized)
-       glthread_recursive_lock_init (lock);
-      if (pthread_mutex_unlock (&lock->guard) != 0)
-       abort ();
+       {
+         err = glthread_recursive_lock_init_multithreaded (lock);
+         if (err != 0)
+           {
+             pthread_mutex_unlock (&lock->guard);
+             return err;
+           }
+       }
+      err = pthread_mutex_unlock (&lock->guard);
+      if (err != 0)
+       return err;
     }
-  if (pthread_mutex_lock (&lock->recmutex) != 0)
-    abort ();
+  return pthread_mutex_lock (&lock->recmutex);
 }
 
-void
-glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
 {
   if (!lock->initialized)
-    abort ();
-  if (pthread_mutex_unlock (&lock->recmutex) != 0)
-    abort ();
+    return EINVAL;
+  return pthread_mutex_unlock (&lock->recmutex);
 }
 
-void
-glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
 {
+  int err;
+
   if (!lock->initialized)
-    abort ();
-  if (pthread_mutex_destroy (&lock->recmutex) != 0)
-    abort ();
+    return EINVAL;
+  err = pthread_mutex_destroy (&lock->recmutex);
+  if (err != 0)
+    return err;
   lock->initialized = 0;
+  return 0;
 }
 
 #  endif
 
 # else
 
-void
-glthread_recursive_lock_init (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
 {
-  if (pthread_mutex_init (&lock->mutex, NULL) != 0)
-    abort ();
+  int err;
+
+  err = pthread_mutex_init (&lock->mutex, NULL);
+  if (err != 0)
+    return err;
   lock->owner = (pthread_t) 0;
   lock->depth = 0;
+  return 0;
 }
 
-void
-glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
 {
   pthread_t self = pthread_self ();
   if (lock->owner != self)
     {
-      if (pthread_mutex_lock (&lock->mutex) != 0)
-       abort ();
+      int err;
+
+      err = pthread_mutex_lock (&lock->mutex);
+      if (err != 0)
+       return err;
       lock->owner = self;
     }
   if (++(lock->depth) == 0) /* wraparound? */
-    abort ();
+    {
+      lock->depth--;
+      return EAGAIN;
+    }
+  return 0;
 }
 
-void
-glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
 {
   if (lock->owner != pthread_self ())
-    abort ();
+    return EPERM;
   if (lock->depth == 0)
-    abort ();
+    return EINVAL;
   if (--(lock->depth) == 0)
     {
       lock->owner = (pthread_t) 0;
-      if (pthread_mutex_unlock (&lock->mutex) != 0)
-       abort ();
+      return pthread_mutex_unlock (&lock->mutex);
     }
+  else
+    return 0;
 }
 
-void
-glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
 {
   if (lock->owner != (pthread_t) 0)
-    abort ();
-  if (pthread_mutex_destroy (&lock->mutex) != 0)
-    abort ();
+    return EBUSY;
+  return (pthread_mutex_destroy (&lock->mutex);
 }
 
 # endif
@@ -410,7 +526,7 @@ glthread_once_singlethreaded (pthread_once_t *once_control)
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
-void
+static void
 glthread_once_call (void *arg)
 {
   void (**gl_once_temp_addr) (void) = (void (**) (void)) arg;
@@ -418,6 +534,13 @@ glthread_once_call (void *arg)
   initfunction ();
 }
 
+int
+glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void))
+{
+  void (*temp) (void) = initfunction;
+  return (!pth_once (once_control, glthread_once_call, &temp) ? errno : 0);
+}
+
 int
 glthread_once_singlethreaded (pth_once_t *once_control)
 {
@@ -446,72 +569,87 @@ glthread_once_singlethreaded (pth_once_t *once_control)
 
 /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
-void
-glthread_recursive_lock_init (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
 {
-  if (mutex_init (&lock->mutex, USYNC_THREAD, NULL) != 0)
-    abort ();
+  int err;
+
+  err = mutex_init (&lock->mutex, USYNC_THREAD, NULL);
+  if (err != 0)
+    return err;
   lock->owner = (thread_t) 0;
   lock->depth = 0;
+  return 0;
 }
 
-void
-glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
 {
   thread_t self = thr_self ();
   if (lock->owner != self)
     {
-      if (mutex_lock (&lock->mutex) != 0)
-       abort ();
+      int err;
+
+      err = mutex_lock (&lock->mutex);
+      if (err != 0)
+       return err;
       lock->owner = self;
     }
   if (++(lock->depth) == 0) /* wraparound? */
-    abort ();
+    {
+      lock->depth--;
+      return EAGAIN;
+    }
+  return 0;
 }
 
-void
-glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
 {
   if (lock->owner != thr_self ())
-    abort ();
+    return EPERM;
   if (lock->depth == 0)
-    abort ();
+    return EINVAL;
   if (--(lock->depth) == 0)
     {
       lock->owner = (thread_t) 0;
-      if (mutex_unlock (&lock->mutex) != 0)
-       abort ();
+      return mutex_unlock (&lock->mutex);
     }
+  else
+    return 0;
 }
 
-void
-glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
+int
+glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
 {
   if (lock->owner != (thread_t) 0)
-    abort ();
-  if (mutex_destroy (&lock->mutex) != 0)
-    abort ();
+    return EBUSY;
+  return mutex_destroy (&lock->mutex);
 }
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
-void
-glthread_once (gl_once_t *once_control, void (*initfunction) (void))
+int
+glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void))
 {
   if (!once_control->inited)
     {
+      int err;
+
       /* Use the mutex to guarantee that if another thread is already calling
         the initfunction, this thread waits until it's finished.  */
-      if (mutex_lock (&once_control->mutex) != 0)
-       abort ();
+      err = mutex_lock (&once_control->mutex);
+      if (err != 0)
+       return err;
       if (!once_control->inited)
        {
          once_control->inited = 1;
          initfunction ();
        }
-      if (mutex_unlock (&once_control->mutex) != 0)
-       abort ();
+      return mutex_unlock (&once_control->mutex);
     }
+  else
+    return 0;
 }
 
 int
@@ -537,13 +675,13 @@ glthread_once_singlethreaded (gl_once_t *once_control)
 /* -------------------------- gl_lock_t datatype -------------------------- */
 
 void
-glthread_lock_init (gl_lock_t *lock)
+glthread_lock_init_func (gl_lock_t *lock)
 {
   InitializeCriticalSection (&lock->lock);
   lock->guard.done = 1;
 }
 
-void
+int
 glthread_lock_lock (gl_lock_t *lock)
 {
   if (!lock->guard.done)
@@ -558,23 +696,26 @@ glthread_lock_lock (gl_lock_t *lock)
          Sleep (0);
     }
   EnterCriticalSection (&lock->lock);
+  return 0;
 }
 
-void
+int
 glthread_lock_unlock (gl_lock_t *lock)
 {
   if (!lock->guard.done)
-    abort ();
+    return EINVAL;
   LeaveCriticalSection (&lock->lock);
+  return 0;
 }
 
-void
+int
 glthread_lock_destroy (gl_lock_t *lock)
 {
   if (!lock->guard.done)
-    abort ();
+    return EINVAL;
   DeleteCriticalSection (&lock->lock);
   lock->guard.done = 0;
+  return 0;
 }
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
@@ -666,7 +807,7 @@ gl_waitqueue_notify_all (gl_waitqueue_t *wq)
 }
 
 void
-glthread_rwlock_init (gl_rwlock_t *lock)
+glthread_rwlock_init_func (gl_rwlock_t *lock)
 {
   InitializeCriticalSection (&lock->lock);
   gl_waitqueue_init (&lock->waiting_readers);
@@ -675,7 +816,7 @@ glthread_rwlock_init (gl_rwlock_t *lock)
   lock->guard.done = 1;
 }
 
-void
+int
 glthread_rwlock_rdlock (gl_rwlock_t *lock)
 {
   if (!lock->guard.done)
@@ -710,7 +851,7 @@ glthread_rwlock_rdlock (gl_rwlock_t *lock)
             removed us from the waiting_readers, incremented lock->runcount.  */
          if (!(lock->runcount > 0))
            abort ();
-         return;
+         return 0;
        }
       else
        {
@@ -726,9 +867,10 @@ glthread_rwlock_rdlock (gl_rwlock_t *lock)
     }
   lock->runcount++;
   LeaveCriticalSection (&lock->lock);
+  return 0;
 }
 
-void
+int
 glthread_rwlock_wrlock (gl_rwlock_t *lock)
 {
   if (!lock->guard.done)
@@ -762,7 +904,7 @@ glthread_rwlock_wrlock (gl_rwlock_t *lock)
             removed us from the waiting_writers, set lock->runcount = -1.  */
          if (!(lock->runcount == -1))
            abort ();
-         return;
+         return 0;
        }
       else
        {
@@ -778,13 +920,14 @@ glthread_rwlock_wrlock (gl_rwlock_t *lock)
     }
   lock->runcount--; /* runcount becomes -1 */
   LeaveCriticalSection (&lock->lock);
+  return 0;
 }
 
-void
+int
 glthread_rwlock_unlock (gl_rwlock_t *lock)
 {
   if (!lock->guard.done)
-    abort ();
+    return EINVAL;
   EnterCriticalSection (&lock->lock);
   if (lock->runcount < 0)
     {
@@ -797,7 +940,10 @@ glthread_rwlock_unlock (gl_rwlock_t *lock)
     {
       /* Drop a reader lock.  */
       if (!(lock->runcount > 0))
-       abort ();
+       {
+         LeaveCriticalSection (&lock->lock);
+         return EPERM;
+       }
       lock->runcount--;
     }
   if (lock->runcount == 0)
@@ -818,27 +964,29 @@ glthread_rwlock_unlock (gl_rwlock_t *lock)
        }
     }
   LeaveCriticalSection (&lock->lock);
+  return 0;
 }
 
-void
+int
 glthread_rwlock_destroy (gl_rwlock_t *lock)
 {
   if (!lock->guard.done)
-    abort ();
+    return EINVAL;
   if (lock->runcount != 0)
-    abort ();
+    return EBUSY;
   DeleteCriticalSection (&lock->lock);
   if (lock->waiting_readers.array != NULL)
     free (lock->waiting_readers.array);
   if (lock->waiting_writers.array != NULL)
     free (lock->waiting_writers.array);
   lock->guard.done = 0;
+  return 0;
 }
 
 /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
 void
-glthread_recursive_lock_init (gl_recursive_lock_t *lock)
+glthread_recursive_lock_init_func (gl_recursive_lock_t *lock)
 {
   lock->owner = 0;
   lock->depth = 0;
@@ -846,7 +994,7 @@ glthread_recursive_lock_init (gl_recursive_lock_t *lock)
   lock->guard.done = 1;
 }
 
-void
+int
 glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
 {
   if (!lock->guard.done)
@@ -868,37 +1016,43 @@ glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
        lock->owner = self;
       }
     if (++(lock->depth) == 0) /* wraparound? */
-      abort ();
+      {
+       lock->depth--;
+       return EAGAIN;
+      }
   }
+  return 0;
 }
 
-void
+int
 glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
 {
   if (lock->owner != GetCurrentThreadId ())
-    abort ();
+    return EPERM;
   if (lock->depth == 0)
-    abort ();
+    return EINVAL;
   if (--(lock->depth) == 0)
     {
       lock->owner = 0;
       LeaveCriticalSection (&lock->lock);
     }
+  return 0;
 }
 
-void
+int
 glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
 {
   if (lock->owner != 0)
-    abort ();
+    return EBUSY;
   DeleteCriticalSection (&lock->lock);
   lock->guard.done = 0;
+  return 0;
 }
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
 void
-glthread_once (gl_once_t *once_control, void (*initfunction) (void))
+glthread_once_func (gl_once_t *once_control, void (*initfunction) (void))
 {
   if (once_control->inited <= 0)
     {
index 23a9d15e400807d45d8777c8c9f256b7d413bba1..bf13ba0dab38bbcd958f3be20981ef8a2470c459 100644 (file)
      Taking the lock:     gl_lock_lock (name);
      Releasing the lock:  gl_lock_unlock (name);
      De-initialization:   gl_lock_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:      err = glthread_lock_init (&name);
+     Taking the lock:     err = glthread_lock_lock (&name);
+     Releasing the lock:  err = glthread_lock_unlock (&name);
+     De-initialization:   err = glthread_lock_destroy (&name);
 
    Read-Write (non-recursive) locks:
      Type:                gl_rwlock_t
                           gl_rwlock_wrlock (name);
      Releasing the lock:  gl_rwlock_unlock (name);
      De-initialization:   gl_rwlock_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:      err = glthread_rwlock_init (&name);
+     Taking the lock:     err = glthread_rwlock_rdlock (&name);
+                          err = glthread_rwlock_wrlock (&name);
+     Releasing the lock:  err = glthread_rwlock_unlock (&name);
+     De-initialization:   err = glthread_rwlock_destroy (&name);
 
    Recursive locks:
      Type:                gl_recursive_lock_t
      Taking the lock:     gl_recursive_lock_lock (name);
      Releasing the lock:  gl_recursive_lock_unlock (name);
      De-initialization:   gl_recursive_lock_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:      err = glthread_recursive_lock_init (&name);
+     Taking the lock:     err = glthread_recursive_lock_lock (&name);
+     Releasing the lock:  err = glthread_recursive_lock_unlock (&name);
+     De-initialization:   err = glthread_recursive_lock_destroy (&name);
 
   Once-only execution:
      Type:                gl_once_t
      Initializer:         gl_once_define(extern, name)
      Execution:           gl_once (name, initfunction);
+   Equivalent functions with control of error handling:
+     Execution:           err = glthread_once (&name, initfunction);
 */
 
 
 #ifndef _LOCK_H
 #define _LOCK_H
 
+#include <errno.h>
+
 /* ========================================================================= */
 
 #if USE_POSIX_THREADS
@@ -147,34 +167,14 @@ typedef pthread_mutex_t gl_lock_t;
     STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer;
 # define gl_lock_initializer \
     PTHREAD_MUTEX_INITIALIZER
-# define gl_lock_init(NAME) \
-    do                                                                  \
-      {                                                                 \
-        if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) \
-          abort ();                                                     \
-      }                                                                 \
-    while (0)
-# define gl_lock_lock(NAME) \
-    do                                                            \
-      {                                                           \
-        if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) \
-          abort ();                                               \
-      }                                                           \
-    while (0)
-# define gl_lock_unlock(NAME) \
-    do                                                              \
-      {                                                             \
-        if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) \
-          abort ();                                                 \
-      }                                                             \
-    while (0)
-# define gl_lock_destroy(NAME) \
-    do                                                               \
-      {                                                              \
-        if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) \
-          abort ();                                                  \
-      }                                                              \
-    while (0)
+# define glthread_lock_init(LOCK) \
+    (pthread_in_use () ? pthread_mutex_init (LOCK, NULL) : 0)
+# define glthread_lock_lock(LOCK) \
+    (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
+# define glthread_lock_unlock(LOCK) \
+    (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
+# define glthread_lock_destroy(LOCK) \
+    (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
@@ -189,41 +189,16 @@ typedef pthread_rwlock_t gl_rwlock_t;
       STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer;
 #   define gl_rwlock_initializer \
       PTHREAD_RWLOCK_INITIALIZER
-#   define gl_rwlock_init(NAME) \
-      do                                                                   \
-        {                                                                  \
-          if (pthread_in_use () && pthread_rwlock_init (&NAME, NULL) != 0) \
-            abort ();                                                      \
-        }                                                                  \
-      while (0)
-#   define gl_rwlock_rdlock(NAME) \
-      do                                                               \
-        {                                                              \
-          if (pthread_in_use () && pthread_rwlock_rdlock (&NAME) != 0) \
-            abort ();                                                  \
-        }                                                              \
-      while (0)
-#   define gl_rwlock_wrlock(NAME) \
-      do                                                               \
-        {                                                              \
-          if (pthread_in_use () && pthread_rwlock_wrlock (&NAME) != 0) \
-            abort ();                                                  \
-        }                                                              \
-      while (0)
-#   define gl_rwlock_unlock(NAME) \
-      do                                                               \
-        {                                                              \
-          if (pthread_in_use () && pthread_rwlock_unlock (&NAME) != 0) \
-            abort ();                                                  \
-        }                                                              \
-      while (0)
-#   define gl_rwlock_destroy(NAME) \
-      do                                                                \
-        {                                                               \
-          if (pthread_in_use () && pthread_rwlock_destroy (&NAME) != 0) \
-            abort ();                                                   \
-        }                                                               \
-      while (0)
+#   define glthread_rwlock_init(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0)
+#   define glthread_rwlock_rdlock(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0)
+#   define glthread_rwlock_wrlock(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_wrlock (LOCK) : 0)
+#   define glthread_rwlock_unlock(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_unlock (LOCK) : 0)
+#   define glthread_rwlock_destroy(LOCK) \
+      (pthread_in_use () ? pthread_rwlock_destroy (LOCK) : 0)
 
 #  else
 
@@ -240,46 +215,21 @@ typedef struct
       STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 #   define gl_rwlock_initializer \
       { 0, PTHREAD_MUTEX_INITIALIZER }
-#   define gl_rwlock_init(NAME) \
-      do                                  \
-        {                                 \
-          if (pthread_in_use ())          \
-            glthread_rwlock_init (&NAME); \
-        }                                 \
-      while (0)
-#   define gl_rwlock_rdlock(NAME) \
-      do                                    \
-        {                                   \
-          if (pthread_in_use ())            \
-            glthread_rwlock_rdlock (&NAME); \
-        }                                   \
-      while (0)
-#   define gl_rwlock_wrlock(NAME) \
-      do                                    \
-        {                                   \
-          if (pthread_in_use ())            \
-            glthread_rwlock_wrlock (&NAME); \
-        }                                   \
-      while (0)
-#   define gl_rwlock_unlock(NAME) \
-      do                                    \
-        {                                   \
-          if (pthread_in_use ())            \
-            glthread_rwlock_unlock (&NAME); \
-        }                                   \
-      while (0)
-#   define gl_rwlock_destroy(NAME) \
-      do                                     \
-        {                                    \
-          if (pthread_in_use ())             \
-            glthread_rwlock_destroy (&NAME); \
-        }                                    \
-      while (0)
-extern void glthread_rwlock_init (gl_rwlock_t *lock);
-extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
+#   define glthread_rwlock_init(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_rdlock(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_wrlock(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_unlock(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
+#   define glthread_rwlock_destroy(LOCK) \
+      (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
 
 #  endif
 
@@ -300,46 +250,21 @@ typedef struct
     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 # define gl_rwlock_initializer \
     { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }
-# define gl_rwlock_init(NAME) \
-    do                                  \
-      {                                 \
-        if (pthread_in_use ())          \
-          glthread_rwlock_init (&NAME); \
-      }                                 \
-    while (0)
-# define gl_rwlock_rdlock(NAME) \
-    do                                    \
-      {                                   \
-        if (pthread_in_use ())            \
-          glthread_rwlock_rdlock (&NAME); \
-      }                                   \
-    while (0)
-# define gl_rwlock_wrlock(NAME) \
-    do                                    \
-      {                                   \
-        if (pthread_in_use ())            \
-          glthread_rwlock_wrlock (&NAME); \
-      }                                   \
-    while (0)
-# define gl_rwlock_unlock(NAME) \
-    do                                    \
-      {                                   \
-        if (pthread_in_use ())            \
-          glthread_rwlock_unlock (&NAME); \
-      }                                   \
-    while (0)
-# define gl_rwlock_destroy(NAME) \
-    do                                     \
-      {                                    \
-        if (pthread_in_use ())             \
-          glthread_rwlock_destroy (&NAME); \
-      }                                    \
-    while (0)
-extern void glthread_rwlock_init (gl_rwlock_t *lock);
-extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
+# define glthread_rwlock_init(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0)
+# define glthread_rwlock_rdlock(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_wrlock(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_unlock(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0)
+# define glthread_rwlock_destroy(LOCK) \
+    (pthread_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock);
 
 # endif
 
@@ -361,35 +286,15 @@ typedef pthread_mutex_t gl_recursive_lock_t;
 #    define gl_recursive_lock_initializer \
        PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 #   endif
-#   define gl_recursive_lock_init(NAME) \
-      do                                          \
-        {                                         \
-          if (pthread_in_use ())                  \
-            glthread_recursive_lock_init (&NAME); \
-        }                                         \
-      while (0)
-#   define gl_recursive_lock_lock(NAME) \
-      do                                                            \
-        {                                                           \
-          if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) \
-            abort ();                                               \
-        }                                                           \
-      while (0)
-#   define gl_recursive_lock_unlock(NAME) \
-      do                                                              \
-        {                                                             \
-          if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) \
-            abort ();                                                 \
-        }                                                             \
-      while (0)
-#   define gl_recursive_lock_destroy(NAME) \
-      do                                                               \
-        {                                                              \
-          if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) \
-            abort ();                                                  \
-        }                                                              \
-      while (0)
-extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
+#   define glthread_recursive_lock_init(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_lock(LOCK) \
+      (pthread_in_use () ? pthread_mutex_lock (LOCK) : 0)
+#   define glthread_recursive_lock_unlock(LOCK) \
+      (pthread_in_use () ? pthread_mutex_unlock (LOCK) : 0)
+#   define glthread_recursive_lock_destroy(LOCK) \
+      (pthread_in_use () ? pthread_mutex_destroy (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
 
 #  else
 
@@ -406,38 +311,18 @@ typedef struct
       STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 #   define gl_recursive_lock_initializer \
       { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }
-#   define gl_recursive_lock_init(NAME) \
-      do                                          \
-        {                                         \
-          if (pthread_in_use ())                  \
-            glthread_recursive_lock_init (&NAME); \
-        }                                         \
-      while (0)
-#   define gl_recursive_lock_lock(NAME) \
-      do                                          \
-        {                                         \
-          if (pthread_in_use ())                  \
-            glthread_recursive_lock_lock (&NAME); \
-        }                                         \
-      while (0)
-#   define gl_recursive_lock_unlock(NAME) \
-      do                                            \
-        {                                           \
-          if (pthread_in_use ())                    \
-            glthread_recursive_lock_unlock (&NAME); \
-        }                                           \
-      while (0)
-#   define gl_recursive_lock_destroy(NAME) \
-      do                                             \
-        {                                            \
-          if (pthread_in_use ())                     \
-            glthread_recursive_lock_destroy (&NAME); \
-        }                                            \
-      while (0)
-extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
+#   define glthread_recursive_lock_init(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_lock(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_unlock(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
+#   define glthread_recursive_lock_destroy(LOCK) \
+      (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
 
 #  endif
 
@@ -459,38 +344,18 @@ typedef struct
      STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 #  define gl_recursive_lock_initializer \
      { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }
-#  define gl_recursive_lock_init(NAME) \
-     do                                          \
-       {                                         \
-         if (pthread_in_use ())                  \
-           glthread_recursive_lock_init (&NAME); \
-       }                                         \
-     while (0)
-#  define gl_recursive_lock_lock(NAME) \
-     do                                          \
-       {                                         \
-         if (pthread_in_use ())                  \
-           glthread_recursive_lock_lock (&NAME); \
-       }                                         \
-     while (0)
-#  define gl_recursive_lock_unlock(NAME) \
-     do                                            \
-       {                                           \
-         if (pthread_in_use ())                    \
-           glthread_recursive_lock_unlock (&NAME); \
-       }                                           \
-     while (0)
-#  define gl_recursive_lock_destroy(NAME) \
-     do                                             \
-       {                                            \
-         if (pthread_in_use ())                     \
-           glthread_recursive_lock_destroy (&NAME); \
-       }                                            \
-     while (0)
-extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
+#  define glthread_recursive_lock_init(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_init_multithreaded (LOCK) : 0)
+#  define glthread_recursive_lock_lock(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_lock_multithreaded (LOCK) : 0)
+#  define glthread_recursive_lock_unlock(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_unlock_multithreaded (LOCK) : 0)
+#  define glthread_recursive_lock_destroy(LOCK) \
+     (pthread_in_use () ? glthread_recursive_lock_destroy_multithreaded (LOCK) : 0)
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
 
 # endif
 
@@ -499,21 +364,10 @@ extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 typedef pthread_once_t gl_once_t;
 # define gl_once_define(STORAGECLASS, NAME) \
     STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT;
-# define gl_once(NAME, INITFUNCTION) \
-    do                                                   \
-      {                                                  \
-        if (pthread_in_use ())                           \
-          {                                              \
-            if (pthread_once (&NAME, INITFUNCTION) != 0) \
-              abort ();                                  \
-          }                                              \
-        else                                             \
-          {                                              \
-            if (glthread_once_singlethreaded (&NAME))    \
-              INITFUNCTION ();                           \
-          }                                              \
-      }                                                  \
-    while (0)
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (pthread_in_use ()                                                         \
+     ? pthread_once (ONCE_CONTROL, INITFUNCTION)                               \
+     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
 extern int glthread_once_singlethreaded (pthread_once_t *once_control);
 
 # ifdef __cplusplus
@@ -565,29 +419,14 @@ typedef pth_mutex_t gl_lock_t;
     STORAGECLASS pth_mutex_t NAME = gl_lock_initializer;
 # define gl_lock_initializer \
     PTH_MUTEX_INIT
-# define gl_lock_init(NAME) \
-    do                                               \
-      {                                              \
-        if (pth_in_use() && !pth_mutex_init (&NAME)) \
-          abort ();                                  \
-      }                                              \
-    while (0)
-# define gl_lock_lock(NAME) \
-    do                                                           \
-      {                                                          \
-        if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) \
-          abort ();                                              \
-      }                                                          \
-    while (0)
-# define gl_lock_unlock(NAME) \
-    do                                                  \
-      {                                                 \
-        if (pth_in_use() && !pth_mutex_release (&NAME)) \
-          abort ();                                     \
-      }                                                 \
-    while (0)
-# define gl_lock_destroy(NAME) \
-    (void)(&NAME)
+# define glthread_lock_init(LOCK) \
+    (pth_in_use() && !pth_mutex_init (LOCK) ? errno : 0)
+# define glthread_lock_lock(LOCK) \
+    (pth_in_use() && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
+# define glthread_lock_unlock(LOCK) \
+    (pth_in_use() && !pth_mutex_release (LOCK) ? errno : 0)
+# define glthread_lock_destroy(LOCK) \
+    ((void)(LOCK), 0)
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
@@ -598,38 +437,16 @@ typedef pth_rwlock_t gl_rwlock_t;
      STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer;
 #  define gl_rwlock_initializer \
      PTH_RWLOCK_INIT
-#  define gl_rwlock_init(NAME) \
-     do                                                \
-       {                                               \
-         if (pth_in_use() && !pth_rwlock_init (&NAME)) \
-           abort ();                                   \
-       }                                               \
-     while (0)
-#  define gl_rwlock_rdlock(NAME) \
-     do                                                              \
-       {                                                             \
-         if (pth_in_use()                                            \
-             && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RD, 0, NULL)) \
-           abort ();                                                 \
-       }                                                             \
-     while (0)
-#  define gl_rwlock_wrlock(NAME) \
-     do                                                              \
-       {                                                             \
-         if (pth_in_use()                                            \
-             && !pth_rwlock_acquire (&NAME, PTH_RWLOCK_RW, 0, NULL)) \
-           abort ();                                                 \
-       }                                                             \
-     while (0)
-#  define gl_rwlock_unlock(NAME) \
-     do                                                   \
-       {                                                  \
-         if (pth_in_use() && !pth_rwlock_release (&NAME)) \
-           abort ();                                      \
-       }                                                  \
-     while (0)
-#  define gl_rwlock_destroy(NAME) \
-     (void)(&NAME)
+#  define glthread_rwlock_init(LOCK) \
+     (pth_in_use() && !pth_rwlock_init (LOCK) ? errno : 0)
+#  define glthread_rwlock_rdlock(LOCK) \
+     (pth_in_use() && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RD, 0, NULL) ? errno : 0)
+#  define glthread_rwlock_wrlock(LOCK) \
+     (pth_in_use() && !pth_rwlock_acquire (LOCK, PTH_RWLOCK_RW, 0, NULL) ? errno : 0)
+#  define glthread_rwlock_unlock(LOCK) \
+     (pth_in_use() && !pth_rwlock_release (LOCK) ? errno : 0)
+#  define glthread_rwlock_destroy(LOCK) \
+     ((void)(LOCK), 0)
 
 /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
@@ -641,52 +458,25 @@ typedef pth_mutex_t gl_recursive_lock_t;
      STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer;
 #  define gl_recursive_lock_initializer \
      PTH_MUTEX_INIT
-#  define gl_recursive_lock_init(NAME) \
-     do                                               \
-       {                                              \
-         if (pth_in_use() && !pth_mutex_init (&NAME)) \
-           abort ();                                  \
-       }                                              \
-     while (0)
-#  define gl_recursive_lock_lock(NAME) \
-     do                                                           \
-       {                                                          \
-         if (pth_in_use() && !pth_mutex_acquire (&NAME, 0, NULL)) \
-           abort ();                                              \
-       }                                                          \
-     while (0)
-#  define gl_recursive_lock_unlock(NAME) \
-     do                                                  \
-       {                                                 \
-         if (pth_in_use() && !pth_mutex_release (&NAME)) \
-           abort ();                                     \
-       }                                                 \
-     while (0)
-#  define gl_recursive_lock_destroy(NAME) \
-     (void)(&NAME)
+#  define glthread_recursive_lock_init(LOCK) \
+     (pth_in_use() && !pth_mutex_init (LOCK) ? errno : 0)
+#  define glthread_recursive_lock_lock(LOCK) \
+     (pth_in_use() && !pth_mutex_acquire (LOCK, 0, NULL) ? errno : 0)
+#  define glthread_recursive_lock_unlock(LOCK) \
+     (pth_in_use() && !pth_mutex_release (LOCK) ? errno : 0)
+#  define glthread_recursive_lock_destroy(LOCK) \
+     ((void)(LOCK), 0)
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
 typedef pth_once_t gl_once_t;
 # define gl_once_define(STORAGECLASS, NAME) \
     STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT;
-# define gl_once(NAME, INITFUNCTION) \
-    do                                                                \
-      {                                                               \
-        if (pth_in_use ())                                            \
-          {                                                           \
-            void (*gl_once_temp) (void) = INITFUNCTION;               \
-            if (!pth_once (&NAME, glthread_once_call, &gl_once_temp)) \
-              abort ();                                               \
-          }                                                           \
-        else                                                          \
-          {                                                           \
-            if (glthread_once_singlethreaded (&NAME))                 \
-              INITFUNCTION ();                                        \
-          }                                                           \
-      }                                                               \
-    while (0)
-extern void glthread_once_call (void *arg);
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (pth_in_use ()                                                             \
+     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
+     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
+extern int glthread_once_multithreaded (pth_once_t *once_control, void (*initfunction) (void));
 extern int glthread_once_singlethreaded (pth_once_t *once_control);
 
 # ifdef __cplusplus
@@ -742,34 +532,14 @@ typedef mutex_t gl_lock_t;
     STORAGECLASS mutex_t NAME = gl_lock_initializer;
 # define gl_lock_initializer \
     DEFAULTMUTEX
-# define gl_lock_init(NAME) \
-    do                                                                       \
-      {                                                                      \
-        if (thread_in_use () && mutex_init (&NAME, USYNC_THREAD, NULL) != 0) \
-          abort ();                                                          \
-      }                                                                      \
-    while (0)
-# define gl_lock_lock(NAME) \
-    do                                                   \
-      {                                                  \
-        if (thread_in_use () && mutex_lock (&NAME) != 0) \
-          abort ();                                      \
-      }                                                  \
-    while (0)
-# define gl_lock_unlock(NAME) \
-    do                                                     \
-      {                                                    \
-        if (thread_in_use () && mutex_unlock (&NAME) != 0) \
-          abort ();                                        \
-      }                                                    \
-    while (0)
-# define gl_lock_destroy(NAME) \
-    do                                                      \
-      {                                                     \
-        if (thread_in_use () && mutex_destroy (&NAME) != 0) \
-          abort ();                                         \
-      }                                                     \
-    while (0)
+# define glthread_lock_init(LOCK) \
+    (thread_in_use () ? mutex_init (LOCK, USYNC_THREAD, NULL) : 0)
+# define glthread_lock_lock(LOCK) \
+    (thread_in_use () ? mutex_lock (LOCK) : 0)
+# define glthread_lock_unlock(LOCK) \
+    (thread_in_use () ? mutex_unlock (LOCK) : 0)
+# define glthread_lock_destroy(LOCK) \
+    (thread_in_use () ? mutex_destroy (LOCK) : 0)
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
@@ -780,41 +550,16 @@ typedef rwlock_t gl_rwlock_t;
     STORAGECLASS rwlock_t NAME = gl_rwlock_initializer;
 # define gl_rwlock_initializer \
     DEFAULTRWLOCK
-# define gl_rwlock_init(NAME) \
-    do                                                                        \
-      {                                                                       \
-        if (thread_in_use () && rwlock_init (&NAME, USYNC_THREAD, NULL) != 0) \
-          abort ();                                                           \
-      }                                                                       \
-    while (0)
-# define gl_rwlock_rdlock(NAME) \
-    do                                                  \
-      {                                                 \
-        if (thread_in_use () && rw_rdlock (&NAME) != 0) \
-          abort ();                                     \
-      }                                                 \
-    while (0)
-# define gl_rwlock_wrlock(NAME) \
-    do                                                  \
-      {                                                 \
-        if (thread_in_use () && rw_wrlock (&NAME) != 0) \
-          abort ();                                     \
-      }                                                 \
-    while (0)
-# define gl_rwlock_unlock(NAME) \
-    do                                                  \
-      {                                                 \
-        if (thread_in_use () && rw_unlock (&NAME) != 0) \
-          abort ();                                     \
-      }                                                 \
-    while (0)
-# define gl_rwlock_destroy(NAME) \
-    do                                                       \
-      {                                                      \
-        if (thread_in_use () && rwlock_destroy (&NAME) != 0) \
-          abort ();                                          \
-      }                                                      \
-    while (0)
+# define glthread_rwlock_init(LOCK) \
+    (thread_in_use () ? rwlock_init (LOCK, USYNC_THREAD, NULL) : 0)
+# define glthread_rwlock_rdlock(LOCK) \
+    (thread_in_use () ? rw_rdlock (LOCK) : 0)
+# define glthread_rwlock_wrlock(LOCK) \
+    (thread_in_use () ? rw_wrlock (LOCK) : 0)
+# define glthread_rwlock_unlock(LOCK) \
+    (thread_in_use () ? rw_unlock (LOCK) : 0)
+# define glthread_rwlock_destroy(LOCK) \
+    (thread_in_use () ? rwlock_destroy (LOCK) : 0)
 
 /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
@@ -834,38 +579,38 @@ typedef struct
     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 # define gl_recursive_lock_initializer \
     { DEFAULTMUTEX, (thread_t) 0, 0 }
-# define gl_recursive_lock_init(NAME) \
+# define glthread_recursive_lock_init(LOCK) \
     do                                          \
       {                                         \
         if (thread_in_use ())                   \
-          glthread_recursive_lock_init (&NAME); \
+          glthread_recursive_lock_init_multithreaded (LOCK); \
       }                                         \
     while (0)
-# define gl_recursive_lock_lock(NAME) \
+# define glthread_recursive_lock_lock(LOCK) \
     do                                          \
       {                                         \
         if (thread_in_use ())                   \
-          glthread_recursive_lock_lock (&NAME); \
+          glthread_recursive_lock_lock_multithreaded (LOCK); \
       }                                         \
     while (0)
-# define gl_recursive_lock_unlock(NAME) \
+# define glthread_recursive_lock_unlock(LOCK) \
     do                                            \
       {                                           \
         if (thread_in_use ())                     \
-          glthread_recursive_lock_unlock (&NAME); \
+          glthread_recursive_lock_unlock_multithreaded (LOCK); \
       }                                           \
     while (0)
-# define gl_recursive_lock_destroy(NAME) \
+# define glthread_recursive_lock_destroy(LOCK) \
     do                                             \
       {                                            \
         if (thread_in_use ())                      \
-          glthread_recursive_lock_destroy (&NAME); \
+          glthread_recursive_lock_destroy_multithreaded (LOCK); \
       }                                            \
     while (0)
-extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock);
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
@@ -877,21 +622,11 @@ typedef struct
         gl_once_t;
 # define gl_once_define(STORAGECLASS, NAME) \
     STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX };
-# define gl_once(NAME, INITFUNCTION) \
-    do                                                \
-      {                                               \
-        if (thread_in_use ())                         \
-          {                                           \
-            glthread_once (&NAME, INITFUNCTION);      \
-          }                                           \
-        else                                          \
-          {                                           \
-            if (glthread_once_singlethreaded (&NAME)) \
-              INITFUNCTION ();                        \
-          }                                           \
-      }                                               \
-    while (0)
-extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (thread_in_use ()                                                          \
+     ? glthread_once_multithreaded (ONCE_CONTROL, INITFUNCTION)                \
+     : (glthread_once_singlethreaded (ONCE_CONTROL) ? (INITFUNCTION (), 0) : 0))
+extern int glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void));
 extern int glthread_once_singlethreaded (gl_once_t *once_control);
 
 # ifdef __cplusplus
@@ -937,18 +672,12 @@ typedef struct
     STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
 # define gl_lock_initializer \
     { { 0, -1 } }
-# define gl_lock_init(NAME) \
-    glthread_lock_init (&NAME)
-# define gl_lock_lock(NAME) \
-    glthread_lock_lock (&NAME)
-# define gl_lock_unlock(NAME) \
-    glthread_lock_unlock (&NAME)
-# define gl_lock_destroy(NAME) \
-    glthread_lock_destroy (&NAME)
-extern void glthread_lock_init (gl_lock_t *lock);
-extern void glthread_lock_lock (gl_lock_t *lock);
-extern void glthread_lock_unlock (gl_lock_t *lock);
-extern void glthread_lock_destroy (gl_lock_t *lock);
+# define glthread_lock_init(LOCK) \
+    (glthread_lock_init_func (LOCK), 0)
+extern void glthread_lock_init_func (gl_lock_t *lock);
+extern int glthread_lock_lock (gl_lock_t *lock);
+extern int glthread_lock_unlock (gl_lock_t *lock);
+extern int glthread_lock_destroy (gl_lock_t *lock);
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
@@ -979,21 +708,13 @@ typedef struct
     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 # define gl_rwlock_initializer \
     { { 0, -1 } }
-# define gl_rwlock_init(NAME) \
-    glthread_rwlock_init (&NAME)
-# define gl_rwlock_rdlock(NAME) \
-    glthread_rwlock_rdlock (&NAME)
-# define gl_rwlock_wrlock(NAME) \
-    glthread_rwlock_wrlock (&NAME)
-# define gl_rwlock_unlock(NAME) \
-    glthread_rwlock_unlock (&NAME)
-# define gl_rwlock_destroy(NAME) \
-    glthread_rwlock_destroy (&NAME)
-extern void glthread_rwlock_init (gl_rwlock_t *lock);
-extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_unlock (gl_rwlock_t *lock);
-extern void glthread_rwlock_destroy (gl_rwlock_t *lock);
+# define glthread_rwlock_init(LOCK) \
+    (glthread_rwlock_init_func (LOCK), 0)
+extern void glthread_rwlock_init_func (gl_rwlock_t *lock);
+extern int glthread_rwlock_rdlock (gl_rwlock_t *lock);
+extern int glthread_rwlock_wrlock (gl_rwlock_t *lock);
+extern int glthread_rwlock_unlock (gl_rwlock_t *lock);
+extern int glthread_rwlock_destroy (gl_rwlock_t *lock);
 
 /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
@@ -1015,18 +736,12 @@ typedef struct
     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 # define gl_recursive_lock_initializer \
     { { 0, -1 }, 0, 0 }
-# define gl_recursive_lock_init(NAME) \
-    glthread_recursive_lock_init (&NAME)
-# define gl_recursive_lock_lock(NAME) \
-    glthread_recursive_lock_lock (&NAME)
-# define gl_recursive_lock_unlock(NAME) \
-    glthread_recursive_lock_unlock (&NAME)
-# define gl_recursive_lock_destroy(NAME) \
-    glthread_recursive_lock_destroy (&NAME)
-extern void glthread_recursive_lock_init (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
-extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
+# define glthread_recursive_lock_init(LOCK) \
+    (glthread_recursive_lock_init_func (LOCK), 0)
+extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_lock (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_unlock (gl_recursive_lock_t *lock);
+extern int glthread_recursive_lock_destroy (gl_recursive_lock_t *lock);
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
@@ -1039,9 +754,9 @@ typedef struct
         gl_once_t;
 # define gl_once_define(STORAGECLASS, NAME) \
     STORAGECLASS gl_once_t NAME = { -1, -1 };
-# define gl_once(NAME, INITFUNCTION) \
-    glthread_once (&NAME, INITFUNCTION)
-extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void));
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
+extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));
 
 # ifdef __cplusplus
 }
@@ -1060,50 +775,156 @@ extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void))
 typedef int gl_lock_t;
 # define gl_lock_define(STORAGECLASS, NAME)
 # define gl_lock_define_initialized(STORAGECLASS, NAME)
-# define gl_lock_init(NAME)
-# define gl_lock_lock(NAME)
-# define gl_lock_unlock(NAME)
-# define gl_lock_destroy(NAME)
+# define glthread_lock_init(NAME) 0
+# define glthread_lock_lock(NAME) 0
+# define glthread_lock_unlock(NAME) 0
+# define glthread_lock_destroy(NAME) 0
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
 typedef int gl_rwlock_t;
 # define gl_rwlock_define(STORAGECLASS, NAME)
 # define gl_rwlock_define_initialized(STORAGECLASS, NAME)
-# define gl_rwlock_init(NAME)
-# define gl_rwlock_rdlock(NAME)
-# define gl_rwlock_wrlock(NAME)
-# define gl_rwlock_unlock(NAME)
-# define gl_rwlock_destroy(NAME)
+# define glthread_rwlock_init(NAME) 0
+# define glthread_rwlock_rdlock(NAME) 0
+# define glthread_rwlock_wrlock(NAME) 0
+# define glthread_rwlock_unlock(NAME) 0
+# define glthread_rwlock_destroy(NAME) 0
 
 /* --------------------- gl_recursive_lock_t datatype --------------------- */
 
 typedef int gl_recursive_lock_t;
 # define gl_recursive_lock_define(STORAGECLASS, NAME)
 # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME)
-# define gl_recursive_lock_init(NAME)
-# define gl_recursive_lock_lock(NAME)
-# define gl_recursive_lock_unlock(NAME)
-# define gl_recursive_lock_destroy(NAME)
+# define glthread_recursive_lock_init(NAME) 0
+# define glthread_recursive_lock_lock(NAME) 0
+# define glthread_recursive_lock_unlock(NAME) 0
+# define glthread_recursive_lock_destroy(NAME) 0
 
 /* -------------------------- gl_once_t datatype -------------------------- */
 
 typedef int gl_once_t;
 # define gl_once_define(STORAGECLASS, NAME) \
     STORAGECLASS gl_once_t NAME = 0;
-# define gl_once(NAME, INITFUNCTION) \
-    do                       \
-      {                      \
-        if (NAME == 0)       \
-          {                  \
-            NAME = ~ 0;      \
-            INITFUNCTION (); \
-          }                  \
-      }                      \
-    while (0)
+# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
+    (*(ONCE_CONTROL) == 0 ? (*(ONCE_CONTROL) = ~ 0, INITFUNCTION (), 0) : 0)
 
 #endif
 
 /* ========================================================================= */
 
+/* Macros with built-in error handling.  */
+
+/* -------------------------- gl_lock_t datatype -------------------------- */
+
+#define gl_lock_init(NAME) \
+   do                                  \
+     {                                 \
+       if (glthread_lock_init (&NAME)) \
+         abort ();                     \
+     }                                 \
+   while (0)
+#define gl_lock_lock(NAME) \
+   do                                  \
+     {                                 \
+       if (glthread_lock_lock (&NAME)) \
+         abort ();                     \
+     }                                 \
+   while (0)
+#define gl_lock_unlock(NAME) \
+   do                                    \
+     {                                   \
+       if (glthread_lock_unlock (&NAME)) \
+         abort ();                       \
+     }                                   \
+   while (0)
+#define gl_lock_destroy(NAME) \
+   do                                     \
+     {                                    \
+       if (glthread_lock_destroy (&NAME)) \
+         abort ();                        \
+     }                                    \
+   while (0)
+
+/* ------------------------- gl_rwlock_t datatype ------------------------- */
+
+#define gl_rwlock_init(NAME) \
+   do                                    \
+     {                                   \
+       if (glthread_rwlock_init (&NAME)) \
+         abort ();                       \
+     }                                   \
+   while (0)
+#define gl_rwlock_rdlock(NAME) \
+   do                                      \
+     {                                     \
+       if (glthread_rwlock_rdlock (&NAME)) \
+         abort ();                         \
+     }                                     \
+   while (0)
+#define gl_rwlock_wrlock(NAME) \
+   do                                      \
+     {                                     \
+       if (glthread_rwlock_wrlock (&NAME)) \
+         abort ();                         \
+     }                                     \
+   while (0)
+#define gl_rwlock_unlock(NAME) \
+   do                                      \
+     {                                     \
+       if (glthread_rwlock_unlock (&NAME)) \
+         abort ();                         \
+     }                                     \
+   while (0)
+#define gl_rwlock_destroy(NAME) \
+   do                                       \
+     {                                      \
+       if (glthread_rwlock_destroy (&NAME)) \
+         abort ();                          \
+     }                                      \
+   while (0)
+
+/* --------------------- gl_recursive_lock_t datatype --------------------- */
+
+#define gl_recursive_lock_init(NAME) \
+   do                                            \
+     {                                           \
+       if (glthread_recursive_lock_init (&NAME)) \
+         abort ();                               \
+     }                                           \
+   while (0)
+#define gl_recursive_lock_lock(NAME) \
+   do                                            \
+     {                                           \
+       if (glthread_recursive_lock_lock (&NAME)) \
+         abort ();                               \
+     }                                           \
+   while (0)
+#define gl_recursive_lock_unlock(NAME) \
+   do                                              \
+     {                                             \
+       if (glthread_recursive_lock_unlock (&NAME)) \
+         abort ();                                 \
+     }                                             \
+   while (0)
+#define gl_recursive_lock_destroy(NAME) \
+   do                                               \
+     {                                              \
+       if (glthread_recursive_lock_destroy (&NAME)) \
+         abort ();                                  \
+     }                                              \
+   while (0)
+
+/* -------------------------- gl_once_t datatype -------------------------- */
+
+#define gl_once(NAME, INITFUNCTION) \
+   do                                           \
+     {                                          \
+       if (glthread_once (&NAME, INITFUNCTION)) \
+         abort ();                              \
+     }                                          \
+   while (0)
+
+/* ========================================================================= */
+
 #endif /* _LOCK_H */