[commit: ghc] master: base: Fix fdReady() potentially running forever on Windows. (c2a1fa7)
git at git.haskell.org
git at git.haskell.org
Tue Sep 19 21:55:31 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/c2a1fa7aec426727be6df79f3db109183e42cfdc/ghc
>---------------------------------------------------------------
commit c2a1fa7aec426727be6df79f3db109183e42cfdc
Author: Niklas Hambüchen <mail at nh2.me>
Date: Tue Sep 19 15:10:00 2017 -0400
base: Fix fdReady() potentially running forever on Windows.
This fixes #13497 for Windows -- at least for the `if (isSock)` part; I
haven't investigated the case where it's not a socket yet.
Solved by copying the new current-time based waiting logic from the
non-Windows implementation above.
Reviewers: bgamari, austin, hvr
Reviewed By: bgamari
Subscribers: rwbarton, thomie
Differential Revision: https://phabricator.haskell.org/D3954
>---------------------------------------------------------------
c2a1fa7aec426727be6df79f3db109183e42cfdc
libraries/base/cbits/inputReady.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/libraries/base/cbits/inputReady.c b/libraries/base/cbits/inputReady.c
index dbfdb28..14f1c54 100644
--- a/libraries/base/cbits/inputReady.c
+++ b/libraries/base/cbits/inputReady.c
@@ -21,10 +21,6 @@
int
fdReady(int fd, int write, int msecs, int isSock)
{
-
-#if !defined(_WIN32)
- struct pollfd fds[1];
-
// if we need to track the time then record the end time in case we are
// interrupted.
Time endTime = 0;
@@ -32,6 +28,9 @@ fdReady(int fd, int write, int msecs, int isSock)
endTime = getProcessElapsedTime() + MSToTime(msecs);
}
+#if !defined(_WIN32)
+ struct pollfd fds[1];
+
fds[0].fd = fd;
fds[0].events = write ? POLLOUT : POLLIN;
fds[0].revents = 0;
@@ -59,7 +58,8 @@ fdReady(int fd, int write, int msecs, int isSock)
if (isSock) {
int maxfd, ready;
fd_set rfd, wfd;
- struct timeval tv;
+ struct timeval remaining_tv;
+
if ((fd >= (int)FD_SETSIZE) || (fd < 0)) {
fprintf(stderr, "fdReady: fd is too big");
abort();
@@ -76,12 +76,22 @@ fdReady(int fd, int write, int msecs, int isSock)
* (maxfd-1)
*/
maxfd = fd + 1;
- tv.tv_sec = msecs / 1000;
- tv.tv_usec = (msecs % 1000) * 1000;
- while ((ready = select(maxfd, &rfd, &wfd, NULL, &tv)) < 0 ) {
- if (errno != EINTR ) {
- return -1;
+ Time remaining = MSToTime(msecs);
+ remaining_tv.tv_sec = TimeToMS(remaining) / 1000;
+ remaining_tv.tv_usec = TimeToUS(remaining) % 1000000;
+
+ while ((ready = select(maxfd, &rfd, &wfd, NULL, &remaining_tv)) < 0 ) {
+ if (errno == EINTR) {
+ if (msecs > 0) {
+ Time now = getProcessElapsedTime();
+ if (now >= endTime) return 0;
+ remaining = endTime - now;
+ remaining_tv.tv_sec = TimeToMS(remaining) / 1000;
+ remaining_tv.tv_usec = TimeToUS(remaining) % 1000000;
+ }
+ } else {
+ return (-1);
}
}
More information about the ghc-commits
mailing list