From 1a3bcf103c582b20e9ea70dfed0ee68b24243f55 Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 26 Aug 2013 06:27:48 +0000 Subject: timeout.rb: skip rescue * lib/timeout.rb (Timeout#timeout): should not be caught by rescue clause. [Bug #8730] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42690 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/timeout.rb | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'lib/timeout.rb') diff --git a/lib/timeout.rb b/lib/timeout.rb index 284305bcca..97af8547f4 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -26,6 +26,18 @@ module Timeout class Error < RuntimeError end class ExitException < ::Exception # :nodoc: + attr_reader :klass, :thread + + def initialize(*) + super + @thread = Thread.current + freeze + end + + def exception(*) + throw(self, caller) if self.thread == Thread.current + self + end end # :stopdoc: @@ -50,8 +62,7 @@ module Timeout # a module method, so you can call it directly as Timeout.timeout(). def timeout(sec, klass = nil) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? - exception = klass || Class.new(ExitException) - begin + bt = catch(ExitException.new) do |exception| begin x = Thread.current y = Thread.start { @@ -60,7 +71,8 @@ module Timeout rescue => e x.raise e else - x.raise exception, "execution expired" + # no message, not to make new instance. + x.raise exception end } return yield(sec) @@ -70,18 +82,14 @@ module Timeout y.join # make sure y is dead. end end - rescue exception => e - rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o - (bt = e.backtrace).reject! {|m| rej =~ m} - level = -caller(CALLER_OFFSET).size - while THIS_FILE =~ bt[level] - bt.delete_at(level) - level += 1 - end - raise if klass # if exception class is specified, it - # would be expected outside. - raise Error, e.message, e.backtrace end + rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/o + bt.reject! {|m| rej =~ m} + level = -caller(CALLER_OFFSET).size + while THIS_FILE =~ bt[level] + bt.delete_at(level) + end + raise((klass||Error), "execution expired", bt) end module_function :timeout -- cgit v1.2.3