[ruby-core:64775] Re: [ruby-trunk - Bug #10193] [Closed] TestIO#test_readpartial_locktmp fails randomly

From: Eric Wong <normalperson@...>
Date: 2014-09-04 20:55:56 UTC
List: ruby-core #64775
Eric Wong <normalperson@yhbt.net> wrote:
> Testing the following:

Sorry, bad patch.  The big rescue/ensure clauses was hiding bugs.

The problem is th.stop? happens twice:

	1) release GVL for read() => EAGAIN
	2) release GVL for rb_io_wait_readable()

We only accounted for one case in the previous code (and it is
unpredictable which).

I'm confident about the following patch:

--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -2866,24 +2866,29 @@ End
     data = "a" * 100
     th = nil
     with_pipe do |r,w|
-      r.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
-      th = Thread.new {r.readpartial(100, buf)}
-      Thread.pass until th.stop?
-      buf.replace("")
-      assert_empty(buf, bug6099)
-      assert_predicate(th, :alive?)
-      w.write(data)
-      Thread.pass while th.alive?
-    end
-    assert_equal(data, buf, bug6099)
-  rescue RuntimeError # can't modify string; temporarily locked
-  ensure
-    if th
       begin
+        r.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
+        th = Thread.new {r.readpartial(100, buf)}
+
+        Thread.pass until th.stop?
+
+        assert_equal 100, buf.bytesize
+
+        begin
+          buf.replace("")
+        rescue RuntimeError => e
+          assert_match(/can't modify string; temporarily locked/, e.message)
+          Thread.pass
+        end until buf.empty?
+
+        assert_empty(buf, bug6099)
+        assert_predicate(th, :alive?)
+        w.write(data)
+        Thread.pass while th.alive?
         th.join
-      rescue IOError
       end
     end
+    assert_equal(data, buf, bug6099)
   end
 
   def test_advise_pipe

In This Thread

Prev Next