[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
This commit is contained in:
Hermès Bélusca-Maïto 2017-09-26 14:29:25 +00:00
parent 036a0ad651
commit 4bce7ced02

View file

@ -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;
}