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

ruby-changes:46906

From: normal <ko1@a...>
Date: Tue, 6 Jun 2017 09:13:52 +0900 (JST)
Subject: [ruby-changes:46906] normal:r59020 (trunk): IO#close: do not enqueue redundant interrupts

normal	2017-06-06 09:13:47 +0900 (Tue, 06 Jun 2017)

  New Revision: 59020

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59020

  Log:
    IO#close: do not enqueue redundant interrupts
    
    Enqueuing multiple errors for one event causes spurious errors
    down the line, as reported by Nikolay Vashchenko in
    https://bugs.ruby-lang.org/issues/13632
    
    * thread.c (rb_notify_fd_close): do not enqueue multiple interrupts
      [ruby-core:81581] [Bug #13632]
    * test/ruby/test_io.rb (test_single_exception_on_close):
      new test based on script from Nikolay

  Modified files:
    trunk/test/ruby/test_io.rb
    trunk/thread.c
Index: test/ruby/test_io.rb
===================================================================
--- test/ruby/test_io.rb	(revision 59019)
+++ test/ruby/test_io.rb	(revision 59020)
@@ -2823,6 +2823,28 @@ __END__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L2823
     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]'
Index: thread.c
===================================================================
--- thread.c	(revision 59019)
+++ thread.c	(revision 59020)
@@ -2213,6 +2213,8 @@ rb_notify_fd_close(int fd) https://github.com/ruby/ruby/blob/trunk/thread.c#L2213
 	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;

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

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