diff options
Diffstat (limited to 'mutex.c')
| -rw-r--r-- | mutex.c | 44 | 
1 files changed, 38 insertions, 6 deletions
| @@ -69,6 +69,15 @@ _mutex_check_need_init(pthread_mutex_t *mutex)      {        result = pthread_mutex_init(mutex, NULL);      } +  else if (*mutex == NULL) +    { +      /* +       * The mutex has been destroyed while we were waiting to +       * initialise it, so the operation that caused the +       * auto-initialisation should fail. +       */ +      result = EINVAL; +    }    LeaveCriticalSection(&_pthread_mutex_test_init_lock); @@ -177,13 +186,13 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)        return EINVAL;      } -  mx = *mutex; -    /*     * Check to see if we have something to delete.     */ -  if (mx != (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT) +  if (*mutex != (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)      { +      mx = *mutex; +        if (mx->mutex == 0)  	{  	  DeleteCriticalSection(&mx->cs); @@ -203,10 +212,33 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)    else      {        /* -       * This is all we need to do to destroy a statically -       * initialised mutex that has not yet been used (initialised). +       * See notes in _mutex_check_need_init() above also.         */ -      *mutex = NULL; +      EnterCriticalSection(&_pthread_mutex_test_init_lock); + +      /* +       * Check again. +       */ +      if (*mutex == (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT) +        { +          /* +           * This is all we need to do to destroy a statically +           * initialised mutex that has not yet been used (initialised). +           * If we get to here, another thread +           * waiting to initialise this mutex will get an EINVAL. +           */ +          *mutex = NULL; +        } +      else +        { +          /* +           * The mutex has been initialised while we were waiting +           * so assume it's in use. +           */ +          result = EBUSY; +        } + +      LeaveCriticalSection(&_pthread_mutex_test_init_lock);      }    return(result); | 
