diff options
Diffstat (limited to 'locks/win32/thread_mutex.c')
-rw-r--r-- | locks/win32/thread_mutex.c | 23 |
1 files changed, 21 insertions, 2 deletions
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(); } |