summaryrefslogtreecommitdiff
path: root/locks/win32/thread_mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'locks/win32/thread_mutex.c')
-rw-r--r--locks/win32/thread_mutex.c23
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();
}