summaryrefslogtreecommitdiff
path: root/pthread_once.c
diff options
context:
space:
mode:
authorrpj <rpj>2005-03-16 01:32:06 +0000
committerrpj <rpj>2005-03-16 01:32:06 +0000
commit3d32060783bcaf10f38ff6eef6fcf5711bfeada4 (patch)
tree6878834ccd0e2408cbd1bf14a04c471aef66cff9 /pthread_once.c
parentedff26f320def7562009773ff8f258688d9860f6 (diff)
Only init_routine is cancellable
Diffstat (limited to 'pthread_once.c')
-rw-r--r--pthread_once.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/pthread_once.c b/pthread_once.c
index d27b49c..73fea33 100644
--- a/pthread_once.c
+++ b/pthread_once.c
@@ -41,10 +41,10 @@
static void
ptw32_once_init_routine_cleanup(void * arg)
{
- int oldCancelState;
pthread_once_t * once_control = (pthread_once_t *) arg;
- (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->done, (LONG)PTW32_ONCE_CANCELLED);
+ (void) pthread_mutex_lock(&ptw32_once_control.mtx);
+ once_control->done = PTW32_ONCE_CANCELLED;
(void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->started, -1L);
/*
* Wake everyone up.
@@ -52,7 +52,6 @@ ptw32_once_init_routine_cleanup(void * arg)
* Holding the mutex during the broadcast prevents threads being left
* behind waiting.
*/
- (void) pthread_mutex_lock(&ptw32_once_control.mtx);
(void) pthread_cond_broadcast(&ptw32_once_control.cond);
(void) pthread_mutex_unlock(&ptw32_once_control.mtx);
}
@@ -93,7 +92,6 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void))
*/
{
int result;
- int oldCancelState;
if (once_control == NULL || init_routine == NULL)
{
@@ -122,13 +120,15 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void))
* a change in the ABI, maintaining backwards compatibility.
*/
- while (!InterlockedExchangeAdd((LPLONG)&once_control->done, 0L) /* Full mem barrier read */
- & PTW32_ONCE_DONE)
+ while (!(InterlockedExchangeAdd((LPLONG)&once_control->done, 0L) /* Full mem barrier read */
+ & PTW32_ONCE_DONE))
{
if (PTW32_INTERLOCKED_EXCHANGE((LPLONG) &once_control->started, 0L) == -1)
{
/* In case the previous initter was cancelled, reset cancelled state */
- (void) PTW32_INTERLOCKED_EXCHANGE((LPLONG)&once_control->done, (LONG)PTW32_ONCE_CLEAR);
+ (void) pthread_mutex_lock(&ptw32_once_control.mtx);
+ once_control->done = PTW32_ONCE_CLEAR;
+ (void) pthread_mutex_unlock(&ptw32_once_control.mtx);
#ifdef _MSC_VER
#pragma inline_depth(0)
@@ -147,12 +147,14 @@ pthread_once (pthread_once_t * once_control, void (*init_routine) (void))
* behind waiting.
*/
(void) pthread_mutex_lock(&ptw32_once_control.mtx);
- once_control->done = PTW32_TRUE;
+ once_control->done = PTW32_ONCE_DONE;
(void) pthread_cond_broadcast(&ptw32_once_control.cond);
(void) pthread_mutex_unlock(&ptw32_once_control.mtx);
}
else
{
+ int oldCancelState;
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldCancelState);
(void) pthread_mutex_lock(&ptw32_once_control.mtx);
while (!once_control->done)