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

ruby-changes:51220

From: normal <ko1@a...>
Date: Tue, 15 May 2018 12:49:26 +0900 (JST)
Subject: [ruby-changes:51220] normal:r63427 (trunk): thread.c: enable ppoll for FreeBSD 11.0 and later

normal	2018-05-15 12:49:21 +0900 (Tue, 15 May 2018)

  New Revision: 63427

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63427

  Log:
    thread.c: enable ppoll for FreeBSD 11.0 and later
    
    FreeBSD 11.0+ supports ppoll, so we may use it after accounting
    for portability differences in how it treats POLLOUT vs POLLHUP
    events as mutually exclusive (as documented in the FreeBSD
    poll(2) manpage).
    
    For waiting on high-numbered single FDs, this should put
    FreeBSD on equal footing with Linux and should allow cheaper
    FD readiness checking with sleepy GC in the future.
    
    * thread.c (USE_POLL, POLLERR_SET): define for FreeBSD 11.0+
      (rb_wait_for_single_fd): return all requested events on POLLERR_SET
      io.c (USE_POLL): define for FreeBSD 11.0+

  Modified files:
    trunk/io.c
    trunk/thread.c
Index: io.c
===================================================================
--- io.c	(revision 63426)
+++ io.c	(revision 63427)
@@ -10643,15 +10643,21 @@ maygvl_copy_stream_continue_p(int has_gv https://github.com/ruby/ruby/blob/trunk/io.c#L10643
 }
 
 /* non-Linux poll may not work on all FDs */
-#if defined(HAVE_POLL) && defined(__linux__)
-#  define USE_POLL 1
-#  define IOWAIT_SYSCALL "poll"
-#else
-#  define IOWAIT_SYSCALL "select"
+#if defined(HAVE_POLL)
+#  if defined(__linux__)
+#    define USE_POLL 1
+#  endif
+#  if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000
+#    define USE_POLL 1
+#  endif
+#endif
+
+#ifndef USE_POLL
 #  define USE_POLL 0
 #endif
 
 #if USE_POLL
+#  define IOWAIT_SYSCALL "poll"
 STATIC_ASSERT(pollin_expected, POLLIN == RB_WAITFD_IN);
 STATIC_ASSERT(pollout_expected, POLLOUT == RB_WAITFD_OUT);
 static int
@@ -10665,6 +10671,7 @@ nogvl_wait_for_single_fd(int fd, short e https://github.com/ruby/ruby/blob/trunk/io.c#L10671
     return poll(&fds, 1, -1);
 }
 #else /* !USE_POLL */
+#  define IOWAIT_SYSCALL "select"
 static int
 nogvl_wait_for_single_fd(int fd, short events)
 {
Index: thread.c
===================================================================
--- thread.c	(revision 63426)
+++ thread.c	(revision 63427)
@@ -206,8 +206,15 @@ vm_living_thread_num(const rb_vm_t *vm) https://github.com/ruby/ruby/blob/trunk/thread.c#L206
  * one we know of that supports using poll() in all places select()
  * would work.
  */
-#if defined(HAVE_POLL) && defined(__linux__)
-#  define USE_POLL
+#if defined(HAVE_POLL)
+#  if defined(__linux__)
+#    define USE_POLL
+#  endif
+#  if defined(__FreeBSD_version) && __FreeBSD_version >= 1100000
+#    define USE_POLL
+     /* FreeBSD does not set POLLOUT when POLLHUP happens */
+#    define POLLERR_SET (POLLHUP | POLLERR)
+#  endif
 #endif
 
 static struct timespec *
@@ -3923,6 +3930,10 @@ rb_thread_fd_select(int max, rb_fdset_t https://github.com/ruby/ruby/blob/trunk/thread.c#L3930
 #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
 #define POLLEX_SET (POLLPRI)
 
+#ifndef POLLERR_SET /* defined for FreeBSD for now */
+#  define POLLERR_SET (0)
+#endif
+
 #ifndef HAVE_PPOLL
 /* TODO: don't ignore sigmask */
 int
@@ -4004,6 +4015,10 @@ rb_wait_for_single_fd(int fd, int events https://github.com/ruby/ruby/blob/trunk/thread.c#L4015
     if (fds.revents & POLLEX_SET)
 	result |= RB_WAITFD_PRI;
 
+    /* all requested events are ready if there is an error */
+    if (fds.revents & POLLERR_SET)
+	result |= events;
+
     return result;
 }
 #else /* ! USE_POLL - implement rb_io_poll_fd() using select() */

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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