diff options
author | Yann Ylavic <ylavic@apache.org> | 2017-05-07 20:44:59 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2017-05-07 20:44:59 +0000 |
commit | dffd37afe717dc568d59c76de3ddafe33ecfdf88 (patch) | |
tree | f014552943a96c1e99d1f7bd9bcffe63df35ff59 | |
parent | 9313b5c24a282b93a2657f6f34b4285ac4efc28c (diff) | |
download | apr-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
-rw-r--r-- | locks/unix/proc_mutex.c | 83 |
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 */ |