summaryrefslogtreecommitdiff
path: root/rts/posix
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-01-16 09:49:24 +0000
committerSimon Marlow <marlowsd@gmail.com>2012-01-16 13:27:57 +0000
commitfac8ecbbafde17dd92439c41747223c43e9d2b80 (patch)
treec3b5a0da07c8e738ead81983a7ac42bb29d715e5 /rts/posix
parenta9e17cc2fdadf34b6f2bdd1e8889259327d31578 (diff)
downloadhaskell-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.c35
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