summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb10
-rw-r--r--thread.c34
3 files changed, 41 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index a6b9beff14..305a7a4bc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed May 4 19:00:59 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+
+ * thread.c (rb_wait_for_single_fd): Fix wrong return value.
+ * test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
+ (TestWaitForSingleFD#test_wait_for_closed_pipe): test for it.
+
Wed May 4 18:46:39 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* ext/-test-/wait_for_single_fd: New. for testing
diff --git a/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb b/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
index 76ef68002a..c7dd0909f0 100644
--- a/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
+++ b/test/-ext-/wait_for_single_fd/test_wait_for_single_fd.rb
@@ -29,4 +29,14 @@ class TestWaitForSingleFD < Test::Unit::TestCase
end
end
end
+
+ def test_wait_for_closed_pipe
+ with_pipe do |r,w|
+ w.close
+ rc = IO.wait_for_single_fd(r.fileno, RB_WAITFD_IN, nil)
+ assert_equal RB_WAITFD_IN, rc
+ end
+ end
+
+
end
diff --git a/thread.c b/thread.c
index 5e10a8366f..1a3dabeb96 100644
--- a/thread.c
+++ b/thread.c
@@ -2714,6 +2714,13 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
#endif
#ifdef USE_POLL
+
+
+/* The same with linux kernel. TODO: make platform independent definition. */
+#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
+#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
+#define POLLEX_SET (POLLPRI)
+
/*
* returns a mask of events
*/
@@ -2736,15 +2743,6 @@ retry:
if (result < 0) lerrno = errno;
}, ubf_select, GET_THREAD());
- if (result > 0) {
- if (fds.revents & POLLNVAL) {
- errno = EBADF;
- return -1;
- }
- result = (int)(fds.revents & fds.events);
- return result == 0 ? events : result;
- }
-
if (result < 0) {
errno = lerrno;
switch (errno) {
@@ -2759,8 +2757,26 @@ retry:
}
goto retry;
}
+ return -1;
}
+ if (fds.revents & POLLNVAL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * POLLIN, POLLOUT have a different meanings from select(2)'s read/write bit.
+ * Therefore we need fix it up.
+ */
+ result = 0;
+ if (fds.revents & POLLIN_SET)
+ result |= RB_WAITFD_IN;
+ if (fds.revents & POLLOUT_SET)
+ result |= RB_WAITFD_OUT;
+ if (fds.revents & POLLEX_SET)
+ result |= RB_WAITFD_PRI;
+
return result;
}
#else /* ! USE_POLL - implement rb_io_poll_fd() using select() */