Forum: Ruby-dev [ruby-trunk - Feature #7505][Open] Mutex#owned? メソッドの新設

Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2012-12-03 16:33
(Received via mailing list)
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さんの好みにはあわなさそう。
Posted by tarui (Masaya Tarui) (Guest)
on 2012-12-03 17:01
(Received via mailing list)
Issue #7505 has been updated by tarui (Masaya Tarui).


多分、こういう事だろうとおもうのですが、

mutex=Mutex.new
Thread.new{
  mutex.synchronize{
    begin
      sleep 1
      mutex.sleep
    ensure
      リソース解放
    end
  }
}
mutex.syncronize{
  sleep 10
}

mutex.sleepでmutexを手放している間にC-cがされてmutexを確保しようとするが確保できなかったとして、
そのmutexを確保しているThreadも死なないと行けないのでいずれmutexは解放されて、
mutex.sleepの方でmutexを取れるんじゃ無いでしょうか?

なので、mutexを取れるまで待つように修正する方針を押したいと思います。
つまり、1,2,3いずれの例でもmutexを保持してensureに入るようにしたい。

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

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さんの好みにはあわなさそう。
Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2012-12-03 17:13
(Received via mailing list)
Issue #7505 has been updated by kosaki (Motohiro KOSAKI).


樽井さんの例はもっと危険で mutexがunlockしたまま例外で抜けてきて synchronized抜けるときにもう一度 
unlockしちゃうので、二重unlockでThreadErrorになっちゃいますね


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

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さんの好みにはあわなさそう。
Posted by tarui (Masaya Tarui) (Guest)
on 2012-12-03 17:17
(Received via mailing list)
Issue #7505 has been updated by tarui (Masaya Tarui).


それは小崎さんの3の場合でも同じだと思うけど、
そう言う点からしても、例外で抜ける場合でmutexのlockとらないでunlockしたままとかおかしいですよね。
----------------------------------------
Feature #7505: Mutex#owned? メソッドの新設
https://bugs.ruby-lang.org/issues/7505#change-34369

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さんの好みにはあわなさそう。
Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2012-12-03 17:23
(Received via mailing list)
Issue #7505 has been updated by kosaki (Motohiro KOSAKI).


> なので、mutexを取れるまで待つように修正する方針を押したいと思います。

これは個人的には賛成しますが、別チケットにすることを提案します。
----------------------------------------
Feature #7505: Mutex#owned? メソッドの新設
https://bugs.ruby-lang.org/issues/7505#change-34370

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さんの好みにはあわなさそう。
Posted by tarui (Masaya Tarui) (Guest)
on 2012-12-03 17:26
(Received via mailing list)
Issue #7505 has been updated by tarui (Masaya Tarui).


>> なので、mutexを取れるまで待つように修正する方針を押したいと思います。
>これは個人的には賛成しますが、別チケットにすることを提案します。
Mutex#owned? の話でしたね。すいません。
これ自体には賛成です。
ただ、これでどうして元の課題が救えるのか分かりませんでした。

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

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さんの好みにはあわなさそう。
Posted by kosaki (Motohiro KOSAKI) (Guest)
on 2012-12-03 17:40
(Received via mailing list)
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さんの好みにはあわなさそう。
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.