From c06da4735da0e2285c1e3e52202b7090b3f43b1b Mon Sep 17 00:00:00 2001 From: kosaki Date: Wed, 4 May 2011 10:02:06 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31429 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++ .../test_wait_for_single_fd.rb | 10 ++++++ thread.c | 34 ++++++++++++++----- 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 + + * 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 * 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() */