bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lock module improvement


From: Bruno Haible
Subject: Re: Lock module improvement
Date: Sun, 3 Aug 2008 20:46:26 +0200
User-agent: KMail/1.5.4

Yoann Vandoorselaere wrote:
> >      Declaration:         gl_lock_define(extern, name)
> >      Initializer:         gl_lock_define_initialized(, name)
> >      Initialization:      gl_lock_init (name);
> >      Taking the lock:     gl_lock_lock (name);
> >      Releasing the lock:  gl_lock_unlock (name);
> >      De-initialization:   gl_lock_destroy (name);
> > 
> > What should be the names of the 4 inline functions?
> 
> In the current lock.c implementation, the glthread_ prefix is being
> used, so we could keep using this scheme, keeping the current gl_ prefix
> for macros, and using the following for inline function:
> 
> int glthread_lock_lock(name);
> int glthread_lock_unlock(name);
> int glthread_lock_destroy(name);

Sounds good. I'm applying this change.


2008-08-03  Bruno Haible  <address@hidden>

        Additional non-aborting API for lock and tls.
        * 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.
        * lib/tls.h: Include <errno.h>.
        (glthread_tls_key_init): New macro/function.
        (gl_tls_key_init): Define as wrapper around glthread_tls_key_init.
        (glthread_tls_set): New macro/function.
        (gl_tls_set): Define as wrapper around glthread_tls_set.
        (glthread_tls_key_destroy): New macro/function.
        (gl_tls_key_destroy): Define as wrapper around glthread_tls_key_destroy.
        Update function declarations.
        * lib/tls.c (glthread_tls_get_multithreaded): Renamed from
        glthread_tls_get.
        Suggested by Yoann Vandoorselaere <address@hidden>.

--- lib/lock.c.orig     2008-08-03 20:43:23.000000000 +0200
+++ lib/lock.c  2008-08-03 20:24:32.000000000 +0200
@@ -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 General Public License as published by
@@ -74,87 +74,123 @@
 
 #  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)
+int
+glthread_rwlock_init_multithreaded (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 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
@@ -165,51 +201,70 @@
     {
       /* 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)
@@ -219,29 +274,42 @@
       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
@@ -252,123 +320,171 @@
 
 #  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
@@ -409,7 +525,7 @@
 
 /* -------------------------- 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 @@
 }
 
 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)
 {
   /* We know that pth_once_t is an integer type.  */
@@ -445,72 +568,87 @@
 
 /* --------------------- 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
@@ -536,13 +674,13 @@
 /* -------------------------- 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)
@@ -557,23 +695,26 @@
          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 ------------------------- */
@@ -665,7 +806,7 @@
 }
 
 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);
@@ -674,7 +815,7 @@
   lock->guard.done = 1;
 }
 
-void
+int
 glthread_rwlock_rdlock (gl_rwlock_t *lock)
 {
   if (!lock->guard.done)
@@ -709,7 +850,7 @@
             removed us from the waiting_readers, incremented lock->runcount.  
*/
          if (!(lock->runcount > 0))
            abort ();
-         return;
+         return 0;
        }
       else
        {
@@ -725,9 +866,10 @@
     }
   lock->runcount++;
   LeaveCriticalSection (&lock->lock);
+  return 0;
 }
 
-void
+int
 glthread_rwlock_wrlock (gl_rwlock_t *lock)
 {
   if (!lock->guard.done)
@@ -761,7 +903,7 @@
             removed us from the waiting_writers, set lock->runcount = -1.  */
          if (!(lock->runcount == -1))
            abort ();
-         return;
+         return 0;
        }
       else
        {
@@ -777,13 +919,14 @@
     }
   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)
     {
@@ -796,7 +939,10 @@
     {
       /* Drop a reader lock.  */
       if (!(lock->runcount > 0))
-       abort ();
+       {
+         LeaveCriticalSection (&lock->lock);
+         return EPERM;
+       }
       lock->runcount--;
     }
   if (lock->runcount == 0)
@@ -817,27 +963,29 @@
        }
     }
   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;
@@ -845,7 +993,7 @@
   lock->guard.done = 1;
 }
 
-void
+int
 glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
 {
   if (!lock->guard.done)
@@ -867,37 +1015,43 @@
        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)
     {
--- lib/lock.h.orig     2008-08-03 20:43:23.000000000 +0200
+++ lib/lock.h  2008-08-03 20:19:08.000000000 +0200
@@ -31,6 +31,11 @@
      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
@@ -41,6 +46,12 @@
                           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
@@ -50,17 +61,26 @@
      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
@@ -146,34 +166,14 @@
     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 ------------------------- */
 
@@ -188,41 +188,16 @@
       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
 
@@ -239,46 +214,21 @@
       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
 
@@ -299,46 +249,21 @@
     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
 
@@ -360,35 +285,15 @@
 #    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
 
@@ -405,38 +310,18 @@
       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
 
@@ -458,38 +343,18 @@
      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
 
@@ -498,21 +363,10 @@
 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
@@ -564,29 +418,14 @@
     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 ------------------------- */
 
@@ -597,38 +436,16 @@
      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 --------------------- */
 
@@ -640,52 +457,25 @@
      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
@@ -741,34 +531,14 @@
     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 ------------------------- */
 
@@ -779,41 +549,16 @@
     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 --------------------- */
 
@@ -833,38 +578,38 @@
     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 -------------------------- */
 
@@ -876,21 +621,11 @@
         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
@@ -936,18 +671,12 @@
     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 ------------------------- */
 
@@ -978,21 +707,13 @@
     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 --------------------- */
 
@@ -1014,18 +735,12 @@
     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 -------------------------- */
 
@@ -1038,9 +753,9 @@
         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
 }
@@ -1059,50 +774,156 @@
 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 */
--- lib/tls.c.orig      2008-08-03 20:43:23.000000000 +0200
+++ lib/tls.c   2008-08-03 19:12:13.000000000 +0200
@@ -1,5 +1,5 @@
 /* Thread-local storage 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 General Public License as published by
@@ -41,7 +41,7 @@
 /* ------------------------- gl_tls_key_t datatype ------------------------- */
 
 void *
-glthread_tls_get (thread_key_t key)
+glthread_tls_get_multithreaded (thread_key_t key)
 {
   void *value;
 
--- lib/tls.h.orig      2008-08-03 20:43:23.000000000 +0200
+++ lib/tls.h   2008-08-03 19:35:05.000000000 +0200
@@ -20,11 +20,15 @@
    thread library.  It does not contain primitives for creating threads or
    for other multithreading primitives.
 
-   Type:                      gl_tls_key_t
-   Initialization:            gl_tls_key_init (name, destructor);
-   Getting per-thread value:  gl_tls_get (name)
-   Setting per-thread value:  gl_tls_set (name, pointer);
-   De-initialization:         gl_tls_key_destroy (name);
+     Type:                      gl_tls_key_t
+     Initialization:            gl_tls_key_init (name, destructor);
+     Getting per-thread value:  gl_tls_get (name)
+     Setting per-thread value:  gl_tls_set (name, pointer);
+     De-initialization:         gl_tls_key_destroy (name);
+   Equivalent functions with control of error handling:
+     Initialization:            err = glthread_tls_key_init (&name, 
destructor);
+     Setting per-thread value:  err = glthread_tls_set (&name, pointer);
+     De-initialization:         err = glthread_tls_key_destroy (&name);
 
    A per-thread value is of type 'void *'.
 
@@ -39,6 +43,8 @@
 #ifndef _TLS_H
 #define _TLS_H
 
+#include <errno.h>
+
 /* ========================================================================= */
 
 #if USE_POSIX_THREADS
@@ -90,41 +96,20 @@
           pthread_key_t key;
         }
         gl_tls_key_t;
-# define gl_tls_key_init(NAME, DESTRUCTOR) \
-    do                                                             \
-      {                                                            \
-        if (pthread_in_use ())                                     \
-          {                                                        \
-            if (pthread_key_create (&(NAME).key, DESTRUCTOR) != 0) \
-              abort ();                                            \
-          }                                                        \
-        else                                                       \
-          (NAME).singlethread_value = NULL;                        \
-      }                                                            \
-    while (0)
+# define glthread_tls_key_init(KEY, DESTRUCTOR) \
+    (pthread_in_use ()                              \
+     ? pthread_key_create (&(KEY)->key, DESTRUCTOR) \
+     : ((KEY)->singlethread_value = NULL, 0))
 # define gl_tls_get(NAME) \
     (pthread_in_use ()                  \
      ? pthread_getspecific ((NAME).key) \
      : (NAME).singlethread_value)
-# define gl_tls_set(NAME, POINTER) \
-    do                                                            \
-      {                                                           \
-        if (pthread_in_use ())                                    \
-          {                                                       \
-            if (pthread_setspecific ((NAME).key, (POINTER)) != 0) \
-              abort ();                                           \
-          }                                                       \
-        else                                                      \
-          (NAME).singlethread_value = (POINTER);                  \
-      }                                                           \
-    while (0)
-# define gl_tls_key_destroy(NAME) \
-    do                                                                 \
-      {                                                                \
-        if (pthread_in_use () && pthread_key_delete ((NAME).key) != 0) \
-          abort ();                                                    \
-      }                                                                \
-    while (0)
+# define glthread_tls_set(KEY, POINTER) \
+    (pthread_in_use ()                             \
+     ? pthread_setspecific ((KEY)->key, (POINTER)) \
+     : ((KEY)->singlethread_value = (POINTER), 0))
+# define glthread_tls_key_destroy(KEY) \
+    (pthread_in_use () ? pthread_key_delete ((KEY)->key) : 0)
 
 #endif
 
@@ -163,41 +148,22 @@
           pth_key_t key;
         }
         gl_tls_key_t;
-# define gl_tls_key_init(NAME, DESTRUCTOR) \
-    do                                                     \
-      {                                                    \
-        if (pth_in_use ())                                 \
-          {                                                \
-            if (!pth_key_create (&(NAME).key, DESTRUCTOR)) \
-              abort ();                                    \
-          }                                                \
-        else                                               \
-          (NAME).singlethread_value = NULL;                \
-      }                                                    \
-    while (0)
+# define glthread_tls_key_init(KEY, DESTRUCTOR) \
+    (pth_in_use ()                                             \
+     ? (!pth_key_create (&(KEY)->key, DESTRUCTOR) ? errno : 0) \
+     : ((KEY)->singlethread_value = NULL, 0))
 # define gl_tls_get(NAME) \
     (pth_in_use ()                  \
      ? pth_key_getdata ((NAME).key) \
      : (NAME).singlethread_value)
-# define gl_tls_set(NAME, POINTER) \
-    do                                                    \
-      {                                                   \
-        if (pth_in_use ())                                \
-          {                                               \
-            if (!pth_key_setdata ((NAME).key, (POINTER))) \
-              abort ();                                   \
-          }                                               \
-        else                                              \
-          (NAME).singlethread_value = (POINTER);          \
-      }                                                   \
-    while (0)
-# define gl_tls_key_destroy(NAME) \
-    do                                                     \
-      {                                                    \
-        if (pth_in_use () && !pth_key_delete ((NAME).key)) \
-          abort ();                                        \
-      }                                                    \
-    while (0)
+# define glthread_tls_set(KEY, POINTER) \
+    (pth_in_use ()                                            \
+     ? (!pth_key_setdata ((KEY)->key, (POINTER)) ? errno : 0) \
+     : ((KEY)->singlethread_value = (POINTER), 0))
+# define glthread_tls_key_destroy(KEY) \
+    (pth_in_use ()                                \
+     ? (!pth_key_delete ((KEY)->key) ? errno : 0) \
+     : 0)
 
 #endif
 
@@ -235,38 +201,22 @@
           thread_key_t key;
         }
         gl_tls_key_t;
-# define gl_tls_key_init(NAME, DESTRUCTOR) \
-    do                                                        \
-      {                                                       \
-        if (thread_in_use ())                                 \
-          {                                                   \
-            if (thr_keycreate (&(NAME).key, DESTRUCTOR) != 0) \
-              abort ();                                       \
-          }                                                   \
-        else                                                  \
-          (NAME).singlethread_value = NULL;                   \
-      }                                                       \
-    while (0)
+# define glthread_tls_key_init(KEY, DESTRUCTOR) \
+    (thread_in_use ()                          \
+     ? thr_keycreate (&(KEY)->key, DESTRUCTOR) \
+     : ((KEY)->singlethread_value = NULL, 0))
 # define gl_tls_get(NAME) \
     (thread_in_use ()                \
-     ? glthread_tls_get ((NAME).key) \
+     ? glthread_tls_get_multithreaded ((NAME).key) \
      : (NAME).singlethread_value)
-extern void *glthread_tls_get (thread_key_t key);
-# define gl_tls_set(NAME, POINTER) \
-    do                                                        \
-      {                                                       \
-        if (thread_in_use ())                                 \
-          {                                                   \
-            if (thr_setspecific ((NAME).key, (POINTER)) != 0) \
-              abort ();                                       \
-          }                                                   \
-        else                                                  \
-          (NAME).singlethread_value = (POINTER);              \
-      }                                                       \
-    while (0)
-# define gl_tls_key_destroy(NAME) \
+extern void *glthread_tls_get_multithreaded (thread_key_t key);
+# define glthread_tls_set(KEY, POINTER) \
+    (thread_in_use ()                              \
+     ? thr_setspecific ((KEY)->key, (POINTER))     \
+     : ((KEY)->singlethread_value = (POINTER), 0))
+# define glthread_tls_key_destroy(KEY) \
     /* Unsupported.  */ \
-    (void)0
+    0
 
 #endif
 
@@ -279,31 +229,15 @@
 /* ------------------------- gl_tls_key_t datatype ------------------------- */
 
 typedef DWORD gl_tls_key_t;
-# define gl_tls_key_init(NAME, DESTRUCTOR) \
+# define glthread_tls_key_init(KEY, DESTRUCTOR) \
     /* The destructor is unsupported.  */    \
-    do                                           \
-      {                                          \
-        if (((NAME) = TlsAlloc ()) == (DWORD)-1) \
-          abort ();                              \
-        (void) (DESTRUCTOR);                     \
-      }                                          \
-    while (0)
+    ((*(KEY) = TlsAlloc ()) == (DWORD)-1 ? EAGAIN : ((void) (DESTRUCTOR), 0))
 # define gl_tls_get(NAME) \
     TlsGetValue (NAME)
-# define gl_tls_set(NAME, POINTER) \
-    do                                    \
-      {                                   \
-        if (!TlsSetValue (NAME, POINTER)) \
-          abort ();                       \
-      }                                   \
-    while (0)
-# define gl_tls_key_destroy(NAME) \
-    do                       \
-      {                      \
-        if (!TlsFree (NAME)) \
-          abort ();          \
-      }                      \
-    while (0)
+# define glthread_tls_set(KEY, POINTER) \
+    (!TlsSetValue (*(KEY), POINTER) ? EINVAL : 0)
+# define glthread_tls_key_destroy(KEY) \
+    (!TlsFree (*(KEY)) ? EINVAL : 0)
 
 #endif
 
@@ -320,18 +254,47 @@
           void *singlethread_value;
         }
         gl_tls_key_t;
-# define gl_tls_key_init(NAME, DESTRUCTOR) \
-    ((NAME).singlethread_value = NULL, \
-     (void) (DESTRUCTOR))
+# define glthread_tls_key_init(KEY, DESTRUCTOR) \
+    ((KEY)->singlethread_value = NULL, \
+     (void) (DESTRUCTOR),              \
+     0)
 # define gl_tls_get(NAME) \
     (NAME).singlethread_value
-# define gl_tls_set(NAME, POINTER) \
-    (NAME).singlethread_value = (POINTER)
-# define gl_tls_key_destroy(NAME) \
-    (void)0
+# define glthread_tls_set(KEY, POINTER) \
+    ((KEY)->singlethread_value = (POINTER), 0)
+# define glthread_tls_key_destroy(KEY) \
+    0
 
 #endif
 
 /* ========================================================================= */
 
+/* Macros with built-in error handling.  */
+
+/* ------------------------- gl_tls_key_t datatype ------------------------- */
+
+#define gl_tls_key_init(NAME, DESTRUCTOR) \
+   do                                                 \
+     {                                                \
+       if (glthread_tls_key_init (&NAME, DESTRUCTOR)) \
+         abort ();                                    \
+     }                                                \
+   while (0)
+#define gl_tls_set(NAME, POINTER) \
+   do                                         \
+     {                                        \
+       if (glthread_tls_set (&NAME, POINTER)) \
+         abort ();                            \
+     }                                        \
+   while (0)
+#define gl_tls_key_destroy(NAME) \
+   do                                        \
+     {                                       \
+       if (glthread_tls_key_destroy (&NAME)) \
+         abort ();                           \
+     }                                       \
+   while (0)
+
+/* ========================================================================= */
+
 #endif /* _TLS_H */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]