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

ruby-changes:45987

From: nagachika <ko1@a...>
Date: Wed, 22 Mar 2017 23:01:12 +0900 (JST)
Subject: [ruby-changes:45987] nagachika:r58058 (ruby_2_3): merge revision(s) 57199, 57202, 57206, 57224: [Backport #13076]

nagachika	2017-03-22 23:01:06 +0900 (Wed, 22 Mar 2017)

  New Revision: 58058

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

  Log:
    merge revision(s) 57199,57202,57206,57224: [Backport #13076]
    
    io.c: fix race between read and close
    
    * io.c (io_fillbuf): fix race between read and close, in the case
      the IO gets closed before the reading thread achieve the lock.
      [ruby-core:78845] [Bug #13076]
    thread.c: fix race between read and close
    
    * thread.c (rb_thread_fd_close): wait until all threads using the
      fd finish the operation, not to free the buffer in use.
      [ruby-core:78845] [Bug #13076]
    revert a part of r57199
    
    * io.c (io_fillbuf): revert a part of r57199 because it broke IO#getch.
      see also [Bug #13076]
    
    io.c: fix race between read and close
    
    * io.c (io_fillbuf): fix race between read and close and bail out
      in the case the IO gets closed before the reading thread achieve
      the lock.  [ruby-core:78845] [Bug #13076]

  Modified directories:
    branches/ruby_2_3/
  Modified files:
    branches/ruby_2_3/io.c
    branches/ruby_2_3/test/ruby/test_io.rb
    branches/ruby_2_3/thread.c
    branches/ruby_2_3/version.h
Index: ruby_2_3/io.c
===================================================================
--- ruby_2_3/io.c	(revision 58057)
+++ ruby_2_3/io.c	(revision 58058)
@@ -431,7 +431,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd https://github.com/ruby/ruby/blob/trunk/ruby_2_3/io.c#L431
     if (!READ_DATA_PENDING(fptr)) {\
 	WAIT_FD_IN_WIN32(fptr);\
 	rb_io_check_closed(fptr);\
-     }\
+    }\
 } while(0)
 
 #ifndef S_ISSOCK
@@ -1781,6 +1781,7 @@ io_fillbuf(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/ruby_2_3/io.c#L1781
 		rb_syserr_fail_path(e, path);
 	    }
         }
+	if (r > 0) rb_io_check_closed(fptr);
         fptr->rbuf.off = 0;
         fptr->rbuf.len = (int)r; /* r should be <= rbuf_capa */
         if (r == 0)
Index: ruby_2_3/thread.c
===================================================================
--- ruby_2_3/thread.c	(revision 58057)
+++ ruby_2_3/thread.c	(revision 58058)
@@ -2173,14 +2173,22 @@ rb_thread_fd_close(int fd) https://github.com/ruby/ruby/blob/trunk/ruby_2_3/thread.c#L2173
 {
     rb_vm_t *vm = GET_THREAD()->vm;
     rb_thread_t *th = 0;
+    int busy;
 
+  retry:
+    busy = 0;
     list_for_each(&vm->living_threads, th, vmlt_node) {
 	if (th->waiting_fd == fd) {
 	    VALUE err = th->vm->special_exceptions[ruby_error_closed_stream];
 	    rb_threadptr_pending_interrupt_enque(th, err);
 	    rb_threadptr_interrupt(th);
+	    busy = 1;
 	}
     }
+    if (busy) {
+	rb_thread_schedule_limits(0);
+	goto retry;
+    }
 }
 
 /*
Index: ruby_2_3/version.h
===================================================================
--- ruby_2_3/version.h	(revision 58057)
+++ ruby_2_3/version.h	(revision 58058)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_3/version.h#L1
 #define RUBY_VERSION "2.3.3"
 #define RUBY_RELEASE_DATE "2017-03-22"
-#define RUBY_PATCHLEVEL 256
+#define RUBY_PATCHLEVEL 257
 
 #define RUBY_RELEASE_YEAR 2017
 #define RUBY_RELEASE_MONTH 3
Index: ruby_2_3/test/ruby/test_io.rb
===================================================================
--- ruby_2_3/test/ruby/test_io.rb	(revision 58057)
+++ ruby_2_3/test/ruby/test_io.rb	(revision 58058)
@@ -3285,4 +3285,34 @@ End https://github.com/ruby/ruby/blob/trunk/ruby_2_3/test/ruby/test_io.rb#L3285
       end
     end
   end if File::BINARY != 0
+
+  def test_race_gets_and_close
+    assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+    bug13076 = '[ruby-core:78845] [Bug #13076]'
+    begin;
+      100.times do |i|
+        a = []
+        t = []
+        10.times do
+          r,w = IO.pipe
+          a << [r,w]
+          t << Thread.new do
+            begin
+              while r.gets
+              end
+            rescue IOError
+            end
+          end
+        end
+        a.each do |r,w|
+          w.puts "hoge"
+          w.close
+          r.close
+        end
+        assert_nothing_raised(IOError, bug13076) {
+          t.each(&:join)
+        }
+      end
+    end;
+  end
 end

Property changes on: ruby_2_3
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r57199,57202,57206,57224


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

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