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

ruby-changes:52270

From: normal <ko1@a...>
Date: Mon, 20 Aug 2018 10:43:17 +0900 (JST)
Subject: [ruby-changes:52270] normal:r64478 (trunk): spec/ruby/core/io/select_spec.rb: workaround stuck IO.select

normal	2018-08-20 10:43:10 +0900 (Mon, 20 Aug 2018)

  New Revision: 64478

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

  Log:
    spec/ruby/core/io/select_spec.rb: workaround stuck IO.select
    
    Under pipe page memory pressure on Linux, a pipe may only be
    created with a single buffer[1].  And as of Linux v4.18, the
    fs/pipe.c::pipe_poll callback does not account for merging
    done in fs/pipe::pipe_write; only the number of usable buffers
    in the pipe.  Thus it is possible for a pipe to be writable
    (if only by a small amount) despite IO.select saying it is not.
    
    With the default 16384 /proc/sys/fs/pipe-user-pages-soft value
    and the pipe having 16 pages of buffers, this issue is trivially
    reproducible by creating 1024 pipes in a background process
    before running the spec:
    
      $ ulimit -n 2053 # or something higher
      $ ./miniruby -e '1024.times.map { IO.pipe }; sleep' &
      $ make test-spec MSPECOPT=spec/ruby/core/io/select_spec.rb
    
    So, we create a new pipe we never write to for testing
    writability of IO.select.  This may cause the test to fail with
    ENFILE on an overloaded system, but at least that's an obvious
    failure (unlike having a test get stuck).  This should reduce
    failures on our overloaded CI machines:
    
       http://ci.rvm.jp/results/trunk-nopara@silicon-docker/1239426
    
    [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/pipe.c?h=v4.18#n642

  Modified files:
    trunk/spec/ruby/core/io/select_spec.rb
Index: spec/ruby/core/io/select_spec.rb
===================================================================
--- spec/ruby/core/io/select_spec.rb	(revision 64477)
+++ spec/ruby/core/io/select_spec.rb	(revision 64478)
@@ -16,8 +16,10 @@ describe "IO.select" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/io/select_spec.rb#L16
 
   it "returns immediately all objects that are ready for I/O when timeout is 0" do
     @wr.syswrite("be ready")
-    result = IO.select [@rd], [@wr], nil, 0
-    result.should == [[@rd], [@wr], []]
+    IO.pipe do |_, wr|
+      result = IO.select [@rd], [wr], nil, 0
+      result.should == [[@rd], [wr], []]
+    end
   end
 
   it "returns nil after timeout if there are no objects ready for I/O" do
@@ -70,9 +72,11 @@ describe "IO.select" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/io/select_spec.rb#L72
     obj.should_receive(:to_io).at_least(1).and_return(@rd)
     IO.select([obj]).should == [[obj], [], []]
 
-    obj = mock("write_io")
-    obj.should_receive(:to_io).at_least(1).and_return(@wr)
-    IO.select(nil, [obj]).should == [[], [obj], []]
+    IO.pipe do |_, wr|
+      obj = mock("write_io")
+      obj.should_receive(:to_io).at_least(1).and_return(wr)
+      IO.select(nil, [obj]).should == [[], [obj], []]
+    end
   end
 
   it "raises TypeError if supplied objects are not IO" do

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

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