Eric Wong normalperson@yhbt.net wrote:
Testing the following:
Sorry, bad patch. The big rescue/ensure clauses was hiding bugs.
The problem is th.stop? happens twice:
1) release GVL for read() => EAGAIN
2) release GVL for rb_io_wait_readable()
We only accounted for one case in the previous code (and it is
unpredictable which).
I'm confident about the following patch:
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2866,24 +2866,29 @@ End
data = "a" * 100
th = nil
with_pipe do |r,w|
r.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
th = Thread.new {r.readpartial(100, buf)}
Thread.pass until th.stop?
assert_empty(buf, bug6099)
assert_predicate(th, :alive?)
Thread.pass while th.alive?
end
assert_equal(data, buf, bug6099)
rescue RuntimeError # can't modify string; temporarily locked
ensure
if th
begin
r.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
th = Thread.new {r.readpartial(100, buf)}
Thread.pass until th.stop?
assert_equal 100, buf.bytesize
assert_match(/can't modify string; temporarily locked/, e.message)
assert_empty(buf, bug6099)
assert_predicate(th, :alive?)
Thread.pass while th.alive?
th.join
assert_equal(data, buf, bug6099)
end