/* 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
# 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
{
/* 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)
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
# 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
/* -------------------------- gl_once_t datatype -------------------------- */
-void
+static void
glthread_once_call (void *arg)
{
void (**gl_once_temp_addr) (void) = (void (**) (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)
{
/* --------------------- 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
/* -------------------------- 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)
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 ------------------------- */
}
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);
lock->guard.done = 1;
}
-void
+int
glthread_rwlock_rdlock (gl_rwlock_t *lock)
{
if (!lock->guard.done)
removed us from the waiting_readers, incremented lock->runcount. */
if (!(lock->runcount > 0))
abort ();
- return;
+ return 0;
}
else
{
}
lock->runcount++;
LeaveCriticalSection (&lock->lock);
+ return 0;
}
-void
+int
glthread_rwlock_wrlock (gl_rwlock_t *lock)
{
if (!lock->guard.done)
removed us from the waiting_writers, set lock->runcount = -1. */
if (!(lock->runcount == -1))
abort ();
- return;
+ return 0;
}
else
{
}
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)
{
{
/* Drop a reader lock. */
if (!(lock->runcount > 0))
- abort ();
+ {
+ LeaveCriticalSection (&lock->lock);
+ return EPERM;
+ }
lock->runcount--;
}
if (lock->runcount == 0)
}
}
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;
lock->guard.done = 1;
}
-void
+int
glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
{
if (!lock->guard.done)
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)
{
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
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 ------------------------- */
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
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
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
# 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
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
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
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
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 ------------------------- */
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 --------------------- */
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
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 ------------------------- */
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 --------------------- */
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 -------------------------- */
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
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 ------------------------- */
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 --------------------- */
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 -------------------------- */
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
}
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 */
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 *'.
#ifndef _TLS_H
#define _TLS_H
+#include <errno.h>
+
/* ========================================================================= */
#if USE_POSIX_THREADS
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
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
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
/* ------------------------- 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
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 */