< :前の番号
^ :番号順リスト
> :次の番号
P :前の記事(スレッド移動)
N :次の記事(スレッド移動)
|<:前のスレッド
>|:次のスレッド
^ :返事先
_:自分への返事
>:同じ返事先を持つ記事(前)
<:同じ返事先を持つ記事(後)
---:分割してスレッド表示、再表示
| :分割して(縦)スレッド表示、再表示
~ :スレッドのフレーム消去
.:インデックス
..:インデックスのインデックス
Issue #8556 has been updated by headius (Charles Nutter).
Similar in nature to the "synchronized" module method proposed in https://bugs.ruby-lang.org/issues/8961. I like that proposal as well, but it does not help the case where you have a concurrency-unsafe object in hand that you would like to make concurrency-safe.
Another commenter on Twitter suggested that this is not the best way to go about making an object thread-safe, and he's right. It would be better to use immutable collections or explicitly concurrency-friendly collections. However, this is a simple pattern that works for all types of objects and makes it possible to start writing better threaded Ruby code today.
I would also like to note that this is helpful in MRI too, since the bodies of Ruby methods can context switch at any time. MRI also needs a better mechanism for saying "this class's methods should only be executed by one thread at a time".
----------------------------------------
Feature #8556: MutexedDelegator as a trivial way to make an object thread-safe
https://bugs.ruby-lang.org/issues/8556#change-42046
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/