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

ruby-changes:31403

From: usa <ko1@a...>
Date: Thu, 31 Oct 2013 23:03:30 +0900 (JST)
Subject: [ruby-changes:31403] usa:r43482 (ruby_1_9_3): merge revision(s) 43112, 43114, 43117, 43118: [Backport #8980]

usa	2013-10-31 23:03:20 +0900 (Thu, 31 Oct 2013)

  New Revision: 43482

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43482

  Log:
    merge revision(s) 43112,43114,43117,43118: [Backport #8980]
    
    * io.c (rb_io_close_read): keep fptr in write_io to be discarded, to
      fix freed pointer access when it is in use by other threads, and get
      rid of potential memory/fd leak.
    
    * io.c (rb_io_close_write): detach tied IO for writing before closing
      to get rid of race condition.  [ruby-list:49598]
    
    * io.c (rb_io_close_read): duplex IO should wait its child process
      even after close_read.

  Modified directories:
    branches/ruby_1_9_3/
  Modified files:
    branches/ruby_1_9_3/ChangeLog
    branches/ruby_1_9_3/io.c
    branches/ruby_1_9_3/test/ruby/test_io.rb
    branches/ruby_1_9_3/version.h
Index: ruby_1_9_3/ChangeLog
===================================================================
--- ruby_1_9_3/ChangeLog	(revision 43481)
+++ ruby_1_9_3/ChangeLog	(revision 43482)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/ChangeLog#L1
+Thu Oct 31 22:49:56 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* io.c (rb_io_close_read): duplex IO should wait its child process
+	  even after close_read.
+
+Thu Oct 31 22:49:56 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* io.c (rb_io_close_read): keep fptr in write_io to be discarded, to
+	  fix freed pointer access when it is in use by other threads, and get
+	  rid of potential memory/fd leak.
+
 Mon Sep  2 17:21:47 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/date/date_parse.c (rfc2822_cb): check if wday is given, since it
Index: ruby_1_9_3/io.c
===================================================================
--- ruby_1_9_3/io.c	(revision 43481)
+++ ruby_1_9_3/io.c	(revision 43482)
@@ -4064,11 +4064,16 @@ rb_io_close_read(VALUE io) https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/io.c#L4064
     write_io = GetWriteIO(io);
     if (io != write_io) {
 	rb_io_t *wfptr;
-        rb_io_fptr_cleanup(fptr, FALSE);
 	GetOpenFile(write_io, wfptr);
+	wfptr->pid = fptr->pid;
+	fptr->pid = 0;
         RFILE(io)->fptr = wfptr;
-        RFILE(write_io)->fptr = NULL;
-        rb_io_fptr_finalize(fptr);
+	/* bind to write_io temporarily to get rid of memory/fd leak */
+	fptr->tied_io_for_writing = 0;
+	fptr->mode &= ~FMODE_DUPLEX;
+	RFILE(write_io)->fptr = fptr;
+	rb_io_fptr_cleanup(fptr, FALSE);
+	/* should not finalize fptr because another thread may be reading it */
         return Qnil;
     }
 
@@ -4124,12 +4129,12 @@ rb_io_close_write(VALUE io) https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/io.c#L4129
 	rb_raise(rb_eIOError, "closing non-duplex IO for writing");
     }
 
-    rb_io_close(write_io);
     if (io != write_io) {
 	GetOpenFile(io, fptr);
 	fptr->tied_io_for_writing = 0;
 	fptr->mode &= ~FMODE_DUPLEX;
     }
+    rb_io_close(write_io);
     return Qnil;
 }
 
Index: ruby_1_9_3/version.h
===================================================================
--- ruby_1_9_3/version.h	(revision 43481)
+++ ruby_1_9_3/version.h	(revision 43482)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/version.h#L1
 #define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 470
+#define RUBY_PATCHLEVEL 471
 
-#define RUBY_RELEASE_DATE "2013-09-02"
+#define RUBY_RELEASE_DATE "2013-10-31"
 #define RUBY_RELEASE_YEAR 2013
-#define RUBY_RELEASE_MONTH 9
-#define RUBY_RELEASE_DAY 2
+#define RUBY_RELEASE_MONTH 10
+#define RUBY_RELEASE_DAY 31
 
 #include "ruby/version.h"
 
Index: ruby_1_9_3/test/ruby/test_io.rb
===================================================================
--- ruby_1_9_3/test/ruby/test_io.rb	(revision 43481)
+++ ruby_1_9_3/test/ruby/test_io.rb	(revision 43482)
@@ -1094,6 +1094,19 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/test/ruby/test_io.rb#L1094
     end
   end
 
+  def test_close_read_write_separately
+    bug = '[ruby-list:49598]'
+    (1..10).each do |i|
+      assert_nothing_raised(IOError, "#{bug} trying ##{i}") do
+        IO.popen(EnvUtil.rubybin, "r+") {|f|
+          th = Thread.new {f.close_write}
+          f.close_read
+          th.join
+        }
+      end
+    end
+  end
+
   def test_pid
     r, w = IO.pipe
     assert_equal(nil, r.pid)
@@ -1110,6 +1123,17 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/ruby_1_9_3/test/ruby/test_io.rb#L1123
     assert_raise(IOError) { pipe.pid }
   end
 
+  def tesst_pid_after_close_read
+    pid1 = pid2 = nil
+    IO.popen(["echo", ""], "r+") do |io|
+      pid1 = io.pid
+      io.close_read
+      pid2 = io.pid
+    end
+    assert_not_nil(pid1)
+    assert_equal(pid1, pid2)
+  end
+
   def make_tempfile
     t = Tempfile.new("test_io")
     t.binmode

Property changes on: ruby_1_9_3
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r43112,43114,43117-43118


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

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