summaryrefslogtreecommitdiff
path: root/locks
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2017-04-25 15:09:54 +0000
committerYann Ylavic <ylavic@apache.org>2017-04-25 15:09:54 +0000
commit3cae3e68b3aa6772f49879286810b6aa67ff8b15 (patch)
treed3ca24d334bf615caae9f1b867da6531348c5334 /locks
parent72eb2935f3712978c792bca33826eef6da25956c (diff)
downloadapr-3cae3e68b3aa6772f49879286810b6aa67ff8b15.tar.gz
locks: Windows: work around 64bit usecs to native 32bit msecs timeouts for
apr_{proc,thread}_{mutex,cond}_timed{lock,wait}(), such that the given timeout interval value is not truncated or switched from/to signed/unsigned. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1792620 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r--locks/win32/proc_mutex.c23
-rw-r--r--locks/win32/thread_cond.c31
-rw-r--r--locks/win32/thread_mutex.c23
3 files changed, 67 insertions, 10 deletions
diff --git a/locks/win32/proc_mutex.c b/locks/win32/proc_mutex.c
index 648c7a14d..2370bcc8e 100644
--- a/locks/win32/proc_mutex.c
+++ b/locks/win32/proc_mutex.c
@@ -167,9 +167,26 @@ APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
APR_DECLARE(apr_status_t) apr_proc_mutex_timedlock(apr_proc_mutex_t *mutex,
apr_interval_time_t timeout)
{
- DWORD rv, timeout_ms = (timeout <= 0) ? 0 : apr_time_as_msec(timeout);
-
- rv = WaitForSingleObject(mutex->handle, timeout_ms);
+ DWORD rv, timeout_ms = 0;
+ apr_interval_time_t t = timeout;
+
+ do {
+ if (t > 0) {
+ /* Given timeout is 64bit usecs whereas Windows timeouts are
+ * 32bit msecs and below INFINITE (2^32 - 1), so we may need
+ * multiple timed out waits...
+ */
+ if (t > apr_time_from_msec(INFINITE - 1)) {
+ timeout_ms = INFINITE - 1;
+ t -= apr_time_from_msec(INFINITE - 1);
+ }
+ else {
+ timeout_ms = (DWORD)apr_time_as_msec(t);
+ t = 0;
+ }
+ }
+ rv = WaitForSingleObject(mutex->handle, timeout_ms);
+ } while (rv == WAIT_TIMEOUT && t > 0);
if (rv == WAIT_TIMEOUT) {
return APR_TIMEUP;
diff --git a/locks/win32/thread_cond.c b/locks/win32/thread_cond.c
index b2ac1c8ff..d22567a88 100644
--- a/locks/win32/thread_cond.c
+++ b/locks/win32/thread_cond.c
@@ -63,12 +63,13 @@ APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond)
static APR_INLINE apr_status_t thread_cond_timedwait(apr_thread_cond_t *cond,
apr_thread_mutex_t *mutex,
- DWORD timeout_ms )
+ apr_interval_time_t timeout)
{
DWORD res;
apr_status_t rv;
unsigned int wake = 0;
unsigned long generation;
+ DWORD timeout_ms = 0;
EnterCriticalSection(&cond->csection);
cond->num_waiting++;
@@ -78,7 +79,28 @@ static APR_INLINE apr_status_t thread_cond_timedwait(apr_thread_cond_t *cond,
apr_thread_mutex_unlock(mutex);
do {
- res = WaitForSingleObject(cond->semaphore, timeout_ms);
+ apr_interval_time_t t = timeout;
+
+ do {
+ if (t < 0) {
+ timeout_ms = INFINITE;
+ }
+ else if (t > 0) {
+ /* Given timeout is 64bit usecs whereas Windows timeouts are
+ * 32bit msecs and below INFINITE (2^32 - 1), so we may need
+ * multiple timed out waits...
+ */
+ if (t > apr_time_from_msec(INFINITE - 1)) {
+ timeout_ms = INFINITE - 1;
+ t -= apr_time_from_msec(INFINITE - 1);
+ }
+ else {
+ timeout_ms = (DWORD)apr_time_as_msec(t);
+ t = 0;
+ }
+ }
+ res = WaitForSingleObject(mutex->handle, timeout_ms);
+ } while (res == WAIT_TIMEOUT && t > 0);
EnterCriticalSection(&cond->csection);
@@ -115,15 +137,14 @@ static APR_INLINE apr_status_t thread_cond_timedwait(apr_thread_cond_t *cond,
APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
apr_thread_mutex_t *mutex)
{
- return thread_cond_timedwait(cond, mutex, INFINITE);
+ return thread_cond_timedwait(cond, mutex, (apr_interval_time_t)-1);
}
APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
apr_thread_mutex_t *mutex,
apr_interval_time_t timeout)
{
- DWORD timeout_ms = (timeout >= 0) ? apr_time_as_msec(timeout) : INFINITE;
- return thread_cond_timedwait(cond, mutex, timeout_ms);
+ return thread_cond_timedwait(cond, mutex, timeout);
}
APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
diff --git a/locks/win32/thread_mutex.c b/locks/win32/thread_mutex.c
index 2eac69cdb..f19152495 100644
--- a/locks/win32/thread_mutex.c
+++ b/locks/win32/thread_mutex.c
@@ -118,8 +118,27 @@ APR_DECLARE(apr_status_t) apr_thread_mutex_timedlock(apr_thread_mutex_t *mutex,
apr_interval_time_t timeout)
{
if (mutex->type != thread_mutex_critical_section) {
- DWORD rv, timeout_ms = (timeout <= 0) ? 0 : apr_time_as_msec(timeout);
- rv = WaitForSingleObject(mutex->handle, timeout_ms);
+ DWORD rv, timeout_ms = 0;
+ apr_interval_time_t t = timeout;
+
+ do {
+ if (t > 0) {
+ /* Given timeout is 64bit usecs whereas Windows timeouts are
+ * 32bit msecs and below INFINITE (2^32 - 1), so we may need
+ * multiple timed out waits...
+ */
+ if (t > apr_time_from_msec(INFINITE - 1)) {
+ timeout_ms = INFINITE - 1;
+ t -= apr_time_from_msec(INFINITE - 1);
+ }
+ else {
+ timeout_ms = (DWORD)apr_time_as_msec(t);
+ t = 0;
+ }
+ }
+ rv = WaitForSingleObject(mutex->handle, timeout_ms);
+ } while (rv == WAIT_TIMEOUT && t > 0);
+
if ((rv != WAIT_OBJECT_0) && (rv != WAIT_ABANDONED)) {
return (rv == WAIT_TIMEOUT) ? APR_TIMEUP : apr_get_os_error();
}