module Gem::Timeout

def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+

: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