diff --git a/dll/win32/kernel32/client/synch.c b/dll/win32/kernel32/client/synch.c index f7df2f710a..a022e4c33b 100644 --- a/dll/win32/kernel32/client/synch.c +++ b/dll/win32/kernel32/client/synch.c @@ -802,7 +802,16 @@ WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable) { + /* + * This function is the optimized of the following code: + * + * DWORD wait = WaitForSingleObjectEx(GetCurrentThread(), dwMilliseconds, bAlertable); + * if (wait == WAIT_IO_COMPLETION) + * return wait; + * return 0; + */ LARGE_INTEGER Time; + HANDLE hCurrentThread; PLARGE_INTEGER TimePtr; NTSTATUS errCode; RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; @@ -819,27 +828,29 @@ SleepEx(IN DWORD dwMilliseconds, /* Convert the timeout */ TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds); - if (!TimePtr) - { - /* Turn an infinite wait into a really long wait */ - Time.LowPart = 0; - Time.HighPart = 0x80000000; - TimePtr = &Time; - } - /* Loop the delay while APCs are alerting us */ + /* Get the current thread handle */ + hCurrentThread = (HANDLE)NtCurrentThread(); + + /* Start wait loop */ do { - /* Do the delay */ - errCode = NtDelayExecution((BOOLEAN)bAlertable, TimePtr); + /* Do the wait */ + errCode = NtWaitForSingleObject(hCurrentThread, (BOOLEAN)bAlertable, TimePtr); + if (!NT_SUCCESS(errCode)) + { + /* The wait failed */ + BaseSetLastNTError(errCode); + errCode = WAIT_FAILED; + } } while ((bAlertable) && (errCode == STATUS_ALERTED)); - + /* Cleanup the activation context */ if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); /* Return the correct code */ - return (errCode == STATUS_USER_APC) ? WAIT_IO_COMPLETION : 0; + return (errCode == WAIT_IO_COMPLETION) ? errCode : 0; } /*