From: Motohiro KOSAKI Date: 2011-01-17T14:46:06+09:00 Subject: [ruby-dev:43050] [Ruby 1.9-Bug#4284][Open] Timeout.timeout may cause application exit unintetionally, again Bug #4284: Timeout.timeout may cause application exit unintetionally, again http://redmine.ruby-lang.org/issues/show/4284 起票者: Motohiro KOSAKI ステータス: Open, 優先度: Normal 担当者: Yukihiro Matsumoto, カテゴリ: lib, Target version: 1.9.3 ruby -v: ruby 1.9.3dev (2010-12-22 trunk 30291) [x86_64-linux] This issue was discovered during [Bug#4266] discussion. Current timeout is racy. Now, timeout module has following code. ------------------------------------------------------------------------------- def timeout() begin x = Thread.current y = Thread.start { begin sleep sec rescue => e x.raise e else x.raise exception, "execution expired" if x.alive? end } return yield(sec) rescue exception => e raise Error, e.message, e.backtrace ensure if y and y.alive? y.kill y.join # make sure y is dead. end end end --------------------------------------------------------------- Unfortunatelly, y = Thread.start {} is not an atomic operation. Then, A following race can occur. CPU0(thread x) CPU1(thread y) remark --------------------------------------------------------------------------- enter begin block [thread construct] but no assign y yet sleep sec wakeup from sleep x.raise if y return false. (see above) Therefore, CPU0 don't call y.join and leak y's thread resource. C# have solved this two-step-construction vs asynchrounous exception race by RAII. But unfortunately, Ruby don't have such language feature. So, We can't write async-exception-safe code. One of solution is to move timeout module from ruby code into c code as JRuby does. But I don't think timeout is only asynchrounos exception user. we also have Interrupt class (for Ctrl-C) and I think we need to allow to write async exception safe code by ruby. Or, Am I missing something? ---------------------------------------- http://redmine.ruby-lang.org