diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 9142a03f123..8db2817025e 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -550,8 +550,8 @@ type win32 @ stub RtlpNtOpenKey @ stub RtlpNtQueryValueKey @ stub RtlpNtSetValueKey -@ stub RtlpUnWaitCriticalSection -@ stub RtlpWaitForCriticalSection +@ stdcall RtlpUnWaitCriticalSection(ptr) RtlpUnWaitCriticalSection +@ stdcall RtlpWaitForCriticalSection(ptr) RtlpWaitForCriticalSection @ stdcall RtlxAnsiStringToUnicodeSize(ptr) RtlAnsiStringToUnicodeSize @ stdcall RtlxOemStringToUnicodeSize(ptr) RtlOemStringToUnicodeSize @ stdcall RtlxUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize diff --git a/scheduler/critsection.c b/scheduler/critsection.c index 41718617ddc..8c2c4bfd4e5 100644 --- a/scheduler/critsection.c +++ b/scheduler/critsection.c @@ -64,6 +64,50 @@ void WINAPI DeleteCriticalSection( CRITICAL_SECTION *crit ) } +/*********************************************************************** + * RtlpWaitForCriticalSection (NTDLL.@) + */ +void WINAPI RtlpWaitForCriticalSection( CRITICAL_SECTION *crit ) +{ + for (;;) + { + EXCEPTION_RECORD rec; + HANDLE sem = get_semaphore( crit ); + + DWORD res = WaitForSingleObject( sem, 5000L ); + if ( res == WAIT_TIMEOUT ) + { + ERR("Critical section %p wait timed out, retrying (60 sec)\n", crit ); + res = WaitForSingleObject( sem, 60000L ); + if ( res == WAIT_TIMEOUT && TRACE_ON(relay) ) + { + ERR("Critical section %p wait timed out, retrying (5 min)\n", crit ); + res = WaitForSingleObject( sem, 300000L ); + } + } + if (res == STATUS_WAIT_0) break; + + rec.ExceptionCode = EXCEPTION_CRITICAL_SECTION_WAIT; + rec.ExceptionFlags = 0; + rec.ExceptionRecord = NULL; + rec.ExceptionAddress = RtlRaiseException; /* sic */ + rec.NumberParameters = 1; + rec.ExceptionInformation[0] = (DWORD)crit; + RtlRaiseException( &rec ); + } +} + + +/*********************************************************************** + * RtlpUnWaitCriticalSection (NTDLL.@) + */ +void WINAPI RtlpUnWaitCriticalSection( CRITICAL_SECTION *crit ) +{ + HANDLE sem = get_semaphore( crit ); + ReleaseSemaphore( sem, 1, NULL ); +} + + /*********************************************************************** * EnterCriticalSection (KERNEL32.195) (NTDLL.344) */ @@ -78,32 +122,7 @@ void WINAPI EnterCriticalSection( CRITICAL_SECTION *crit ) } /* Now wait for it */ - for (;;) - { - EXCEPTION_RECORD rec; - HANDLE sem = get_semaphore( crit ); - - DWORD res = WaitForSingleObject( sem, 5000L ); - if ( res == WAIT_TIMEOUT ) - { - ERR("Critical section %p wait timed out, retrying (60 sec)\n", crit ); - res = WaitForSingleObject( sem, 60000L ); - if ( res == WAIT_TIMEOUT && TRACE_ON(relay) ) - { - ERR("Critical section %p wait timed out, retrying (5 min)\n", crit ); - res = WaitForSingleObject( sem, 300000L ); - } - } - if (res == STATUS_WAIT_0) break; - - rec.ExceptionCode = EXCEPTION_CRITICAL_SECTION_WAIT; - rec.ExceptionFlags = 0; - rec.ExceptionRecord = NULL; - rec.ExceptionAddress = RtlRaiseException; /* sic */ - rec.NumberParameters = 1; - rec.ExceptionInformation[0] = (DWORD)crit; - RtlRaiseException( &rec ); - } + RtlpWaitForCriticalSection( crit ); } crit->OwningThread = GetCurrentThreadId(); crit->RecursionCount = 1; @@ -149,8 +168,7 @@ void WINAPI LeaveCriticalSection( CRITICAL_SECTION *crit ) if (InterlockedDecrement( &crit->LockCount ) >= 0) { /* Someone is waiting */ - HANDLE sem = get_semaphore( crit ); - ReleaseSemaphore( sem, 1, NULL ); + RtlpUnWaitCriticalSection( crit ); } }