Forum: Ruby-dev [Rejected] allow to unlock mutex locked by another thread

C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 ko1 (Koichi Sasada) (Guest)
on 2012-10-26 22:43
(Received via mailing list)
Issue #3251 has been updated by ko1 (Koichi Sasada).

Status changed from Assigned to Rejected

小崎さん,ありがとうございます.
とりあえず,Mutex になんかするのは reject ということで,
すみませんが,整理して別 ticket としてください>遠藤さん
----------------------------------------
Feature #3251: allow to unlock mutex locked by another thread
https://bugs.ruby-lang.org/issues/3251#change-31650

Author: mame (Yusuke Endoh)
Status: Rejected
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0


=begin
 遠藤です。

 現状では mutex は lock したスレッドからしか unlock できませんが、
 これを許可するようにしませんか。動機は 2 つあります。

 1) Python の condition variable が mutex を別スレッドから unlock
    することで実装されている、のが真似できる
 2) 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
This topic is locked and can not be replied to.