From 4bce7ced02e04b6e5fbf33b47cc4f40eeba51387 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 26 Sep 2017 14:29:25 +0000 Subject: [PATCH] [TIMEOUT]: Use a waitable timer to wait for a maximum of 1 second, instead of using some Sleep(100) calls. The only Sleep() call allowed is the Sleep(INFINITE) one. svn path=/trunk/; revision=75977 --- .../applications/cmdutils/timeout/timeout.c | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/reactos/base/applications/cmdutils/timeout/timeout.c b/reactos/base/applications/cmdutils/timeout/timeout.c index 59010984279..604014fe8b7 100644 --- a/reactos/base/applications/cmdutils/timeout/timeout.c +++ b/reactos/base/applications/cmdutils/timeout/timeout.c @@ -49,6 +49,7 @@ INT InputWait(BOOL bNoBreak, INT timerValue) INT Status = EXIT_SUCCESS; HANDLE hInput; BOOL bUseTimer = (timerValue != -1); + HANDLE hTimer = NULL; DWORD dwStartTime; LONG timeElapsed; DWORD dwWaitState; @@ -67,6 +68,16 @@ INT InputWait(BOOL bNoBreak, INT timerValue) } /* Start a new wait if we use the timer */ + if (bNoBreak && bUseTimer) + { + hTimer = CreateWaitableTimer(NULL, TRUE, NULL); + if (hTimer == NULL) + { + /* A problem happened, bail out */ + PrintError(GetLastError()); + return EXIT_FAILURE; + } + } if (bUseTimer) dwStartTime = GetTickCount(); @@ -138,8 +149,34 @@ INT InputWait(BOOL bNoBreak, INT timerValue) { if (bUseTimer) { - /* We use the timer: wait a little bit before updating it */ - Sleep(100); + LARGE_INTEGER DueTime; + + /* We use the timer: use a passive wait of maximum 1 second */ + timeElapsed = GetTickCount() - dwStartTime; + if (timeElapsed < 1000) + { + /* + * For whatever reason, x86 MSVC generates a ntdll!_allmul + * call when using Int32x32To64(), instead of an imul + * instruction. This leads the linker to error that _allmul + * is missing, since we do not link against ntdll. + * Everything is however OK with GCC... + * We therefore use the __emul() intrinsic which does + * the correct job. + */ + DueTime.QuadPart = __emul(1000 - timeElapsed, -10000); + SetWaitableTimer(hTimer, &DueTime, 0, NULL, NULL, FALSE); + dwWaitState = WaitForSingleObject(hTimer, INFINITE); + + /* Check whether the timer has been signaled */ + if (dwWaitState != WAIT_OBJECT_0) + { + /* An error happened, bail out */ + PrintError(GetLastError()); + Status = EXIT_FAILURE; + break; + } + } } else { @@ -170,7 +207,7 @@ INT InputWait(BOOL bNoBreak, INT timerValue) else dwWaitState = WAIT_TIMEOUT; - /* Check whether the input handle has been signaled, or a timeout happened */ + /* Check whether the input event has been signaled, or a timeout happened */ if (dwWaitState == WAIT_TIMEOUT) continue; if (dwWaitState != WAIT_OBJECT_0) @@ -235,6 +272,9 @@ Quit: if (bNoBreak) SetConsoleCtrlHandler(NULL, FALSE); + if (bNoBreak && bUseTimer) + CloseHandle(hTimer); + return Status; } -- 2.17.1