Feature #3251
closedallow to unlock mutex locked by another thread
Description
=begin
遠藤です。
現状では mutex は lock したスレッドからしか unlock できませんが、
これを許可するようにしませんか。動機は 2 つあります。
- Python の condition variable が mutex を別スレッドから unlock
することで実装されている、のが真似できる - Thread#raise を race condition なしに使えるようになる (気がする)
1 について、Python の condition variable は以下のような感じに実装
されています。
def wait(m1)
m2 = Mutex.new
m2.lock
@waiters << m2
m1.unlock
begin
m2.lock
ensure
m1.lock
end
end
def signal
@waiters.shift.unlock
end
つまり、wait は二重に mutex を lock しようとすることでブロックし、
signal は mutex を別スレッドから unlock することでブロックしている
スレッドを再開します。
今の ConditionVariable の実装には大量の問題点が指摘されているので、
Python の真似をするとよいのではと思います。
権威主義¶
2 について、現状は Thread#raise には以下のような race が存在します。
t1: begin 節を実行している
t2: t1.raise する
t1: rescue/ensure 節の実行を開始する
t3: t1.raise する
t1: rescue/ensure 節が実行されないまま再度例外が発生する
ちなみにこの race はシグナルにも存在します¶
これを、Thread#raise の前に Mutex#lock するというルールにすれば、
race を避けて使うことができるようになります。と思います。
t1: begin 節を実行している
t2: m.lock; t1.raise する
t1: rescue/ensure 節の実行を開始する
t3: m.lock が止まらないので t1.raise できない
t1: 次の例外が投げ込まれる準備ができたら m.unlock する
t3: m.lock が終わって t1.raise する
--
Yusuke Endoh mame@tsg.ne.jp
=end