From f20ec5ec3497e7d1a8301d3c7ec6652dab1c3247 Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 16 Sep 1999 13:21:21 +0000 Subject: Thu Sep 16 1999 Ross Johnson * rwlock.c (pthread_rwlock_destroy): Add serialisation. (_rwlock_check_need_init): Check for detroyed rwlock. * rwlock.c: Check return codes from _rwlock_check_need_init(); modify comments; serialise access to rwlock objects during operations; rename rw_mutex to rw_lock. * implement.h: Rename rw_mutex to rw_lock. * mutex.c (pthread_mutex_destroy): Add serialisation. (_mutex_check_need_init): Check for detroyed mutex. * condvar.c (pthread_cond_destroy): Add serialisation. (_cond_check_need_init): Check for detroyed condvar. * mutex.c: Modify comments. * condvar.c: Modify comments. --- condvar.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'condvar.c') diff --git a/condvar.c b/condvar.c index c84a32a..3f9a7df 100644 --- a/condvar.c +++ b/condvar.c @@ -65,6 +65,15 @@ _cond_check_need_init(pthread_cond_t *cond) { result = pthread_cond_init(cond, NULL); } + else if (*cond == NULL) + { + /* + * The cv has been destroyed while we were waiting to + * initialise it, so the operation that caused the + * auto-initialisation should fail. + */ + result = EINVAL; + } LeaveCriticalSection(&_pthread_cond_test_init_lock); @@ -455,10 +464,10 @@ pthread_cond_destroy (pthread_cond_t * cond) return EINVAL; } - cv = *cond; - - if (cv != (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT) + if (*cond != (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT) { + cv = *cond; + if (pthread_mutex_lock(&(cv->waitersLock)) != 0) { return EINVAL; @@ -476,9 +485,39 @@ pthread_cond_destroy (pthread_cond_t * cond) (void) pthread_mutex_destroy (&(cv->waitersLock)); free(cv); + *cond = NULL; } + else + { + /* + * See notes in _cond_check_need_init() above also. + */ + EnterCriticalSection(&_pthread_cond_test_init_lock); - *cond = NULL; + /* + * Check again. + */ + if (*cond == (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT) + { + /* + * This is all we need to do to destroy a statically + * initialised cond that has not yet been used (initialised). + * If we get to here, another thread + * waiting to initialise this cond will get an EINVAL. + */ + *cond = NULL; + } + else + { + /* + * The cv has been initialised while we were waiting + * so assume it's in use. + */ + result = EBUSY; + } + + LeaveCriticalSection(&_pthread_cond_test_init_lock); + } return (result); } -- cgit v1.2.3