summaryrefslogtreecommitdiff
path: root/locks/unix/proc_mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'locks/unix/proc_mutex.c')
-rw-r--r--locks/unix/proc_mutex.c135
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);