summaryrefslogtreecommitdiff
path: root/locks
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2017-05-07 20:44:59 +0000
committerYann Ylavic <ylavic@apache.org>2017-05-07 20:44:59 +0000
commitdffd37afe717dc568d59c76de3ddafe33ecfdf88 (patch)
treef014552943a96c1e99d1f7bd9bcffe63df35ff59 /locks
parent9313b5c24a282b93a2657f6f34b4285ac4efc28c (diff)
downloadapr-dffd37afe717dc568d59c76de3ddafe33ecfdf88.tar.gz
Merge r1792621, r1792622, r1792625 from trunk:
locks: unix: provide a macro helper for a pattern used several times. No functional change. locks: unix: timedlock: better handling of spurious wakeups that may be inherent to some native/OS condvar implementation. locks: unix: follow up to r1792622. Indent block previously preserved (for easier review), no functional change. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.6.x@1794259 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r--locks/unix/proc_mutex.c83
1 files changed, 45 insertions, 38 deletions
diff --git a/locks/unix/proc_mutex.c b/locks/unix/proc_mutex.c
index 3708b8eb0..863b07ab6 100644
--- a/locks/unix/proc_mutex.c
+++ b/locks/unix/proc_mutex.c
@@ -497,6 +497,8 @@ typedef struct {
apr_uint32_t cond_num_waiters;
#define proc_pthread_mutex_cond_num_waiters(m) \
(proc_pthread_cast(m)->cond_num_waiters)
+#define proc_pthread_mutex_is_cond(m) \
+ ((m)->pthread_refcounting && proc_pthread_mutex_cond_locked(m) != -1)
#endif /* APR_USE_PROC_PTHREAD_MUTEX_COND */
apr_uint32_t refcount;
#define proc_pthread_mutex_refcount(m) \
@@ -527,8 +529,7 @@ static apr_status_t proc_pthread_mutex_unref(void *mutex_)
apr_status_t rv;
#if APR_USE_PROC_PTHREAD_MUTEX_COND
- if (mutex->pthread_refcounting &&
- proc_pthread_mutex_cond_locked(mutex) != -1) {
+ if (proc_pthread_mutex_is_cond(mutex)) {
mutex->curr_locked = 0;
}
else
@@ -543,8 +544,7 @@ static apr_status_t proc_pthread_mutex_unref(void *mutex_)
}
if (!proc_pthread_mutex_dec(mutex)) {
#if APR_USE_PROC_PTHREAD_MUTEX_COND
- if (mutex->pthread_refcounting &&
- proc_pthread_mutex_cond_locked(mutex) != -1 &&
+ if (proc_pthread_mutex_is_cond(mutex) &&
(rv = pthread_cond_destroy(&proc_pthread_mutex_cond(mutex)))) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
@@ -690,8 +690,7 @@ static apr_status_t proc_mutex_pthread_acquire_ex(apr_proc_mutex_t *mutex,
apr_status_t rv;
#if APR_USE_PROC_PTHREAD_MUTEX_COND
- if (mutex->pthread_refcounting &&
- proc_pthread_mutex_cond_locked(mutex) != -1) {
+ if (proc_pthread_mutex_is_cond(mutex)) {
if ((rv = pthread_mutex_lock(&proc_pthread_mutex(mutex)))) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
@@ -708,48 +707,56 @@ static apr_status_t proc_mutex_pthread_acquire_ex(apr_proc_mutex_t *mutex,
}
if (!proc_pthread_mutex_cond_locked(mutex)) {
- proc_pthread_mutex_cond_locked(mutex) = 1;
+ rv = APR_SUCCESS;
}
else if (!timeout) {
rv = APR_TIMEUP;
}
else {
- proc_pthread_mutex_cond_num_waiters(mutex)++;
- if (timeout < 0) {
- rv = pthread_cond_wait(&proc_pthread_mutex_cond(mutex),
- &proc_pthread_mutex(mutex));
-#ifdef HAVE_ZOS_PTHREADS
- if (rv) {
- rv = errno;
- }
-#endif
- }
- else {
- struct timespec abstime;
+ struct timespec abstime;
+ if (timeout > 0) {
timeout += apr_time_now();
abstime.tv_sec = apr_time_sec(timeout);
abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */
+ }
- rv = pthread_cond_timedwait(&proc_pthread_mutex_cond(mutex),
- &proc_pthread_mutex(mutex),
- &abstime);
- if (rv) {
+ proc_pthread_mutex_cond_num_waiters(mutex)++;
+ do {
+ if (timeout < 0) {
+ rv = pthread_cond_wait(&proc_pthread_mutex_cond(mutex),
+ &proc_pthread_mutex(mutex));
+ if (rv) {
#ifdef HAVE_ZOS_PTHREADS
- rv = errno;
+ rv = errno;
#endif
- if (rv == ETIMEDOUT) {
- rv = APR_TIMEUP;
+ break;
}
}
- }
+ else {
+ rv = pthread_cond_timedwait(&proc_pthread_mutex_cond(mutex),
+ &proc_pthread_mutex(mutex),
+ &abstime);
+ if (rv) {
+#ifdef HAVE_ZOS_PTHREADS
+ rv = errno;
+#endif
+ if (rv == ETIMEDOUT) {
+ rv = APR_TIMEUP;
+ }
+ break;
+ }
+ }
+ } while (proc_pthread_mutex_cond_locked(mutex));
proc_pthread_mutex_cond_num_waiters(mutex)--;
}
- if (rv) {
+ if (rv != APR_SUCCESS) {
pthread_mutex_unlock(&proc_pthread_mutex(mutex));
return rv;
}
+ proc_pthread_mutex_cond_locked(mutex) = 1;
+
rv = pthread_mutex_unlock(&proc_pthread_mutex(mutex));
if (rv) {
#ifdef HAVE_ZOS_PTHREADS
@@ -841,8 +848,7 @@ static apr_status_t proc_mutex_pthread_release(apr_proc_mutex_t *mutex)
apr_status_t rv;
#if APR_USE_PROC_PTHREAD_MUTEX_COND
- if (mutex->pthread_refcounting &&
- proc_pthread_mutex_cond_locked(mutex) != -1) {
+ if (proc_pthread_mutex_is_cond(mutex)) {
if ((rv = pthread_mutex_lock(&proc_pthread_mutex(mutex)))) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
@@ -861,22 +867,23 @@ static apr_status_t proc_mutex_pthread_release(apr_proc_mutex_t *mutex)
if (!proc_pthread_mutex_cond_locked(mutex)) {
rv = APR_EINVAL;
}
- else if (proc_pthread_mutex_cond_num_waiters(mutex)) {
+ else if (!proc_pthread_mutex_cond_num_waiters(mutex)) {
+ rv = APR_SUCCESS;
+ }
+ else {
rv = pthread_cond_signal(&proc_pthread_mutex_cond(mutex));
- if (rv) {
#ifdef HAVE_ZOS_PTHREADS
+ if (rv) {
rv = errno;
-#endif
}
+#endif
}
- else {
- proc_pthread_mutex_cond_locked(mutex) = 0;
- rv = APR_SUCCESS;
- }
- if (rv) {
+ if (rv != APR_SUCCESS) {
pthread_mutex_unlock(&proc_pthread_mutex(mutex));
return rv;
}
+
+ proc_pthread_mutex_cond_locked(mutex) = 0;
}
#endif /* APR_USE_PROC_PTHREAD_MUTEX_COND */