diff --git a/judge/scripts/lib/dir_init.rb b/judge/scripts/lib/dir_init.rb deleted file mode 100644 --- a/judge/scripts/lib/dir_init.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'ftools' - -# DirInit::Manager handles directory initialization and clean-up when -# there are many concurrent processes that wants to modify the -# directory in the same way. -# -# An example usage is when each process wants to copy some temporary -# files to the directory and delete these files after finishing its -# job. Problems may occur when the first process delete the files -# while the second process is still using the files. -# -# This library maintain a reference counter on the processes using the -# directory. It locks the dir to manage critical section when -# updating the reference counter. -# -# Example usage: -# -# dman = DirInit::Manager.new("mydir") -# -# dman.setup do -# # do some initialization -# end -# -# #... do anything you want -# -# dman.teardown do -# # clean up -# end -# -# DirInit::Manager ensures that the block passed to setup -# only runs once by the first process in the concurrent dir usage and -# block passed to teardown runs once by the last process in -# that concurrent activities leaving that dir. - -module DirInit - - class Manager - - def initialize(dir_name, usage_filename='.usage_counter') - @dir_name = dir_name - @usage_filename = usage_filename - end - - # Check if someone has initialized the dir. If not, call block. - - def setup # :yields: block - dir = File.new(@dir_name) - dir.flock(File::LOCK_EX) - begin - counter_filename = get_counter_filename - if File.exist? counter_filename - # someone is here - f = File.new(counter_filename,"r+") - counter = f.read.to_i - f.seek(0) - f.write("#{counter+1}\n") - f.close - else - # i'm the first, create the counter file - counter = 0 - f = File.new(counter_filename,"w") - f.write("1\n") - f.close - end - - # if no one is here - if counter == 0 - if block_given? - yield - end - end - - rescue - raise - - ensure - # make sure it unlock the directory - dir.flock(File::LOCK_UN) - end - end - - # Check if I am the last one using the dir. If true, call block. - - def teardown - dir = File.new(@dir_name) - dir.flock(File::LOCK_EX) - begin - counter_filename = get_counter_filename - if File.exist? counter_filename - # someone is here - f = File.new(counter_filename,"r+") - counter = f.read.to_i - f.seek(0) - f.write("#{counter-1}\n") - f.close - - if counter == 1 - # i'm the last one - - File.delete(counter_filename) - if block_given? - yield - end - end - else - # This is BAD - raise "Error: reference count missing" - end - - rescue - raise - - ensure - # make sure it unlock the directory - dir.flock(File::LOCK_UN) - end - end - - protected - - def get_counter_filename - return File.join(@dir_name,@usage_filename) - end - - end -end