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/