diff options
author | Nick <nick@nicksieger.com> | 2008-04-19 10:07:55 -0500 |
---|---|---|
committer | Nick Sieger <nick@nicksieger.com> | 2008-08-29 14:12:08 -0500 |
commit | 3eb68248e0c0495c4533792260c9262fcd2840af (patch) | |
tree | 01b4d30fd7e7a6a380928d3640f6a6d4a525118d /activesupport/lib/active_support | |
parent | 5879b15f23f080badedbbab7835eda8c2c748a52 (diff) | |
download | rails-3eb68248e0c0495c4533792260c9262fcd2840af.tar.gz rails-3eb68248e0c0495c4533792260c9262fcd2840af.tar.bz2 rails-3eb68248e0c0495c4533792260c9262fcd2840af.zip |
Adds Module#synchronize for easier method-level synchronization.
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r-- | activesupport/lib/active_support/core_ext/module.rb | 1 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/synchronization.rb | 35 |
2 files changed, 36 insertions, 0 deletions
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 |