dir.c: retry glob with GC
* dir.c (do_opendir): retry after GC when the limit for open file descriptors reached. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9590e99031
commit
5d20d347c7
@ -1,3 +1,8 @@
|
|||||||
|
Fri Oct 21 16:44:44 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Fri Oct 21 16:06:25 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* ruby.c (open_load_file): retry after GC when the limit for open
|
* ruby.c (open_load_file): retry after GC when the limit for open
|
||||||
|
15
dir.c
15
dir.c
@ -1286,8 +1286,19 @@ do_opendir(const char *path, int flags, rb_encoding *enc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
dirp = opendir(path);
|
dirp = opendir(path);
|
||||||
if (dirp == NULL && !to_be_ignored(errno))
|
if (!dirp) {
|
||||||
sys_warning(path, enc);
|
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
|
#ifdef _WIN32
|
||||||
if (tmp) rb_str_resize(tmp, 0); /* GC guard */
|
if (tmp) rb_str_resize(tmp, 0); /* GC guard */
|
||||||
#endif
|
#endif
|
||||||
|
@ -354,4 +354,18 @@ class TestDir < Test::Unit::TestCase
|
|||||||
assert_raise(Errno::ENOENT) {Dir.empty?(@nodir)}
|
assert_raise(Errno::ENOENT) {Dir.empty?(@nodir)}
|
||||||
assert_not_send([Dir, :empty?, File.join(@root, "b")])
|
assert_not_send([Dir, :empty?, File.join(@root, "b")])
|
||||||
end
|
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
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user