Author: hbelusca Date: Tue Sep 26 14:29:25 2017 New Revision: 75977 URL: http://svn.reactos.org/svn/reactos?rev=75977&view=rev Log: [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.
Modified: trunk/reactos/base/applications/cmdutils/timeout/timeout.c Modified: trunk/reactos/base/applications/cmdutils/timeout/timeout.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils/timeout/timeout.c?rev=75977&r1=75976&r2=75977&view=diff ============================================================================== --- trunk/reactos/base/applications/cmdutils/timeout/timeout.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/cmdutils/timeout/timeout.c [iso-8859-1] Tue Sep 26 14:29:25 2017 @@ -49,6 +49,7 @@ INT Status = EXIT_SUCCESS; HANDLE hInput; BOOL bUseTimer = (timerValue != -1); + HANDLE hTimer = NULL; DWORD dwStartTime; LONG timeElapsed; DWORD dwWaitState; @@ -67,6 +68,16 @@ } /* 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 @@ { 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 @@ 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) @@ -234,6 +271,9 @@ Quit: if (bNoBreak) SetConsoleCtrlHandler(NULL, FALSE); + + if (bNoBreak && bUseTimer) + CloseHandle(hTimer); return Status; }