#!/usr/local/bin/ruby # RenLock -- filelock utility class # # usage: # # lock = RenLock.new(dir, basename) # lock.lock { # ... # } # # another usage: # # lock = RenLock.new(dir, basename) # lock.lock() # ... # lock.unlock() # class RenLockError < StandardError; end class RenLock attr_accessor :timeout, :times, :sleep_time ## default SLEEP_TIME = 1 TIMEOUT = 30 TRY_TIMES = 5 def initialize(dir, basename) @dir, @basename = dir, basename @timeout = TIMEOUT @times = TRY_TIMES @sleep_time = SLEEP_TIME @current = nil @path = @dir+'/'+@basename end def lock() @times.times{ begin @current = current() File.rename(@path, @current) if iterator? begin yield ensure unlock() end end return true rescue sleep @sleep_time end } delete_oldlock() end def delete_oldlock() @path = @dir+'/'+@basename Dir.foreach(@dir){|file| if file =~ /#{@basename}(\d+)/ @current = current() if (Time.now.to_i - $1.to_i > @timeout) begin File.rename(@dir+'/'+file, @current) if iterator? begin yield ensure unlock() end end return true rescue # noop end end raise RenLockError end } raise RenLockError end private :delete_oldlock def current() @path + Time.now.to_i.to_s end private :current def unlock() begin File.rename(@current, @path) rescue # noop end end end ## class RenLock __END__ # Copyright 2001 TAKAHASHI 'Maki' Masayoshi (maki@open-news.com) # all right reserved. # # This script are released under the same terms as Ruby. # # Special Thanks to: # OHZAKI Hiroki (`Perl memo' site) # http://www.din.or.jp/~ohzaki/perl.htm