diff options
author | Yann Ylavic <ylavic@apache.org> | 2019-03-21 00:15:29 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2019-03-21 00:15:29 +0000 |
commit | ad66715c981616c6ffba691620a191fdf89667ab (patch) | |
tree | c6c7675507da7843d2fad67f0491f8de1f67c6e7 /locks | |
parent | 0a2e61045a240e5b81f6e9817039df86505db116 (diff) | |
download | apr-ad66715c981616c6ffba691620a191fdf89667ab.tar.gz |
Merge r1792620 from trunk:
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/branches/1.7.x@1855960 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'locks')
-rw-r--r-- | locks/win32/proc_mutex.c | 23 | ||||
-rw-r--r-- | locks/win32/thread_cond.c | 31 | ||||
-rw-r--r-- | locks/win32/thread_mutex.c | 23 |
3 files changed, 67 insertions, 10 deletions
diff --git a/locks/win32/proc_mutex.c b/locks/win32/proc_mutex.c index d2fe2d450..e132e20a2 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(); } |