From: "kosaki (Motohiro KOSAKI)" <kosaki.motohiro@...> Date: 2012-12-04T01:39:18+09:00 Subject: [ruby-dev:46704] [ruby-trunk - Feature #7505][Assigned] Mutex#owned? メソッドの新設 Issue #7505 has been updated by kosaki (Motohiro KOSAKI). Status changed from Open to Assigned Assignee set to kosaki (Motohiro KOSAKI) ---------------------------------------- Feature #7505: Mutex#owned? メソッドの新設 https://bugs.ruby-lang.org/issues/7505#change-34374 Author: kosaki (Motohiro KOSAKI) Status: Assigned Priority: Normal Assignee: kosaki (Motohiro KOSAKI) 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/