diff options
Diffstat (limited to 'lib/timeout.rb')
-rw-r--r-- | lib/timeout.rb | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/lib/timeout.rb b/lib/timeout.rb index 7fd87ff40b..12c110647e 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -47,39 +47,41 @@ module Timeout # Note that this is both a method of module Timeout, so you can <tt>include # Timeout</tt> into your classes so they have a #timeout method, as well as # 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 + def timeout(sec, klass = nil, immediate: false) #:yield: +sec+ + return yield(sec) if sec == nil or sec.zero? + Thread.async_interrupt_timing(klass ? klass : ExitException => immediate ? :immediate : :on_blocking) do + exception = klass || Class.new(ExitException) begin - x = Thread.current - y = Thread.start { - begin - sleep sec - rescue => e - x.raise e - else - x.raise exception, "execution expired" + begin + x = Thread.current + y = Thread.start { + begin + sleep sec + rescue => e + x.raise e + else + x.raise exception, "execution expired" + end + } + return yield(sec) + ensure + if y + y.kill + y.join # make sure y is dead. end - } - return yield(sec) - ensure - if y - y.kill - y.join # make sure y is dead. 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 - 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 end |