ruby-changes:19380
From: kosaki <ko1@a...>
Date: Wed, 4 May 2011 10:07:12 +0900 (JST)
Subject: [ruby-changes:19380] Ruby:r31420 (trunk): * thread.c (rb_wait_for_single_fd): new. poll(2) based backend for rb_wait_for_single_fd().
kosaki 2011-05-04 10:07:03 +0900 (Wed, 04 May 2011) New Revision: 31420 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=31420 Log: * thread.c (rb_wait_for_single_fd): new. poll(2) based backend for rb_wait_for_single_fd(). Now only Linux uses it. The patch was written by Eric Wong. [Ruby 1.9 - Feature #4531] Modified files: trunk/ChangeLog trunk/configure.in trunk/include/ruby/io.h trunk/thread.c Index: include/ruby/io.h =================================================================== --- include/ruby/io.h (revision 31419) +++ include/ruby/io.h (revision 31420) @@ -27,9 +27,17 @@ #include <stdio_ext.h> #endif -#define RB_WAITFD_IN 0x001 -#define RB_WAITFD_PRI 0x002 -#define RB_WAITFD_OUT 0x004 +#include "ruby/config.h" +#if defined(HAVE_POLL) +# include <poll.h> +# define RB_WAITFD_IN POLLIN +# define RB_WAITFD_PRI POLLPRI +# define RB_WAITFD_OUT POLLOUT +#else +# define RB_WAITFD_IN 0x001 +# define RB_WAITFD_PRI 0x002 +# define RB_WAITFD_OUT 0x004 +#endif #if defined __GNUC__ && __GNUC__ >= 4 #pragma GCC visibility push(default) Index: configure.in =================================================================== --- configure.in (revision 31419) +++ configure.in (revision 31420) @@ -1310,7 +1310,7 @@ dlopen sigprocmask sigaction sigsetjmp _setjmp _longjmp\ setsid telldir seekdir fchmod cosh sinh tanh log2 round\ setuid setgid daemon select_large_fdset setenv unsetenv\ - mktime timegm gmtime_r clock_gettime gettimeofday\ + mktime timegm gmtime_r clock_gettime gettimeofday poll\ pread sendfile shutdown sigaltstack dl_iterate_phdr) AC_CACHE_CHECK(for unsetenv returns a value, rb_cv_unsetenv_return_value, Index: ChangeLog =================================================================== --- ChangeLog (revision 31419) +++ ChangeLog (revision 31420) @@ -1,3 +1,10 @@ +Wed May 4 10:01:27 2011 KOSAKI Motohiro <kosaki.motohiro@g...> + + * thread.c (rb_wait_for_single_fd): new. poll(2) based backend for rb_wait_for_single_fd(). + Now only Linux uses it. + + The patch was written by Eric Wong. [Ruby 1.9 - Feature #4531] + Wed May 4 09:56:57 2011 KOSAKI Motohiro <kosaki.motohiro@g...> * thread.c (rb_wait_for_single_fd): new. Index: thread.c =================================================================== --- thread.c (revision 31419) +++ thread.c (revision 31420) @@ -2704,6 +2704,63 @@ return do_select(max, read, write, except, timeout); } +/* + * poll() is supported by many OSes, but so far Linux is the only + * one we know of that supports using poll() in all places select() + * would work. + */ +#if defined(HAVE_POLL) && defined(linux) +# define USE_POLL +#endif + +#ifdef USE_POLL +/* + * returns a mask of events + */ +int +rb_wait_for_single_fd(int fd, int events, struct timeval *tv) +{ + struct pollfd fds; + int result, lerrno; + double start; + int timeout = tv ? tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000 : -1; + + fds.fd = fd; + fds.events = (short)events; + +retry: + lerrno = 0; + start = timeofday(); + BLOCKING_REGION({ + result = poll(&fds, 1, timeout); + if (result < 0) lerrno = errno; + }, ubf_select, GET_THREAD()); + + if (result > 0) { + /* remain compatible with select(2)-based implementation */ + result = (int)(fds.revents & fds.events); + return result == 0 ? events : result; + } + + if (result < 0) { + errno = lerrno; + switch (errno) { + case EINTR: +#ifdef ERESTART + case ERESTART: +#endif + if (timeout > 0) { + timeout -= (timeofday() - start) * 1000; + if (timeout < 0) + timeout = 0; + } + goto retry; + } + } + + return result; +} +#else /* ! USE_POLL - implement rb_io_poll_fd() using select() */ static rb_fdset_t *init_set_fd(int fd, rb_fdset_t *fds) { rb_fd_init(fds); @@ -2777,6 +2834,7 @@ return r; } +#endif /* ! USE_POLL */ /* * for GC -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/