Skip to content

Commit fb34cc3

Browse files
committed
Add spec for thread-safe autoload
1 parent 3bf93a8 commit fb34cc3

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

spec/ruby/core/module/autoload_spec.rb

+14
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,20 @@ class ModuleSpecs::Autoload::Z < ModuleSpecs::Autoload::ZZ
903903
t2_exc.should be_nil
904904
end
905905

906+
it "blocks other threads until the file is done loading so no partial modules are seen" do
907+
ModuleSpecs::Autoload.autoload :ThreadSafe, fixture(__FILE__, "autoload_thread_safe.rb")
908+
barrier = ModuleSpecs::CyclicBarrier.new 2
909+
ScratchPad.record(barrier)
910+
911+
thread = Thread.new { # starts the autoload
912+
ModuleSpecs::Autoload::ThreadSafe.foo.should == 42
913+
}
914+
barrier.await
915+
ModuleSpecs::Autoload::ThreadSafe.foo.should == 42 # ThreadSafe should only be published once the whole file is loaded
916+
917+
thread.join
918+
end
919+
906920
# https://bugs.ruby-lang.org/issues/10892
907921
it "blocks others threads while doing an autoload" do
908922
file_path = fixture(__FILE__, "repeated_concurrent_autoload.rb")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module ModuleSpecs::Autoload
2+
class ThreadSafe
3+
def self.bar # to illustrate partial loading
4+
end
5+
6+
barrier = ScratchPad.recorded
7+
barrier.await
8+
9+
# the main thread should be waiting for this file to be fully loaded
10+
Thread.pass until Thread.main.stop?
11+
10.times do
12+
Thread.pass
13+
Thread.main.should.stop?
14+
end
15+
16+
def self.foo
17+
42
18+
end
19+
end
20+
end

spec/ruby/core/module/fixtures/classes.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ def extend_object(obj)
475475
end
476476

477477
class CyclicBarrier
478-
def initialize(count = 1)
478+
def initialize(count)
479479
@count = count
480480
@state = 0
481481
@mutex = Mutex.new

0 commit comments

Comments
 (0)