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

ruby-changes:32564

From: akr <ko1@a...>
Date: Sat, 18 Jan 2014 23:13:26 +0900 (JST)
Subject: [ruby-changes:32564] akr:r44643 (trunk): * ext/socket: Avoid unnecessary ppoll/select on Linux.

akr	2014-01-18 23:13:22 +0900 (Sat, 18 Jan 2014)

  New Revision: 44643

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44643

  Log:
    * ext/socket: Avoid unnecessary ppoll/select on Linux.
      Patch by Eric Wong.  [ruby-core:57950] [Bug #9039]

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/basicsocket.c
    trunk/ext/socket/init.c
    trunk/ext/socket/rubysocket.h
    trunk/ext/socket/udpsocket.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 44642)
+++ ChangeLog	(revision 44643)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Jan 18 23:12:19 2014  Tanaka Akira  <akr@f...>
+
+	* ext/socket: Avoid unnecessary ppoll/select on Linux.
+	  Patch by Eric Wong.  [ruby-core:57950] [Bug #9039]
+
 Sat Jan 18 22:57:44 2014  Tanaka Akira  <akr@f...>
 
 	* lib/resolv.rb (Resolv::DNS::Resource::TXT#data): Return concatenated
Index: ext/socket/rubysocket.h
===================================================================
--- ext/socket/rubysocket.h	(revision 44642)
+++ ext/socket/rubysocket.h	(revision 44643)
@@ -386,4 +386,20 @@ NORETURN(void rsock_sys_fail_sockaddr(co https://github.com/ruby/ruby/blob/trunk/ext/socket/rubysocket.h#L386
 NORETURN(void rsock_sys_fail_raddrinfo(const char *, VALUE rai));
 NORETURN(void rsock_sys_fail_raddrinfo_or_sockaddr(const char *, VALUE addr, VALUE rai));
 
+/*
+ * It is safe on Linux to attempt using a socket without waiting on it in
+ * all cases.  For some syscalls (e.g. accept/accept4), blocking on the
+ * syscall instead of relying on select/poll allows the kernel to use
+ * "wake-one" behavior and avoid the thundering herd problem.
+ * This is likely safe on all other *nix-like systems, so this whitelist
+ * can be expanded by interested parties.
+ */
+#if defined(__linux__)
+static inline int rsock_maybe_fd_writable(int fd) { return 1; }
+static inline void rsock_maybe_wait_fd(int fd) { }
+#else /* some systems (mswin/mingw) need these.  ref: r36946 */
+#  define rsock_maybe_fd_writable(fd) rb_thread_fd_writable((fd))
+#  define rsock_maybe_wait_fd(fd) rb_thread_wait_fd((fd))
+#endif
+
 #endif
Index: ext/socket/udpsocket.c
===================================================================
--- ext/socket/udpsocket.c	(revision 44642)
+++ ext/socket/udpsocket.c	(revision 44643)
@@ -177,7 +177,7 @@ udp_send(int argc, VALUE *argv, VALUE so https://github.com/ruby/ruby/blob/trunk/ext/socket/udpsocket.c#L177
       retry:
 	arg.to = res->ai_addr;
 	arg.tolen = res->ai_addrlen;
-	rb_thread_fd_writable(arg.fd);
+	rsock_maybe_fd_writable(arg.fd);
 	n = (int)BLOCKING_REGION_FD(rsock_sendto_blocking, &arg);
 	if (n >= 0) {
 	    freeaddrinfo(res0);
Index: ext/socket/init.c
===================================================================
--- ext/socket/init.c	(revision 44642)
+++ ext/socket/init.c	(revision 44643)
@@ -135,7 +135,7 @@ rsock_s_recvfrom(VALUE sock, int argc, V https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L135
     rb_obj_hide(str);
 
     while (rb_io_check_closed(fptr),
-	   rb_thread_wait_fd(arg.fd),
+	   rsock_maybe_wait_fd(arg.fd),
 	   (slen = BLOCKING_REGION_FD(recvfrom_blocking, &arg)) < 0) {
         if (!rb_io_wait_readable(fptr->fd)) {
             rb_sys_fail("recvfrom(2)");
@@ -575,7 +575,7 @@ rsock_s_accept(VALUE klass, int fd, stru https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L575
     arg.sockaddr = sockaddr;
     arg.len = len;
   retry:
-    rb_thread_wait_fd(fd);
+    rsock_maybe_wait_fd(fd);
     fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg);
     if (fd2 < 0) {
 	switch (errno) {
Index: ext/socket/basicsocket.c
===================================================================
--- ext/socket/basicsocket.c	(revision 44642)
+++ ext/socket/basicsocket.c	(revision 44643)
@@ -563,7 +563,7 @@ rsock_bsock_send(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L563
     GetOpenFile(sock, fptr);
     arg.fd = fptr->fd;
     arg.flags = NUM2INT(flags);
-    while (rb_thread_fd_writable(arg.fd),
+    while (rsock_maybe_fd_writable(arg.fd),
 	   (n = (int)BLOCKING_REGION_FD(func, &arg)) < 0) {
 	if (rb_io_wait_writable(arg.fd)) {
 	    continue;

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

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