diff options
author | Yann Ylavic <ylavic@apache.org> | 2017-05-07 21:35:30 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2017-05-07 21:35:30 +0000 |
commit | 23c9f000e96b133991a6518e629aa4d18fc0d0b6 (patch) | |
tree | 278e91fb321da52936150a853c31c111aec4d7bb /locks | |
parent | e8439b20e4ae98d27a6970fc48e6abe01dd494e4 (diff) | |
download | apr-23c9f000e96b133991a6518e629aa4d18fc0d0b6.tar.gz |
locks: thread: timedlock: better handling of spurious wakeups that may be
inherent to some native/OS condvar implementation.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1794266 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r-- | locks/netware/thread_mutex.c | 22 | ||||
-rw-r--r-- | locks/unix/thread_mutex.c | 44 |
2 files changed, 30 insertions, 36 deletions
diff --git a/locks/netware/thread_mutex.c b/locks/netware/thread_mutex.c index 9c2164278..435abebba 100644 --- a/locks/netware/thread_mutex.c +++ b/locks/netware/thread_mutex.c @@ -115,7 +115,8 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex, apr_interval_time_t timeout) { if (mutex->cond) { - apr_status_t rv; + apr_status_t rv = APR_SUCCESS; + NXLock(mutex->mutex); if (mutex->locked) { if (timeout <= 0) { @@ -123,13 +124,15 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex, } else { mutex->num_waiters++; - rv = apr_thread_cond_timedwait(mutex->cond, mutex, timeout); + do { + rv = apr_thread_cond_timedwait(mutex->cond, mutex, + timeout); + } while (rv == APR_SUCCESS && mutex->locked); mutex->num_waiters--; } } - else { + if (rv == APR_SUCCESS) { mutex->locked = 1; - rv = APR_SUCCESS; } NXUnlock(mutex->mutex); return rv; @@ -140,25 +143,24 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex, APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex) { + apr_status_t rv = APR_SUCCESS; + if (mutex->cond) { - apr_status_t rv; NXLock(mutex->mutex); + if (!mutex->locked) { rv = APR_EINVAL; } else if (mutex->num_waiters) { rv = apr_thread_cond_signal(mutex->cond); } - else { + if (rv == APR_SUCCESS) { mutex->locked = 0; - rv = APR_SUCCESS; } - NXUnlock(mutex->mutex); - return rv; } NXUnlock(mutex->mutex); - return APR_SUCCESS; + return rv; } APR_DECLARE(apr_status_t) apr_thread_mutex_destroy(apr_thread_mutex_t *mutex) diff --git a/locks/unix/thread_mutex.c b/locks/unix/thread_mutex.c index cf859e6ad..f027c791f 100644 --- a/locks/unix/thread_mutex.c +++ b/locks/unix/thread_mutex.c @@ -241,23 +241,26 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex, } else { mutex->num_waiters++; - rv = apr_thread_cond_timedwait(mutex->cond, mutex, timeout); + do { + rv = apr_thread_cond_timedwait(mutex->cond, mutex, + timeout); + if (rv) { #ifdef HAVE_ZOS_PTHREADS - if (rv) { - rv = errno; - } + rv = errno; #endif + break; + } + } while (mutex->locked); mutex->num_waiters--; } - } - else { - mutex->locked = 1; - } - if (rv) { - pthread_mutex_unlock(&mutex->mutex); - return rv; + if (rv) { + pthread_mutex_unlock(&mutex->mutex); + return rv; + } } + mutex->locked = 1; + rv = pthread_mutex_unlock(&mutex->mutex); if (rv) { #ifdef HAVE_ZOS_PTHREADS @@ -277,8 +280,6 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex) apr_status_t status; if (mutex->cond) { - apr_status_t stat2; - status = pthread_mutex_lock(&mutex->mutex); if (status) { #ifdef HAVE_ZOS_PTHREADS @@ -293,21 +294,12 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_unlock(apr_thread_mutex_t *mutex) else if (mutex->num_waiters) { status = apr_thread_cond_signal(mutex->cond); } - else { - mutex->locked = 0; - status = APR_SUCCESS; - } - - stat2 = pthread_mutex_unlock(&mutex->mutex); - if (stat2) { -#ifdef HAVE_ZOS_PTHREADS - status = errno; -#else - status = stat2; -#endif + if (status) { + pthread_mutex_unlock(&mutex->mutex); + return status; } - return status; + mutex->locked = 0; } status = pthread_mutex_unlock(&mutex->mutex); |