Bug #11683 ยป 0001-Add-waiting-for-autoload-in-rb_const_defined_0.patch
test/ruby/test_autoload.rb | ||
---|---|---|
end
|
||
end
|
||
def test_defined_with_autoload
|
||
ruby_impl_require do |called_with|
|
||
Tempfile.create(%w(autoload .rb)) do |file|
|
||
file.puts "class AutoloadTest; module B; end; end"
|
||
file.flush
|
||
add_autoload(file.path)
|
||
begin
|
||
thrs = []
|
||
2.times do
|
||
thrs << Thread.new do
|
||
Thread.pass; assert_equal("constant", defined? Object::AutoloadTest::B)
|
||
end
|
||
end
|
||
thrs.each(&:join)
|
||
ensure
|
||
remove_autoload_constant
|
||
end
|
||
assert_equal [file.path], called_with.uniq
|
||
end
|
||
end
|
||
end
|
||
def add_autoload(path)
|
||
(@autoload_paths ||= []) << path
|
||
::Object.class_eval {autoload(:AutoloadTest, path)}
|
variable.c | ||
---|---|---|
return (int)Qfalse;
|
||
}
|
||
if (ce->value == Qundef && !check_autoload_required(tmp, id, 0) &&
|
||
!rb_autoloading_value(tmp, id, 0))
|
||
!rb_autoloading_value(tmp, id, 0)) {
|
||
VALUE load;
|
||
struct autoload_data_i *ele;
|
||
struct autoload_state state;
|
||
if (!(load = autoload_data(tmp, id)) ||
|
||
!(ele = check_autoload_data(load))) {
|
||
return (int)Qfalse;
|
||
}
|
||
state.thread = rb_thread_current();
|
||
if (ele->state && (ele->state->thread != state.thread)) {
|
||
list_add_tail(&ele->state->waitq.head, &state.waitq.node);
|
||
/*
|
||
* autoload_reset in other thread will resume us and remove us
|
||
* from the waitq list
|
||
*/
|
||
do {
|
||
rb_thread_sleep_deadly();
|
||
} while (state.thread != Qfalse);
|
||
/* retry to look up the autoloaded constant. */
|
||
continue;
|
||
}
|
||
return (int)Qfalse;
|
||
}
|
||
return (int)Qtrue;
|
||
}
|
||
if (!recurse) break;
|