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


Reply via email to