さかいといいます
Timeout#timeout内でConditionVariable#waitを実行しタイムアウトになると、
Mutexがunlockされたままになってしまいます。
require 'timeout'
require 'thread'
mutex = Mutex.new
resource = ConditionVariable.new
mutex.synchronize{
begin
timeout(0.01){
resource.wait(mutex)
}
rescue Timeout::Error
p mutex.locked? #=> false
end
}
# そもそも、この2つを組み合わせるのが想定外なのかもしれませんが、
# 幾つかのスレッドライブラリ (e.g. pthread, gthread, SRFI-18, Win32, etc) では
# timeoutを指定してwaitすることが出来るので、
# Rubyのスレッドでも同じことをしたかったのです。
最初は以下のように単にbegin/ensureを使うよう変更すればよいのかと思ったのですが、
ensure節まで到達した後 mutex.lock を実行する直前のタイミングで
Timeoutによって割り込まれる可能性も考慮する必要があるのでしょうか……
Index: lib/thread.rb
===================================================================
RCS file: /src/ruby/lib/thread.rb,v
retrieving revision 1.16
diff -u -p -r1.16 thread.rb
--- lib/thread.rb 16 Nov 2003 01:53:12 -0000 1.16
+++ lib/thread.rb 25 May 2004 14:16:00 -0000
@@ -189,11 +189,14 @@ class ConditionVariable
# Releases the lock held in +mutex+ and waits; reacquires the lock on wakeup.
#
def wait(mutex)
- mutex.exclusive_unlock do
- @waiters.push(Thread.current)
- Thread.stop
+ begin
+ mutex.exclusive_unlock do
+ @waiters.push(Thread.current)
+ Thread.stop
+ end
+ ensure
+ mutex.lock
end
- mutex.lock
end
#
--
酒井 政裕 / Masahiro Sakai