[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]