summaryrefslogtreecommitdiff
path: root/test/testlock.c
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2015-03-19 23:38:38 +0000
committerYann Ylavic <ylavic@apache.org>2015-03-19 23:38:38 +0000
commit90c4770899c4c45288e1cd1cb0277324a7d3bdbf (patch)
treedb6a0ab5bc8d6b81c56cd429c0b9bda4383c15ec /test/testlock.c
parentc94867c4cd3211541e22b5a293ee96398c886e9c (diff)
downloadapr-90c4770899c4c45288e1cd1cb0277324a7d3bdbf.tar.gz
locks: introduce apr_{thread,proc,global}_mutex_timedlock().
For proc mutexes, the new mechanism APR_LOCK_DEFAULT_TIMED usable at creation time allows for the best mechanism to be elected (unixes: 1 to 3, or specific: 4 to 7): 1. PROC_PTHREAD if pthread_mutex_timedlock() and pthread_mutex_set_robust_np() are both available, 2. SYSV if semtimedop() is availale, 3. POSIXSEM if sem_timedwait() is available, 4. BeOS' acquire_sem_etc() if available, 5. NetWare falls back to apr_thread_mutex_timedlock() as for others functions, 6. OS2's DosRequestMutexSem(), 7. Windows' WaitForSingleObject(). Otherwise (like when fcntl and flock only are availble, if that's ever possible), APR_ENOTIMPL is returned. For thread mutexes, the new flag APR_THREAD_MUTEX_TIMED, usable at create() time still, allows to switch to an implementation using a condition variable and apr_thread_cond_timedwait() when if no native mechanism is available (eg. NetWare, pthreads but without pthread_mutex_timedlock() available). On windows, this initializes a WaitForSingleObject()able handle (Mutex) instead of the fastest (but not timeout-able) CRITICAL_SECTION used by default. All apr_{thread,proc,global}_mutex_timedlock() functions can take a relative or absolute time, thanks to the last (boolean) argument. Test suite updated accordingly. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1667900 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testlock.c')
-rw-r--r--test/testlock.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/test/testlock.c b/test/testlock.c
index dddb52f76..a36720b84 100644
--- a/test/testlock.c
+++ b/test/testlock.c
@@ -90,7 +90,12 @@ static void *APR_THREAD_FUNC thread_mutex_function(apr_thread_t *thd, void *data
while (1)
{
- apr_thread_mutex_lock(thread_mutex);
+ if (data) {
+ apr_thread_mutex_timedlock(thread_mutex, *(apr_time_t *)data, 0);
+ }
+ else {
+ apr_thread_mutex_lock(thread_mutex);
+ }
if (i == MAX_ITER)
exitLoop = 0;
else
@@ -178,6 +183,38 @@ static void test_thread_mutex(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, MAX_ITER, x);
}
+static void test_thread_timedmutex(abts_case *tc, void *data)
+{
+ apr_thread_t *t1, *t2, *t3, *t4;
+ apr_status_t s1, s2, s3, s4;
+ apr_time_t timeout;
+
+ s1 = apr_thread_mutex_create(&thread_mutex, APR_THREAD_MUTEX_TIMED, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
+ ABTS_PTR_NOTNULL(tc, thread_mutex);
+
+ i = 0;
+ x = 0;
+
+ timeout = apr_time_from_sec(5);
+
+ s1 = apr_thread_create(&t1, NULL, thread_mutex_function, &timeout, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, s1);
+ s2 = apr_thread_create(&t2, NULL, thread_mutex_function, &timeout, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, s2);
+ s3 = apr_thread_create(&t3, NULL, thread_mutex_function, &timeout, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, s3);
+ s4 = apr_thread_create(&t4, NULL, thread_mutex_function, &timeout, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, s4);
+
+ apr_thread_join(&s1, t1);
+ apr_thread_join(&s2, t2);
+ apr_thread_join(&s3, t3);
+ apr_thread_join(&s4, t4);
+
+ ABTS_INT_EQUAL(tc, MAX_ITER, x);
+}
+
static void test_thread_rwlock(abts_case *tc, void *data)
{
apr_thread_t *t1, *t2, *t3, *t4;
@@ -305,6 +342,38 @@ static void test_timeoutcond(abts_case *tc, void *data)
apr_thread_cond_destroy(timeout_cond));
}
+static void test_timeoutmutex(abts_case *tc, void *data)
+{
+ apr_status_t s;
+ apr_time_t begin, end;
+ apr_time_t timeout;
+ int i;
+
+ s = apr_thread_mutex_create(&timeout_mutex, APR_THREAD_MUTEX_TIMED, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, s);
+ ABTS_PTR_NOTNULL(tc, timeout_mutex);
+
+ timeout = apr_time_from_sec(5);
+
+ ABTS_INT_EQUAL(tc, 0, apr_thread_mutex_lock(timeout_mutex));
+ for (i = 0; i < MAX_RETRY; i++) {
+ begin = apr_time_now();
+ s = apr_thread_mutex_timedlock(timeout_mutex, timeout, 0);
+ end = apr_time_now();
+
+ if (s != APR_SUCCESS && !APR_STATUS_IS_TIMEUP(s)) {
+ continue;
+ }
+ ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(s));
+ ABTS_ASSERT(tc, "Timer returned too late", end - begin - timeout < 100000);
+ break;
+ }
+ ABTS_ASSERT(tc, "Too many retries", i < MAX_RETRY);
+ ABTS_INT_EQUAL(tc, 0, apr_thread_mutex_unlock(timeout_mutex));
+ APR_ASSERT_SUCCESS(tc, "Unable to destroy the mutex",
+ apr_thread_mutex_destroy(timeout_mutex));
+}
+
#endif /* !APR_HAS_THREADS */
#if !APR_HAS_THREADS
@@ -323,9 +392,11 @@ abts_suite *testlock(abts_suite *suite)
abts_run_test(suite, threads_not_impl, NULL);
#else
abts_run_test(suite, test_thread_mutex, NULL);
+ abts_run_test(suite, test_thread_timedmutex, NULL);
abts_run_test(suite, test_thread_rwlock, NULL);
abts_run_test(suite, test_cond, NULL);
abts_run_test(suite, test_timeoutcond, NULL);
+ abts_run_test(suite, test_timeoutmutex, NULL);
#endif
return suite;