Hi all,

Here's a patch to deal with "special" situations in poll().  Mario found a
problem on Linux:
http://paste.call-cc.org/paste?id=c01e9dfcce2f56e88be143a01c6c4fb0bf1bec25
I think this is due to the change described here:
http://lkml.indiana.edu/hypermail/linux/kernel/0103.1/0711.html

In any case, we don't check poll() revents for any other values than
POLLIN/POLLOUT, which is clearly wrong; if a pipe is closed, there's
nothing to read, but it will be POLLHUP'ed.  Apparently on non-Linux
this generally won't be signalled like this (except maybe in some
situations), which is why this wasn't noticed before.

I nominate this patch for inclusion in the stability branch.

Cheers,
Peter
-- 
http://www.more-magic.net
>From 2acf354837ee98aaabaf6493cb4a2b27e8068b6b Mon Sep 17 00:00:00 2001
From: Peter Bex <peter....@xs4all.nl>
Date: Tue, 26 Feb 2013 18:58:45 +0100
Subject: [PATCH] When checking whether an FD is ready for input or output,
 also check for special situations (error, device/FIFO/pipe hangup and invalid
 FD) in the poll() implementation of the scheduler. This fixes a CPU
 consumption bug in waiting for process-ports on Linux (thanks to Mario
 Goulart for finding the bug).

---
 NEWS          | 3 +++
 scheduler.scm | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 226cc73..a5f9054 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,9 @@
 - Core libraries
   - read-line no longer returns trailing CRs in rare cases on TCP ports (#568)
 
+- Runtime system
+  - Special events in poll() are now handled, avoiding hangs in threaded apps.
+
 4.8.1
 
 - Security fixes
diff --git a/scheduler.scm b/scheduler.scm
index ff521a7..ee258fe 100644
--- a/scheduler.scm
+++ b/scheduler.scm
@@ -85,8 +85,8 @@ C_inline int C_fd_ready(int fd, int pos, int what) {
   return(C_fdset_set[pos].revents & what);
 }
 
-#define C_fd_input_ready(fd,pos)  C_mk_bool(C_fd_ready(C_unfix(fd), 
C_unfix(pos),POLLIN))
-#define C_fd_output_ready(fd,pos)  C_mk_bool(C_fd_ready(C_unfix(fd), 
C_unfix(pos),POLLOUT))
+#define C_fd_input_ready(fd,pos)  C_mk_bool(C_fd_ready(C_unfix(fd), 
C_unfix(pos),POLLIN|POLLERR|POLLHUP|POLLNVAL))
+#define C_fd_output_ready(fd,pos)  C_mk_bool(C_fd_ready(C_unfix(fd), 
C_unfix(pos),POLLOUT|POLLERR|POLLHUP|POLLNVAL))
 
 C_inline int C_ready_fds_timeout(int to, double tm) {
   return poll(C_fdset_set, C_fdset_nfds, to ? (int)tm : -1);
-- 
1.8.0.1

_______________________________________________
Chicken-hackers mailing list
Chicken-hackers@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-hackers

Reply via email to