summaryrefslogtreecommitdiff
path: root/locks
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2017-05-07 21:35:30 +0000
committerYann Ylavic <ylavic@apache.org>2017-05-07 21:35:30 +0000
commit23c9f000e96b133991a6518e629aa4d18fc0d0b6 (patch)
tree278e91fb321da52936150a853c31c111aec4d7bb /locks
parente8439b20e4ae98d27a6970fc48e6abe01dd494e4 (diff)
downloadapr-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.c22
-rw-r--r--locks/unix/thread_mutex.c44
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);