diff options
-rw-r--r-- | pthread_once.c | 18 |
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) |