diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-01-16 09:49:24 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-01-16 13:27:57 +0000 |
commit | fac8ecbbafde17dd92439c41747223c43e9d2b80 (patch) | |
tree | c3b5a0da07c8e738ead81983a7ac42bb29d715e5 /rts/posix | |
parent | a9e17cc2fdadf34b6f2bdd1e8889259327d31578 (diff) | |
download | haskell-fac8ecbbafde17dd92439c41747223c43e9d2b80.tar.gz |
Fix bug causing polling instead of blocking in the non-threaded RTS (#5773)
This was a regression introduced accidentally in
6b1098511aaabd2c9503ee7be6da1944466f9cb4. We were previously passing
a large time value to select() to simulate blocking, and this broke
due to a change from unsigned to signed arithmetic. I've refactored
it to be less fragile now - we just pass NULL as the timeval parameter
to select(), which is the correct way to do blocking.
Diffstat (limited to 'rts/posix')
-rw-r--r-- | rts/posix/Select.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/rts/posix/Select.c b/rts/posix/Select.c index 45737ce0cc..ffe72e8933 100644 --- a/rts/posix/Select.c +++ b/rts/posix/Select.c @@ -118,13 +118,9 @@ awaitEvent(rtsBool wait) int maxfd = -1; rtsBool select_succeeded = rtsTrue; rtsBool unblock_all = rtsFalse; - struct timeval tv; - Time min; + struct timeval tv, *ptv; LowResTime now; - tv.tv_sec = 0; - tv.tv_usec = 0; - IF_DEBUG(scheduler, debugBelch("scheduler: checking for threads blocked on I/O"); if (wait) { @@ -145,15 +141,7 @@ awaitEvent(rtsBool wait) return; } - if (!wait) { - min = 0; - } else if (sleeping_queue != END_TSO_QUEUE) { - min = LowResTimeToTime(sleeping_queue->block_info.target - now); - } else { - min = (Time)-1; - } - - /* + /* * Collect all of the fd's that we're interested in */ FD_ZERO(&rfd); @@ -194,12 +182,23 @@ awaitEvent(rtsBool wait) } } + if (wait) { + ptv = NULL; + } else if (sleeping_queue != END_TSO_QUEUE) { + Time min = LowResTimeToTime(sleeping_queue->block_info.target - now); + tv.tv_sec = TimeToSeconds(min); + tv.tv_usec = TimeToUS(min) % 1000000; + ptv = &tv; + } else { + // just poll + tv.tv_sec = 0; + tv.tv_usec = 0; + ptv = &tv; + } + /* Check for any interesting events */ - tv.tv_sec = TimeToSeconds(min); - tv.tv_usec = TimeToUS(min) % 1000000; - - while ((numFound = select(maxfd+1, &rfd, &wfd, NULL, &tv)) < 0) { + while ((numFound = select(maxfd+1, &rfd, &wfd, NULL, ptv)) < 0) { if (errno != EINTR) { /* Handle bad file descriptors by unblocking all the waiting threads. Why? Because a thread might have been |