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

ruby-changes:44394

From: nobu <ko1@a...>
Date: Fri, 21 Oct 2016 16:44:51 +0900 (JST)
Subject: [ruby-changes:44394] nobu:r56467 (trunk): dir.c: retry glob with GC

nobu	2016-10-21 16:44:46 +0900 (Fri, 21 Oct 2016)

  New Revision: 56467

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

  Log:
    dir.c: retry glob with GC
    
    * dir.c (do_opendir): retry after GC when the limit for open file
      descriptors reached.

  Modified files:
    trunk/ChangeLog
    trunk/dir.c
    trunk/test/ruby/test_dir.rb
Index: dir.c
===================================================================
--- dir.c	(revision 56466)
+++ dir.c	(revision 56467)
@@ -1286,8 +1286,19 @@ do_opendir(const char *path, int flags, https://github.com/ruby/ruby/blob/trunk/dir.c#L1286
     }
 #endif
     dirp = opendir(path);
-    if (dirp == NULL && !to_be_ignored(errno))
-	sys_warning(path, enc);
+    if (!dirp) {
+	int e = errno;
+	switch (rb_gc_for_fd(e)) {
+	  default:
+	    dirp = opendir(path);
+	    if (dirp) break;
+	    e = errno;
+	    /* fallback */
+	  case 0:
+	    if (to_be_ignored(e)) break;
+	    sys_warning(path, enc);
+	}
+    }
 #ifdef _WIN32
     if (tmp) rb_str_resize(tmp, 0); /* GC guard */
 #endif
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 56466)
+++ ChangeLog	(revision 56467)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Oct 21 16:44:44 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* dir.c (do_opendir): retry after GC when the limit for open file
+	  descriptors reached.
+
 Fri Oct 21 16:06:25 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* ruby.c (open_load_file): retry after GC when the limit for open
Index: test/ruby/test_dir.rb
===================================================================
--- test/ruby/test_dir.rb	(revision 56466)
+++ test/ruby/test_dir.rb	(revision 56467)
@@ -354,4 +354,18 @@ class TestDir < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_dir.rb#L354
     assert_raise(Errno::ENOENT) {Dir.empty?(@nodir)}
     assert_not_send([Dir, :empty?, File.join(@root, "b")])
   end
+
+  def test_glob_gc_for_fd
+    assert_separately(["-C", @root], "#{<<-"begin;"}\n#{<<-"end;"}", timeout: 3)
+    begin;
+      Process.setrlimit(Process::RLIMIT_NOFILE, 50)
+      begin
+        tap {tap {tap {(0..100).map {open(IO::NULL)}}}}
+      rescue Errno::EMFILE
+      end
+      list = Dir.glob("*").sort
+      assert_not_empty(list)
+      assert_equal([*"a".."z"], list)
+    end;
+  end
 end

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

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