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

ruby-changes:32987

From: normal <ko1@a...>
Date: Fri, 21 Feb 2014 09:55:19 +0900 (JST)
Subject: [ruby-changes:32987] normal:r45066 (trunk): socket: sendmsg/recvmsg only retries blocking on errors

normal	2014-02-21 09:55:13 +0900 (Fri, 21 Feb 2014)

  New Revision: 45066

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

  Log:
    socket: sendmsg/recvmsg only retries blocking on errors
    
    * ext/socket/ancdata.c (bsock_sendmsg_internal): only retry on error
      (bsock_recvmsg_internal): ditto
    * test/socket/test_unix.rb: test above for infinite loop

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/ancdata.c
    trunk/test/socket/test_unix.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45065)
+++ ChangeLog	(revision 45066)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Feb 21 09:48:56 2014  Eric Wong  <e@8...>
+
+	* ext/socket/ancdata.c (bsock_sendmsg_internal): only retry on error
+	  (bsock_recvmsg_internal): ditto
+	* test/socket/test_unix.rb: test above for infinite loop
+
 Fri Feb 21 08:27:19 2014  Eric Wong  <e@8...>
 
 	* include/ruby/ruby.h (RB_GC_GUARD):
Index: ext/socket/ancdata.c
===================================================================
--- ext/socket/ancdata.c	(revision 45065)
+++ ext/socket/ancdata.c	(revision 45066)
@@ -1282,12 +1282,11 @@ bsock_sendmsg_internal(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/ext/socket/ancdata.c#L1282
 
     ss = rb_sendmsg(fptr->fd, &mh, flags);
 
-    if (!nonblock && rb_io_wait_writable(fptr->fd)) {
-        rb_io_check_closed(fptr);
-        goto retry;
-    }
-
     if (ss == -1) {
+        if (!nonblock && rb_io_wait_writable(fptr->fd)) {
+            rb_io_check_closed(fptr);
+            goto retry;
+        }
         if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
             rb_readwrite_sys_fail(RB_IO_WAIT_WRITABLE, "sendmsg(2) would block");
 	rb_sys_fail("sendmsg(2)");
@@ -1601,12 +1600,11 @@ bsock_recvmsg_internal(int argc, VALUE * https://github.com/ruby/ruby/blob/trunk/ext/socket/ancdata.c#L1600
 
     ss = rb_recvmsg(fptr->fd, &mh, flags);
 
-    if (!nonblock && rb_io_wait_readable(fptr->fd)) {
-        rb_io_check_closed(fptr);
-        goto retry;
-    }
-
     if (ss == -1) {
+        if (!nonblock && rb_io_wait_readable(fptr->fd)) {
+            rb_io_check_closed(fptr);
+            goto retry;
+        }
         if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
             rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "recvmsg(2) would block");
 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
Index: test/socket/test_unix.rb
===================================================================
--- test/socket/test_unix.rb	(revision 45065)
+++ test/socket/test_unix.rb	(revision 45066)
@@ -5,6 +5,7 @@ end https://github.com/ruby/ruby/blob/trunk/test/socket/test_unix.rb#L5
 
 require "test/unit"
 require "tempfile"
+require "timeout"
 require "tmpdir"
 require "thread"
 require "io/nonblock"
@@ -369,6 +370,28 @@ class TestSocket_UNIXSocket < Test::Unit https://github.com/ruby/ruby/blob/trunk/test/socket/test_unix.rb#L370
     s2.close if s2
   end
 
+  def test_dgram_pair_sendrecvmsg_errno_set
+    s1, s2 = to_close = UNIXSocket.pair(Socket::SOCK_DGRAM)
+    pipe = IO.pipe
+    to_close.concat(pipe)
+    set_errno = lambda do
+      begin
+        pipe[0].read_nonblock(1)
+        fail
+      rescue => e
+        assert(IO::EAGAINWaitReadable === e)
+      end
+    end
+    Timeout.timeout(10) do
+      set_errno.call
+      assert_equal(2, s1.sendmsg("HI"))
+      set_errno.call
+      assert_equal("HI", s2.recvmsg[0])
+    end
+  ensure
+    to_close.each(&:close) if to_close
+  end
+
   def test_epipe # [ruby-dev:34619]
     s1, s2 = UNIXSocket.pair
     s1.shutdown(Socket::SHUT_WR)

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

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