2 # Synchronize access around a method, delegating synchronization to a
3 # particular mutex. A mutex (either a Mutex, or any object that responds to
4 # #synchronize and yields to a block) must be provided as a final :with option.
5 # The :with option should be a symbol or string, and can represent a method,
6 # constant, or instance or class variable.
13 # synchronize :expire, :with => :@@lock
15 def synchronize(*methods
)
16 options
= methods
.extract_options
!
17 unless options
.is_a
?(Hash
) && with
= options
[:with]
18 raise ArgumentError
, "Synchronization needs a mutex. Supply an options hash with a :with key as the last argument (e.g. synchronize :hello, :with => :@mutex)."
21 methods
.each
do |method
|
22 aliased_method
, punctuation
= method
.to_s
.sub(/([?!=])$/, ''), $1
24 if method_defined
?("#{aliased_method}_without_synchronization#{punctuation}")
25 raise ArgumentError
, "#{method} is already synchronized. Double synchronization is not currently supported."
28 module_eval(<<-EOS, __FILE__, __LINE__)
29 def #{aliased_method}_with_synchronization#{punctuation}(*args, &block) # def expire_with_synchronization(*args, &block)
30 #{with}.synchronize do # @@lock.synchronize do
31 #{aliased_method}_without_synchronization#{punctuation}(*args, &block) # expire_without_synchronization(*args, &block)
36 alias_method_chain method
, :synchronization