diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c index 839c7cace07..6e0332b3cd1 100644 --- a/dlls/ntdll/critsection.c +++ b/dlls/ntdll/critsection.c @@ -435,10 +435,12 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) */ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) { + LONGLONG timeout = NtCurrentTeb()->Peb->CriticalSectionTimeout.QuadPart / -10000000; for (;;) { EXCEPTION_RECORD rec; NTSTATUS status = wait_semaphore( crit, 5 ); + timeout -= 5; if ( status == STATUS_TIMEOUT ) { @@ -448,11 +450,14 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (60 sec)\n", crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) ); status = wait_semaphore( crit, 60 ); + timeout -= 60; + if ( status == STATUS_TIMEOUT && TRACE_ON(relay) ) { ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (5 min)\n", crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) ); status = wait_semaphore( crit, 300 ); + timeout -= 300; } } if (status == STATUS_WAIT_0) break; @@ -460,6 +465,9 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) /* Throw exception only for Wine internal locks */ if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[0])) continue; + /* only throw deadlock exception if configured timeout is reached */ + if (timeout > 0) continue; + rec.ExceptionCode = STATUS_POSSIBLE_DEADLOCK; rec.ExceptionFlags = 0; rec.ExceptionRecord = NULL;