diff options
Diffstat (limited to 'locks/unix/proc_mutex.c')
-rw-r--r-- | locks/unix/proc_mutex.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/locks/unix/proc_mutex.c b/locks/unix/proc_mutex.c index 4105ff3ef..5ac787f0c 100644 --- a/locks/unix/proc_mutex.c +++ b/locks/unix/proc_mutex.c @@ -174,6 +174,32 @@ static apr_status_t proc_mutex_posix_tryacquire(apr_proc_mutex_t *mutex) return APR_SUCCESS; } +static apr_status_t proc_mutex_posix_timedacquire(apr_proc_mutex_t *mutex, + apr_time_t timeout, + int absolute) +{ +#if HAVE_SEM_TIMEDWAIT + struct timespec abstime; + + if (!absolute) { + timeout += apr_time_now(); + } + abstime.tv_sec = apr_time_sec(timeout); + abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */ + + if (sem_timedwait(mutex->psem_interproc, &abstime) < 0) { + if (errno == ETIMEDOUT) { + return APR_TIMEUP; + } + return errno; + } + mutex->curr_locked = 1; + return APR_SUCCESS; +#else + return APR_ENOTIMPL; +#endif +} + static apr_status_t proc_mutex_posix_release(apr_proc_mutex_t *mutex) { mutex->curr_locked = 0; @@ -195,6 +221,7 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_posixsem_methods = proc_mutex_posix_create, proc_mutex_posix_acquire, proc_mutex_posix_tryacquire, + proc_mutex_posix_timedacquire, proc_mutex_posix_release, proc_mutex_posix_cleanup, proc_mutex_no_child_init, @@ -293,6 +320,37 @@ static apr_status_t proc_mutex_sysv_tryacquire(apr_proc_mutex_t *mutex) return APR_SUCCESS; } +static apr_status_t proc_mutex_sysv_timedacquire(apr_proc_mutex_t *mutex, + apr_time_t timeout, + int absolute) +{ +#if HAVE_SEMTIMEDOP + int rc; + struct timespec abstime; + + if (!absolute) { + timeout += apr_time_now(); + } + abstime.tv_sec = apr_time_sec(timeout); + abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */ + + do { + rc = semtimedop(mutex->interproc->filedes, &proc_mutex_op_on, 1, + &abstime); + } while (rc < 0 && errno == EINTR); + if (rc < 0) { + if (errno == EAGAIN) { + return APR_TIMEUP; + } + return errno; + } + mutex->curr_locked = 1; + return APR_SUCCESS; +#else + return APR_ENOTIMPL; +#endif +} + static apr_status_t proc_mutex_sysv_release(apr_proc_mutex_t *mutex) { int rc; @@ -335,6 +393,7 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_sysv_methods = proc_mutex_sysv_create, proc_mutex_sysv_acquire, proc_mutex_sysv_tryacquire, + proc_mutex_sysv_timedacquire, proc_mutex_sysv_release, proc_mutex_sysv_cleanup, proc_mutex_no_child_init, @@ -511,6 +570,43 @@ static apr_status_t proc_mutex_proc_pthread_tryacquire(apr_proc_mutex_t *mutex) return rv; } +static apr_status_t +proc_mutex_proc_pthread_timedacquire(apr_proc_mutex_t *mutex, + apr_time_t timeout, + int absolute) +{ + apr_status_t rv; + struct timespec abstime; + + if (!absolute) { + timeout += apr_time_now(); + } + abstime.tv_sec = apr_time_sec(timeout); + abstime.tv_nsec = apr_time_usec(timeout) * 1000; /* nanoseconds */ + + if ((rv = pthread_mutex_timedlock(mutex->pthread_interproc, &abstime))) { +#ifdef HAVE_ZOS_PTHREADS + rv = errno; +#endif + if (rv == ETIMEDOUT) { + return APR_TIMEUP; + } +#ifdef HAVE_PTHREAD_MUTEX_ROBUST + /* Okay, our owner died. Let's try to make it consistent again. */ + if (rv == EOWNERDEAD) { + pthread_mutex_consistent_np(mutex->pthread_interproc); + rv = APR_SUCCESS; + } + else + return rv; +#else + return rv; +#endif + } + mutex->curr_locked = 1; + return rv; +} + static apr_status_t proc_mutex_proc_pthread_release(apr_proc_mutex_t *mutex) { apr_status_t rv; @@ -531,6 +627,7 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_proc_pthread_methods = proc_mutex_proc_pthread_create, proc_mutex_proc_pthread_acquire, proc_mutex_proc_pthread_tryacquire, + proc_mutex_proc_pthread_timedacquire, proc_mutex_proc_pthread_release, proc_mutex_proc_pthread_cleanup, proc_mutex_no_child_init, @@ -642,6 +739,13 @@ static apr_status_t proc_mutex_fcntl_tryacquire(apr_proc_mutex_t *mutex) return APR_SUCCESS; } +static apr_status_t proc_mutex_fcntl_timedacquire(apr_proc_mutex_t *mutex, + apr_time_t timeout, + int absolute) +{ + return APR_ENOTIMPL; +} + static apr_status_t proc_mutex_fcntl_release(apr_proc_mutex_t *mutex) { int rc; @@ -682,6 +786,7 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_fcntl_methods = proc_mutex_fcntl_create, proc_mutex_fcntl_acquire, proc_mutex_fcntl_tryacquire, + proc_mutex_fcntl_timedacquire, proc_mutex_fcntl_release, proc_mutex_fcntl_cleanup, proc_mutex_no_child_init, @@ -773,6 +878,13 @@ static apr_status_t proc_mutex_flock_tryacquire(apr_proc_mutex_t *mutex) return APR_SUCCESS; } +static apr_status_t proc_mutex_flock_timedacquire(apr_proc_mutex_t *mutex, + apr_time_t timeout, + int absolute) +{ + return APR_ENOTIMPL; +} + static apr_status_t proc_mutex_flock_release(apr_proc_mutex_t *mutex) { int rc; @@ -837,6 +949,7 @@ static const apr_proc_mutex_unix_lock_methods_t mutex_flock_methods = proc_mutex_flock_create, proc_mutex_flock_acquire, proc_mutex_flock_tryacquire, + proc_mutex_flock_timedacquire, proc_mutex_flock_release, proc_mutex_flock_cleanup, proc_mutex_flock_child_init, @@ -910,6 +1023,21 @@ static apr_status_t proc_mutex_choose_method(apr_proc_mutex_t *new_mutex, apr_lo return APR_ENOTIMPL; #endif break; + case APR_LOCK_DEFAULT_TIMED: +#if APR_HAS_PROC_PTHREAD_SERIALIZE \ + && defined(HAVE_PTHREAD_MUTEX_ROBUST) \ + && defined(HAVE_PTHREAD_MUTEX_TIMEDLOCK) + new_mutex->inter_meth = &mutex_proc_pthread_methods; +#elif APR_HAS_SYSVSEM_SERIALIZE \ + && defined(HAVE_SEMTIMEDOP) + new_mutex->inter_meth = &mutex_sysv_methods; +#elif APR_HAS_POSIXSEM_SERIALIZE \ + && defined(HAVE_SEM_TIMEDWAIT) + new_mutex->inter_meth = &mutex_posixsem_methods; +#else + return APR_ENOTIMPL; +#endif + break; default: return APR_ENOTIMPL; } @@ -981,6 +1109,13 @@ APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex) return mutex->meth->tryacquire(mutex); } +APR_DECLARE(apr_status_t) apr_proc_mutex_timedlock(apr_proc_mutex_t *mutex, + apr_time_t timeout, + int absolute) +{ + return mutex->meth->timedacquire(mutex, timeout, absolute); +} + APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex) { return mutex->meth->release(mutex); |