[Feature #20244] Show the conflicting another chdir block
This commit is contained in:
parent
8fe86feecd
commit
4bb8f8582f
13
dir.c
13
dir.c
@ -1043,14 +1043,20 @@ dir_chdir0(VALUE path)
|
|||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
VALUE thread;
|
VALUE thread;
|
||||||
|
VALUE path;
|
||||||
|
int line;
|
||||||
int blocking;
|
int blocking;
|
||||||
} chdir_lock = {
|
} chdir_lock = {
|
||||||
.blocking = 0, .thread = Qnil,
|
.blocking = 0, .thread = Qnil,
|
||||||
|
.path = Qnil, .line = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chdir_enter(void)
|
chdir_enter(void)
|
||||||
{
|
{
|
||||||
|
if (chdir_lock.blocking == 0) {
|
||||||
|
chdir_lock.path = rb_source_location(&chdir_lock.line);
|
||||||
|
}
|
||||||
chdir_lock.blocking++;
|
chdir_lock.blocking++;
|
||||||
if (NIL_P(chdir_lock.thread)) {
|
if (NIL_P(chdir_lock.thread)) {
|
||||||
chdir_lock.thread = rb_thread_current();
|
chdir_lock.thread = rb_thread_current();
|
||||||
@ -1063,6 +1069,8 @@ chdir_leave(void)
|
|||||||
chdir_lock.blocking--;
|
chdir_lock.blocking--;
|
||||||
if (chdir_lock.blocking == 0) {
|
if (chdir_lock.blocking == 0) {
|
||||||
chdir_lock.thread = Qnil;
|
chdir_lock.thread = Qnil;
|
||||||
|
chdir_lock.path = Qnil;
|
||||||
|
chdir_lock.line = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1075,6 +1083,9 @@ chdir_alone_block_p(void)
|
|||||||
rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block");
|
rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block");
|
||||||
if (!block_given) {
|
if (!block_given) {
|
||||||
rb_warn("conflicting chdir during another chdir block");
|
rb_warn("conflicting chdir during another chdir block");
|
||||||
|
if (!NIL_P(chdir_lock.path)) {
|
||||||
|
rb_compile_warn(RSTRING_PTR(chdir_lock.path), chdir_lock.line, "here");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return block_given;
|
return block_given;
|
||||||
@ -3640,6 +3651,8 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname)
|
|||||||
void
|
void
|
||||||
Init_Dir(void)
|
Init_Dir(void)
|
||||||
{
|
{
|
||||||
|
rb_gc_register_address(&chdir_lock.path);
|
||||||
|
|
||||||
rb_cDir = rb_define_class("Dir", rb_cObject);
|
rb_cDir = rb_define_class("Dir", rb_cObject);
|
||||||
|
|
||||||
rb_include_module(rb_cDir, rb_mEnumerable);
|
rb_include_module(rb_cDir, rb_mEnumerable);
|
||||||
|
@ -104,22 +104,23 @@ class TestDir < Test::Unit::TestCase
|
|||||||
assert_raise(ArgumentError) { Dir.chdir }
|
assert_raise(ArgumentError) { Dir.chdir }
|
||||||
ENV["HOME"] = pwd
|
ENV["HOME"] = pwd
|
||||||
Dir.chdir do
|
Dir.chdir do
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
|
conflicting = /conflicting chdir during another chdir block\n^#{Regexp.quote(__FILE__)}:#{__LINE__-1}:/
|
||||||
|
assert_warning(conflicting) { Dir.chdir(pwd) }
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(@root) }
|
assert_warning(conflicting) { Dir.chdir(@root) }
|
||||||
assert_equal(@root, Dir.pwd)
|
assert_equal(@root, Dir.pwd)
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
|
assert_warning(conflicting) { Dir.chdir(pwd) }
|
||||||
|
|
||||||
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; Dir.chdir(@root) }.join }
|
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; Dir.chdir(@root) }.join }
|
||||||
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; Dir.chdir(@root) { } }.join }
|
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; Dir.chdir(@root) { } }.join }
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
|
assert_warning(conflicting) { Dir.chdir(pwd) }
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(@root) }
|
assert_warning(conflicting) { Dir.chdir(@root) }
|
||||||
assert_equal(@root, Dir.pwd)
|
assert_equal(@root, Dir.pwd)
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
|
assert_warning(conflicting) { Dir.chdir(pwd) }
|
||||||
Dir.chdir(@root) do
|
Dir.chdir(@root) do
|
||||||
assert_equal(@root, Dir.pwd)
|
assert_equal(@root, Dir.pwd)
|
||||||
end
|
end
|
||||||
@ -142,23 +143,25 @@ class TestDir < Test::Unit::TestCase
|
|||||||
|
|
||||||
ENV["HOME"] = pwd
|
ENV["HOME"] = pwd
|
||||||
ret = root_dir.chdir do |*a|
|
ret = root_dir.chdir do |*a|
|
||||||
|
conflicting = /conflicting chdir during another chdir block\n^#{Regexp.quote(__FILE__)}:#{__LINE__-1}:/
|
||||||
|
|
||||||
assert_empty(a)
|
assert_empty(a)
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { dir.chdir }
|
assert_warning(conflicting) { dir.chdir }
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { root_dir.chdir }
|
assert_warning(conflicting) { root_dir.chdir }
|
||||||
|
|
||||||
assert_equal(@root, Dir.pwd)
|
assert_equal(@root, Dir.pwd)
|
||||||
|
|
||||||
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; dir.chdir }.join }
|
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; dir.chdir }.join }
|
||||||
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; dir.chdir{} }.join }
|
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; dir.chdir{} }.join }
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { dir.chdir }
|
assert_warning(conflicting) { dir.chdir }
|
||||||
assert_equal(pwd, Dir.pwd)
|
assert_equal(pwd, Dir.pwd)
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { root_dir.chdir }
|
assert_warning(conflicting) { root_dir.chdir }
|
||||||
assert_equal(@root, Dir.pwd)
|
assert_equal(@root, Dir.pwd)
|
||||||
|
|
||||||
assert_warning(/conflicting chdir during another chdir block/) { dir.chdir }
|
assert_warning(conflicting) { dir.chdir }
|
||||||
|
|
||||||
root_dir.chdir do
|
root_dir.chdir do
|
||||||
assert_equal(@root, Dir.pwd)
|
assert_equal(@root, Dir.pwd)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user