From: "headius (Charles Nutter)" Date: 2013-10-02T02:13:13+09:00 Subject: [ruby-core:57553] [CommonRuby - Feature #8961] Synchronizable module to easily wrap methods in a mutex Issue #8961 has been updated by headius (Charles Nutter). nobu (Nobuyoshi Nakada) wrote: > headius (Charles Nutter) wrote: > > Maybe. I don't like the idea of exposing this mutex/monitor, since it could be modified or locked and never released. I would be more in favor of a "tap" form that synchronizes against the same internal monitor, similar to Java's "synchronized" keyword. > > > > obj.synchronized { thread-sensitive code here } > > Use MonitorMixin. Yeah, that's not a bad option from a pure-Ruby perspective. We could add "synchronized" to classes that include MonitorMixin, perhaps? * added to monitor.rb: module MonitorMixin module ClassMethods def synchronized(method) aliased = :"#{method}_without_synchronization" alias_method aliased, method define_method method do |*args, &block| mon_enter begin __send__(aliased, *args, &block) ensure mon_exit end end end end def self.included(base) base.extend(ClassMethods) end end class Foo include MonitorMixin synchronized def bar # ... end end ... My suggestion to have it be native on Module opened up the possibility of implementing it in a faster, native way. MonitorMixin has a very large perf hit on all impls right now, but especially MRI. See my benchmarks in https://github.com/ruby/ruby/pull/405#issuecomment-25417666 ---------------------------------------- Feature #8961: Synchronizable module to easily wrap methods in a mutex https://bugs.ruby-lang.org/issues/8961#change-42170 Author: tobiassvn (Tobias Svensson) Status: Open Priority: Normal Assignee: Category: Target version: =begin I propose a Synchronizable mixin to easily wrap methods in a mutex which works together with Ruby 2.1's method name symbols returned from '(({def}))'. The Mixin adds a new '(({synchronized}))' class method which would alias the referenced method and redefines the original method wrapped in a '(({synchronize do .. end}))' block. This is probably somewhat related and an alternative to #8556. --- Proof of concept (I've used Monitor here so potential users won't have to worry about reentrancy): require 'monitor' module Synchronizable module ClassMethods def synchronized(method) aliased = :"#{method}_without_synchronization" alias_method aliased, method define_method method do |*args, &block| monitor.synchronize do __send__(aliased, *args, &block) end end end end def monitor @monitor ||= Monitor.new end def self.included(base) base.extend(ClassMethods) end end class Foo include Synchronizable synchronized def bar # ... end end =end -- http://bugs.ruby-lang.org/