From: Tatsuki Sugiura Date: 2004-06-25T06:06:57+09:00 Subject: [ruby-dev:23781] Thread critical でも timeout を使いたい 杉浦と申します。こんにちは。 現在のバージョンだと Thread.critical = true の状態で timeout を呼ぶと、呼び出し元スレッドにに制御が戻ってこない ので、必ずタイムアウトしてしまいます。 $ ruby -rtimeout -e ' Thread.critical = true; timeout(5){ sleep(1) }; puts "end" ' /usr/lib/ruby/1.8/timeout.rb:50:in `timeout': execution expired (Timeout::Error) from /usr/lib/ruby/1.8/timeout.rb:65:in `timeout' from -e:3 critical == true でもスイッチできる特殊なスレッドがあれば良いの かも知れませんが、とりあえず他を全部止めて critical = false する パッチを書いてみました。 出来れば取り込んでいただけないでしょうか。 -- Tatsuki Sugiura mailto:sugi@nemui.org --- lib/timeout.rb.orig 2004-06-24 02:58:29.000000000 +0900 +++ lib/timeout.rb 2004-06-25 05:50:30.000000000 +0900 @@ -36,7 +36,15 @@ def timeout(sec, exception=Error) return yield if sec == nil or sec.zero? begin + stats = Hash.new x = Thread.current + c = Thread.critical + c and Thread.list.each {|t| + t == x and next + stats[t] = !t.stop? + t.stop + } + Thread.critical = false y = Thread.start { sleep sec x.raise exception, "execution expired" if x.alive? @@ -45,6 +53,8 @@ # return true ensure y.kill if y and y.alive? + Thread.critical = c + stats.each { |t, run_p| run_p and t.wakeup } end end module_function :timeout