Skip to content

Instantly share code, notes, and snippets.

@thedarkone
Created December 5, 2012 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedarkone/5e08c309ad8b69b2a31b to your computer and use it in GitHub Desktop.
Save thedarkone/5e08c309ad8b69b2a31b to your computer and use it in GitHub Desktop.
Thread safe autoload test
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment