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

ruby-changes:45126

From: nobu <ko1@a...>
Date: Mon, 26 Dec 2016 23:14:24 +0900 (JST)
Subject: [ruby-changes:45126] nobu:r57199 (trunk): io.c: fix race between read and close

nobu	2016-12-26 23:14:18 +0900 (Mon, 26 Dec 2016)

  New Revision: 57199

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

  Log:
    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]

  Modified files:
    trunk/io.c
    trunk/test/ruby/test_io.rb
Index: io.c
===================================================================
--- io.c	(revision 57198)
+++ io.c	(revision 57199)
@@ -424,7 +424,7 @@ rb_cloexec_fcntl_dupfd(int fd, int minfd https://github.com/ruby/ruby/blob/trunk/io.c#L424
     if (!READ_DATA_PENDING(fptr)) {\
 	WAIT_FD_IN_WIN32(fptr);\
 	rb_io_check_closed(fptr);\
-     }\
+    }\
 } while(0)
 
 #ifndef S_ISSOCK
@@ -1775,6 +1775,7 @@ io_fillbuf(rb_io_t *fptr) https://github.com/ruby/ruby/blob/trunk/io.c#L1775
 		rb_syserr_fail_path(e, path);
 	    }
         }
+	if (r > 0) READ_CHECK(fptr);
         fptr->rbuf.off = 0;
         fptr->rbuf.len = (int)r; /* r should be <= rbuf_capa */
         if (r == 0)
Index: test/ruby/test_io.rb
===================================================================
--- test/ruby/test_io.rb	(revision 57198)
+++ test/ruby/test_io.rb	(revision 57199)
@@ -3366,6 +3366,36 @@ __END__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L3366
     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
+
   if RUBY_ENGINE == "ruby" # implementation details
     def test_foreach_rs_conversion
       make_tempfile {|t|

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

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