Issue #8556 has been reported by headius (Charles Nutter).

----------------------------------------
Feature #8556: MutexedDelegator as a trivial way to make an object thread-safe
https://bugs.ruby-lang.org/issues/8556

Author: headius (Charles Nutter)
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


I propose adding MutexedDelegator as a simple way to wrap any object with a thread-safe wrapper, via existing delegation logic in delegate.rb.

Delegator provides a way to pass method calls through to a wrapped object. SimpleDelegator is a trivial implementation that just holds the object in an instance variable. MutexedDelegator would extend SimpleDelegator and only override initialize and method_missing as follows:

class MutexedDelegator < SimpleDelegator
  def initialize(*)
    super
    @mutex = Mutex.new
  end
  
  def method_missing(m, *args, &block)
    target, mutex = self.__getobj__, @mutex
    begin
      mutex.lock
      target.__send__(m, *args, &block)
    ensure
      mutex.unlock
    end
  end
end

The only changes here are:

* Mutex#lock and unlock logic wrapping the send
* No respond_to? check; I'm not sure why it's there to begin with, since if we're in method_missing the super() call will fail just like a normal method_missing failure anyway
* No backtrace manipulation. This does not work on JRuby and Rubinius anyway, and in this case I feel that the delegator should not hide itself, since there's real behavior change happening.

This is a trivial addition to stdlib that would make it simple to synchronize all calls to a given object in the same way as the JDK's Collections.synchronizedSet/Map/List calls.


-- 
http://bugs.ruby-lang.org/