Skip to content

Commit fcc6fd2

Browse files
committed
Rework sysread to use blocking read_internal_locktmp.
1 parent 45e65f3 commit fcc6fd2

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

io.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5349,30 +5349,24 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
53495349
rb_raise(rb_eIOError, "sysread for buffered IO");
53505350
}
53515351

5352-
/*
5353-
* FIXME: removing rb_thread_wait_fd() here changes sysread semantics
5354-
* on non-blocking IOs. However, it's still currently possible
5355-
* for sysread to raise Errno::EAGAIN if another thread read()s
5356-
* the IO after we return from rb_thread_wait_fd() but before
5357-
* we call read()
5358-
*/
5359-
rb_io_wait(fptr->self, RB_INT2NUM(RUBY_IO_READABLE), Qnil);
5360-
53615352
rb_io_check_closed(fptr);
53625353

53635354
io_setstrbuf(&str, ilen);
5355+
iis.th = rb_thread_current();
53645356
iis.fd = fptr->fd;
5365-
iis.nonblock = 1; /* for historical reasons, maybe (see above) */
5357+
iis.nonblock = 0;
53665358
iis.buf = RSTRING_PTR(str);
53675359
iis.capa = ilen;
53685360
n = read_internal_locktmp(str, &iis);
53695361

53705362
if (n < 0) {
5371-
rb_sys_fail_path(fptr->pathv);
5363+
rb_sys_fail_path(fptr->pathv);
53725364
}
5365+
53735366
io_set_read_length(str, n, shrinkable);
5367+
53745368
if (n == 0 && ilen > 0) {
5375-
rb_eof_error();
5369+
rb_eof_error();
53765370
}
53775371

53785372
return str;

test/ruby/test_io.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3316,11 +3316,17 @@ def test_sysread_locktmp
33163316
data = "a" * 100
33173317
with_pipe do |r,w|
33183318
th = Thread.new {r.sysread(100, buf)}
3319+
33193320
Thread.pass until th.stop?
3320-
buf.replace("")
3321-
assert_empty(buf, bug6099)
3321+
3322+
assert_equal 100, buf.bytesize
3323+
3324+
msg = /can't modify string; temporarily locked/
3325+
assert_raise_with_message(RuntimeError, msg) do
3326+
buf.replace("")
3327+
end
3328+
assert_predicate(th, :alive?)
33223329
w.write(data)
3323-
Thread.pass while th.alive?
33243330
th.join
33253331
end
33263332
assert_equal(data, buf, bug6099)

0 commit comments

Comments
 (0)