Issue #8556 has been updated by Koichi Sasada.

Status changed from Assigned to Rejected

Sorry for long absence.

> The only way to ever make +=, ||=, and others be atomic in Ruby proper would be to change the way they're parsed and potentially add a method that could be called. But this is even unpredictable because for variables, there's still no way to do it atomically.

inc/dec is only an example.

> But this is not possible to fix in current Ruby and all other languages I know don't guarantee any atomicity here either.

I believe ruby should move to non-sharing way. Performance on this approach is not so good, but enough I believe.


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

* Author: Charles Nutter
* Status: Rejected
* Priority: Normal
* Assignee: Koichi Sasada
* Target version: Ruby 2.1.0
----------------------------------------
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.




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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>