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

ruby-changes:66552

From: Samuel <ko1@a...>
Date: Tue, 22 Jun 2021 19:49:19 +0900 (JST)
Subject: [ruby-changes:66552] fcc6fd23ec (master): Rework `sysread` to use blocking `read_internal_locktmp`.

https://git.ruby-lang.org/ruby.git/commit/?id=fcc6fd23ec

From fcc6fd23ec779a2421154bad441e168e4c6d4194 Mon Sep 17 00:00:00 2001
From: Samuel Williams <samuel.williams@o...>
Date: Sun, 20 Jun 2021 11:05:15 +1200
Subject: Rework `sysread` to use blocking `read_internal_locktmp`.

---
 io.c                 | 18 ++++++------------
 test/ruby/test_io.rb | 12 +++++++++---
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/io.c b/io.c
index 7db0560..7033fe6 100644
--- a/io.c
+++ b/io.c
@@ -5349,30 +5349,24 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io) https://github.com/ruby/ruby/blob/trunk/io.c#L5349
         rb_raise(rb_eIOError, "sysread for buffered IO");
     }
 
-    /*
-     * FIXME: removing rb_thread_wait_fd() here changes sysread semantics
-     * on non-blocking IOs.  However, it's still currently possible
-     * for sysread to raise Errno::EAGAIN if another thread read()s
-     * the IO after we return from rb_thread_wait_fd() but before
-     * we call read()
-     */
-    rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
-
     rb_io_check_closed(fptr);
 
     io_setstrbuf(&str, ilen);
+    iis.th = rb_thread_current();
     iis.fd = fptr->fd;
-    iis.nonblock = 1; /* for historical reasons, maybe (see above) */
+    iis.nonblock = 0;
     iis.buf = RSTRING_PTR(str);
     iis.capa = ilen;
     n = read_internal_locktmp(str, &iis);
 
     if (n < 0) {
-	rb_sys_fail_path(fptr->pathv);
+        rb_sys_fail_path(fptr->pathv);
     }
+
     io_set_read_length(str, n, shrinkable);
+
     if (n == 0 && ilen > 0) {
-	rb_eof_error();
+        rb_eof_error();
     }
 
     return str;
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 42149ac..14592e4 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -3316,11 +3316,17 @@ __END__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L3316
     data = "a" * 100
     with_pipe do |r,w|
       th = Thread.new {r.sysread(100, buf)}
+
       Thread.pass until th.stop?
-      buf.replace("")
-      assert_empty(buf, bug6099)
+
+      assert_equal 100, buf.bytesize
+
+      msg = /can't modify string; temporarily locked/
+      assert_raise_with_message(RuntimeError, msg) do
+        buf.replace("")
+      end
+      assert_predicate(th, :alive?)
       w.write(data)
-      Thread.pass while th.alive?
       th.join
     end
     assert_equal(data, buf, bug6099)
-- 
cgit v1.1


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

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