summaryrefslogtreecommitdiff
path: root/condvar.c
diff options
context:
space:
mode:
authorrpj <rpj>1999-09-16 13:21:21 +0000
committerrpj <rpj>1999-09-16 13:21:21 +0000
commitf20ec5ec3497e7d1a8301d3c7ec6652dab1c3247 (patch)
treef7e2090fa5da2196b5bd4b575f1520b18051a0d0 /condvar.c
parent70597d7147b86dd972a803e185f05c0e7de80586 (diff)
Thu Sep 16 1999 Ross Johnson <rpj@swan.canberra.edu.au>
* 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.
Diffstat (limited to 'condvar.c')
-rw-r--r--condvar.c47
1 files changed, 43 insertions, 4 deletions
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);
}