aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/ruby/test_io.rb22
-rw-r--r--thread.c2
2 files changed, 24 insertions, 0 deletions
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 2cd60a4fca..791e52b500 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2823,6 +2823,28 @@ __END__
end;
end
+ def test_single_exception_on_close
+ a = []
+ t = []
+ 10.times do
+ r, w = IO.pipe
+ a << [r, w]
+ t << Thread.new do
+ while r.gets
+ end rescue IOError
+ Thread.current.pending_interrupt?
+ end
+ end
+ a.each do |r, w|
+ w.write -"\n"
+ w.close
+ r.close
+ end
+ t.each do |th|
+ assert_equal false, th.value, '[ruby-core:81581] [Bug #13632]'
+ end
+ end
+
def test_open_mode
feature4742 = "[ruby-core:36338]"
bug6055 = '[ruby-dev:45268]'
diff --git a/thread.c b/thread.c
index da834974bd..42159b3c19 100644
--- a/thread.c
+++ b/thread.c
@@ -2213,6 +2213,8 @@ rb_notify_fd_close(int fd)
if (wfd->fd == fd) {
rb_thread_t *th = wfd->th;
VALUE err = th->vm->special_exceptions[ruby_error_stream_closed];
+
+ wfd->fd = -1; /* ensure we only enqueue once */
rb_threadptr_pending_interrupt_enque(th, err);
rb_threadptr_interrupt(th);
busy = 1;