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