From 3eb68248e0c0495c4533792260c9262fcd2840af Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 19 Apr 2008 10:07:55 -0500 Subject: Adds Module#synchronize for easier method-level synchronization. --- .../lib/active_support/core_ext/module.rb | 1 + .../core_ext/module/synchronization.rb | 35 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 activesupport/lib/active_support/core_ext/module/synchronization.rb (limited to 'activesupport/lib/active_support/core_ext') diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb index 34fcbd124b..392ba99f4e 100644 --- a/activesupport/lib/active_support/core_ext/module.rb +++ b/activesupport/lib/active_support/core_ext/module.rb @@ -7,6 +7,7 @@ require 'active_support/core_ext/module/introspection' require 'active_support/core_ext/module/loading' require 'active_support/core_ext/module/aliasing' require 'active_support/core_ext/module/model_naming' +require 'active_support/core_ext/module/synchronization' class Module include ActiveSupport::CoreExt::Module::ModelNaming diff --git a/activesupport/lib/active_support/core_ext/module/synchronization.rb b/activesupport/lib/active_support/core_ext/module/synchronization.rb new file mode 100644 index 0000000000..bf7740f851 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/module/synchronization.rb @@ -0,0 +1,35 @@ +class Module + # Synchronize access around a method, delegating synchronization to a + # particular mutex. A mutex (either a Mutex, or any object that responds to + # #synchronize and yields to a block) must be provided as a final :with option. + # The :with option should be a symbol or string, and can represent a method, + # constant, or instance or class variable. + # Example: + # class SharedCache + # @@lock = Mutex.new + # def expire + # ... + # end + # synchronize :expire, :with => :@@lock + # end + def synchronize(*methods) + options = methods.extract_options! + unless options.is_a?(Hash) && with = options[:with] + raise ArgumentError, "Synchronization needs a mutex. Supply an options hash with a :with key as the last argument (e.g. synchronize :hello, :with => :@mutex)." + end + + methods.each do |method| + if instance_methods.include?("#{method}_without_synchronization") + raise ArgumentError, "#{method} is already synchronized. Double synchronization is not currently supported." + end + module_eval(<<-EOS, __FILE__, __LINE__) + def #{method}_with_synchronization(*args, &block) + #{with}.synchronize do + #{method}_without_synchronization(*args,&block) + end + end + EOS + alias_method_chain method, :synchronization + end + end +end \ No newline at end of file -- cgit v1.2.3