timeout(sec, klass = nil)
private
Executes the method’s block. If the block execution terminates before
sec seconds has passed, it returns the result value of the block.
If not, it terminates the execution and raises exception (which
defaults to Timeout::Error).
Note that this is both a method of module Timeout, so you can ‘include Timeout’ into your classes so they have a #timeout method, as well as a module
method, so you can call it directly as Timeout.timeout().
Show source
def timeout(sec, klass = nil)
return yield(sec) if sec == nil or sec.zero?
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" if x.alive?
end
}
return yield(sec)
rescue exception => e
rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/
(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
raise Error, e.message, e.backtrace
ensure
if y and y.alive?
y.kill
y.join
end
end
end