diff options
author | Yann Ylavic <ylavic@apache.org> | 2015-03-19 23:38:38 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2015-03-19 23:38:38 +0000 |
commit | 90c4770899c4c45288e1cd1cb0277324a7d3bdbf (patch) | |
tree | db6a0ab5bc8d6b81c56cd429c0b9bda4383c15ec /test/testlock.c | |
parent | c94867c4cd3211541e22b5a293ee96398c886e9c (diff) | |
download | apr-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.c | 73 |
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; |