module Gem::Timeout
def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+
a module method, so you can call it directly as Gem::Timeout.timeout().
Gem::Timeout into your classes so they have a #timeout method, as well as
Note that this is both a method of module Gem::Timeout, so you can include
Scheduler#timeout_after.
If a scheduler is defined, it will be used to handle the timeout by invoking
method cannot be relied on to enforce timeouts for untrusted blocks.
ensure to prevent the handling of the exception. For that reason, this
the block unless +klass+ is given explicitly. However, the block can use
The exception thrown to terminate the given block cannot be rescued inside
+sec+ seconds, otherwise throws an exception, based on the value of +klass+.
Returns the result of the block *if* the block completed before
Omitting will use the default, "execution expired"
+message+:: Error message to raise with Exception Class.
in +sec+ seconds. Omitting will use the default, Gem::Timeout::Error
+klass+:: Exception Class to raise if the block fails to terminate
Any negative number will raise an ArgumentError.
value of 0 or +nil+ will execute the block without any timeout.
or nil may be used, including Floats to specify fractional seconds. A
+sec+:: Number of seconds to wait for the block to terminate. Any non-negative number
+sec+ seconds to complete.
Perform an operation in a block, raising an error if it takes longer than
def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ return yield(sec) if sec == nil or sec.zero? raise ArgumentError, "Timeout sec must be a non-negative number" if 0 > sec message ||= "execution expired" if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after) return scheduler.timeout_after(sec, klass || Error, message, &block) end Gem::Timeout.ensure_timeout_thread_created perform = Proc.new do |exc| request = Request.new(Thread.current, sec, exc, message) QUEUE_MUTEX.synchronize do QUEUE << request CONDVAR.signal end begin return yield(sec) ensure request.finished end end if klass perform.call(klass) else Error.handle_timeout(message, &perform) end end