From: nobu@... Date: 2017-04-06T02:21:19+00:00 Subject: [ruby-core:80586] [Ruby trunk Bug#13405][Rejected] IO#close raises "stream closed" Issue #13405 has been updated by nobu (Nobuyoshi Nakada). Status changed from Open to Rejected "closed stream" and "stream closed" are different. The former is raised when trying an operation on an IO which has been closed already. The latter is raised when the IO is closed in an operation by another thread. ---------------------------------------- Bug #13405: IO#close raises "stream closed" https://bugs.ruby-lang.org/issues/13405#change-64088 * Author: matthewd (Matthew Draper) * Status: Rejected * Priority: Normal * Assignee: * Target version: * ruby -v: * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- IO#close is supposed to ignore an IOError indicating the stream is already closed. Since #10153, however, it can raise the `ruby_error_closed_stream` special exception, because that exception's message is ["stream closed"](https://github.com/ruby/ruby/blob/6d77e28763ed17f75edf3b4072701b4dbd7644bb/thread.c#L4886) instead of ["closed stream"](https://github.com/ruby/ruby/blob/6d77e28763ed17f75edf3b4072701b4dbd7644bb/io.c#L4517). The fix seems easy -- the mismatched string should be updated to use the more common spelling, with something like: ~~~ diff diff --git a/test/lib/test/unit.rb b/test/lib/test/unit.rb index 6cb22e725a..d1efa5dcfd 100644 --- a/test/lib/test/unit.rb +++ b/test/lib/test/unit.rb @@ -228,7 +228,7 @@ def run(task,type) rescue Errno::EPIPE died rescue IOError - raise unless ["stream closed","closed stream"].include? $!.message + raise unless $!.message == "closed stream" died end end diff --git a/test/lib/test/unit/parallel.rb b/test/lib/test/unit/parallel.rb index 50d4427189..09a5530b04 100644 --- a/test/lib/test/unit/parallel.rb +++ b/test/lib/test/unit/parallel.rb @@ -61,7 +61,7 @@ def _run_suite(suite, type) # :nodoc: begin th.join rescue IOError - raise unless ["stream closed","closed stream"].include? $!.message + raise unless $!.message == "closed stream" end i.close diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index ca3f1e2d3b..5775e31dde 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -3411,7 +3411,7 @@ def test_race_closed_stream end sleep 0.01 r.close - assert_raise_with_message(IOError, /stream closed/) do + assert_raise_with_message(IOError, /closed stream/) do thread.join end assert_equal(true, closed, "#{bug13158}: stream should be closed") diff --git a/thread.c b/thread.c index 5d27681b40..4e6faf6dc8 100644 --- a/thread.c +++ b/thread.c @@ -4883,7 +4883,7 @@ Init_Thread(void) rb_define_method(rb_cThread, "name=", rb_thread_setname, 1); rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0); - rb_vm_register_special_exception(ruby_error_closed_stream, rb_eIOError, "stream closed"); + rb_vm_register_special_exception(ruby_error_closed_stream, rb_eIOError, "closed stream"); cThGroup = rb_define_class("ThreadGroup", rb_cObject); rb_define_alloc_func(cThGroup, thgroup_s_alloc); ~~~ ---- I can't work out how to prove this fixes the problem, however. :( [The existing test in `test_io.rb`](https://github.com/ruby/ruby/blob/6d77e28763ed17f75edf3b4072701b4dbd7644bb/test/ruby/test_io.rb#L3400) shows how to cause the special exception to be raised from `gets`, but I haven't managed to synthetically force `close` to raise it. I know it's possible, though: we're seeing this problem semi-frequently in the Rails test suite (e.g. https://travis-ci.org/rails/rails/jobs/218895049#L499) -- though it's partly hidden by #13239 when it occurs on 2.2 and 2.3. -- https://bugs.ruby-lang.org/ Unsubscribe: