in locks/unix/proc_mutex.c [700:848]
static apr_status_t proc_mutex_pthread_acquire_ex(apr_proc_mutex_t *mutex,
apr_interval_time_t timeout)
{
apr_status_t rv;
#if APR_USE_PROC_PTHREAD_MUTEX_COND
if (proc_pthread_mutex_is_cond(mutex)) {
if ((rv = pthread_mutex_lock(&proc_pthread_mutex(mutex)))) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
#if defined(HAVE_PTHREAD_MUTEX_ROBUST) || defined(HAVE_PTHREAD_MUTEX_ROBUST_NP)
/* Okay, our owner died. Let's try to make it consistent again. */
if (rv == EOWNERDEAD) {
proc_pthread_mutex_dec(mutex);
#ifdef HAVE_PTHREAD_MUTEX_ROBUST
pthread_mutex_consistent(&proc_pthread_mutex(mutex));
#else
pthread_mutex_consistent_np(&proc_pthread_mutex(mutex));
#endif
}
else
#endif
return rv;
}
if (!proc_pthread_mutex_cond_locked(mutex)) {
rv = APR_SUCCESS;
}
else if (!timeout) {
rv = APR_TIMEUP;
}
else {
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 */
}
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;
#endif
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 != 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
rv = errno;
#endif
return rv;
}
}
else
#endif /* APR_USE_PROC_PTHREAD_MUTEX_COND */
{
if (timeout < 0) {
rv = pthread_mutex_lock(&proc_pthread_mutex(mutex));
if (rv) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
}
}
else if (!timeout) {
rv = pthread_mutex_trylock(&proc_pthread_mutex(mutex));
if (rv) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
if (rv == EBUSY) {
return APR_TIMEUP;
}
}
}
else
#if defined(HAVE_PTHREAD_MUTEX_TIMEDLOCK)
{
struct timespec abstime;
timeout += apr_time_now();
abstime.tv_sec = apr_time_sec(timeout);
abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */
rv = pthread_mutex_timedlock(&proc_pthread_mutex(mutex), &abstime);
if (rv) {
#ifdef HAVE_ZOS_PTHREADS
rv = errno;
#endif
if (rv == ETIMEDOUT) {
return APR_TIMEUP;
}
}
}
if (rv) {
#if defined(HAVE_PTHREAD_MUTEX_ROBUST) || defined(HAVE_PTHREAD_MUTEX_ROBUST_NP)
/* Okay, our owner died. Let's try to make it consistent again. */
if (rv == EOWNERDEAD) {
proc_pthread_mutex_dec(mutex);
#ifdef HAVE_PTHREAD_MUTEX_ROBUST
pthread_mutex_consistent(&proc_pthread_mutex(mutex));
#else
pthread_mutex_consistent_np(&proc_pthread_mutex(mutex));
#endif
}
else
#endif
return rv;
}
#else /* !HAVE_PTHREAD_MUTEX_TIMEDLOCK */
return proc_mutex_spinsleep_timedacquire(mutex, timeout);
#endif
}
mutex->curr_locked = 1;
return APR_SUCCESS;
}