base: Fix fdReady() potentially running forever for Windows Char devices.
authorNiklas Hamb├╝chen <mail@nh2.me>
Tue, 19 Sep 2017 19:10:31 +0000 (15:10 -0400)
committerBen Gamari <ben@smart-cactus.org>
Tue, 19 Sep 2017 19:58:45 +0000 (15:58 -0400)
Reviewers: bgamari, austin, hvr

Reviewed By: bgamari

Subscribers: rwbarton, thomie

Differential Revision: https://phabricator.haskell.org/D3955

libraries/base/cbits/inputReady.c

index 14f1c54..ab2a1c2 100644 (file)
@@ -102,6 +102,8 @@ fdReady(int fd, int write, int msecs, int isSock)
         HANDLE hFile = (HANDLE)_get_osfhandle(fd);
         DWORD avail;
 
+        Time remaining = MSToTime(msecs);
+
         switch (GetFileType(hFile)) {
 
             case FILE_TYPE_CHAR:
@@ -119,7 +121,11 @@ fdReady(int fd, int write, int msecs, int isSock)
 
                     while (1) // keep trying until we find a real key event
                     {
-                        rc = WaitForSingleObject( hFile, msecs );
+                        // WaitForSingleObject takes an unsigned number,
+                        // `remaining` can be negative. Wait 0 if so.
+                        DWORD wait_ms = (DWORD) max(0, TimeToMS(remaining));
+
+                        rc = WaitForSingleObject( hFile, wait_ms );
                         switch (rc) {
                             case WAIT_TIMEOUT: return 0;
                             case WAIT_OBJECT_0: break;
@@ -167,6 +173,9 @@ fdReady(int fd, int write, int msecs, int isSock)
                                 }
                             }
                         }
+
+                        Time now = getProcessElapsedTime();
+                        remaining = endTime - now;
                     }
                 }