From: "kosaki (Motohiro KOSAKI)" <kosaki.motohiro@...>
Date: 2012-12-04T00:30:19+09:00
Subject: [ruby-dev:46697] [ruby-trunk - Feature #7505][Open] Mutex#owned? メソッドの新設


Issue #7505 has been reported by kosaki (Motohiro KOSAKI).

----------------------------------------
Feature #7505: Mutex#owned? メソッドの新設
https://bugs.ruby-lang.org/issues/7505

Author: kosaki (Motohiro KOSAKI)
Status: Open
Priority: Normal
Assignee: 
Category: core
Target version: next minor


以下のようなプログラムがあったとします。

Thread.async_interrupt_timing(Object => :on_blocking) {
  begin
  mutex = Mutex.new
    mutex.synchronize {
       sleep 1
       condvar.wait mutex
   }
  ensure
    リソース解放したい
  end
}

mutex.synchronizeの中でCtrl-cを押したとき、割り込まれる可能性のある箇所が三ヶ所あります

1) sleep
2) mutex.sleep の中のnative_sleep(condvar.signal 待ち)
3) mutex.sleep の中のrb_mutex_lock(condvar.signalで起床されたが、mutexを別スレッドが使用中だったためmutex待ち)

このとき、1と2はmutexを持ったままensureに入りますが、3はmutexを持たずにensureに入ってきます。さらに悪いことに2と3はRubyからは同じメソッド内にあるため、rubyレベルで workaroundをもうけることができません。

リソースを正しく解放する手段が「ない」というのは問題であるので、Mutex#owned? メソッドの新設を提案します。これはMutex#locked? とは異なり自分がロックを持っているときのみtrueを返します

パッチは以下

https://gist.github.com/4195632

以下余談、POSIXだと、pthread_cond_waitはキャンセレーションポイントではないし、なにがあろうともMutexをlockし終わってから関数を抜けてくるのでこういう問題はありません。これに揃えるという手もあるのですが、そうすると別スレッドがロックを持ったままでいるとCtrl-Cが効かなくなるのでakrさんの好みにはあわなさそう。




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