timeout(sec, klass = nil)
public
Executes the method’s block. If the block execution terminates before
sec seconds has passed, it returns true. 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 if sec == nil or sec.zero?
raise ThreadError, "timeout within critical session" if Thread.critical
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
}
yield sec
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
raise Error, e.message, e.backtrace
ensure
if y and y.alive?
y.kill
y.join
end
end
end