secret
Last active

Thread safe autoload test

  • Download Gist
autoload_test.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
require 'thread'
require 'fileutils'
 
# Disregard the Latch/Barrier classes, they are unimportant
class Latch
def initialize(count = 1)
@count = count
@mutex = Mutex.new
@cond = ConditionVariable.new
end
 
def release
@mutex.synchronize do
@count -= 1 if @count > 0
@cond.broadcast if @count.zero?
end
end
 
def await
@mutex.synchronize do
@cond.wait @mutex if @count > 0
end
end
end
 
class Barrier < Latch
def await
@mutex.synchronize do
if @count.zero? # fall through
elsif @count > 0
@count -= 1
@count.zero? ? @cond.broadcast : @cond.wait(@mutex)
end
end
end
end
 
AUTOLOAD_DIR = '____autoload_test_dir'
COUNT = 10
THREAD_COUNT = 100
 
$LOAD_PATH << '.' unless $LOAD_PATH.include?('.')
 
def setup_autoload_modules
FileUtils.mkdir_p(AUTOLOAD_DIR)
mod_names = []
COUNT.times do |i|
mod_name = :"Mod#{i}"
file_name = "#{AUTOLOAD_DIR}/mod_#{i}.rb"
File.open(file_name, 'w') do |f|
f << <<-RUBY_EVAL
module #{mod_name}
sleep(0.3)
def self.foo
end
end
RUBY_EVAL
end
autoload mod_name, file_name.sub(/\.rb\Z/, '')
mod_names << mod_name
end
mod_names
end
 
begin
mod_names = setup_autoload_modules
barrier = Barrier.new(THREAD_COUNT)
(0..THREAD_COUNT).map do
Thread.new do
barrier.await
mod_names.each do |mod_name|
Object.const_get(mod_name).foo
end
end
end.map(&:join)
ensure
FileUtils.rm_r(AUTOLOAD_DIR) if File.directory?(AUTOLOAD_DIR)
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.