PHP 8.2.31
Preview: timeout.rb Size: 5.72 KB
//proc/thread-self/root/opt/alt/ruby34/share/ruby/timeout.rb

# frozen_string_literal: true
# Timeout long-running blocks
#
# == Synopsis
#
#   require 'timeout'
#   status = Timeout.timeout(5) {
#     # Something that should be interrupted if it takes more than 5 seconds...
#   }
#
# == Description
#
# Timeout provides a way to auto-terminate a potentially long-running
# operation if it hasn't finished in a fixed amount of time.
#
# == Copyright
#
# Copyright:: (C) 2000  Network Applied Communication Laboratory, Inc.
# Copyright:: (C) 2000  Information-technology Promotion Agency, Japan

module Timeout
  # The version
  VERSION = "0.4.3"

  # Internal error raised to when a timeout is triggered.
  class ExitException < Exception
    def exception(*) # :nodoc:
      self
    end
  end

  # Raised by Timeout.timeout when the block times out.
  class Error < RuntimeError
    def self.handle_timeout(message) # :nodoc:
      exc = ExitException.new(message)

      begin
        yield exc
      rescue ExitException => e
        raise new(message) if exc.equal?(e)
        raise
      end
    end
  end

  # :stopdoc:
  CONDVAR = ConditionVariable.new
  QUEUE = Queue.new
  QUEUE_MUTEX = Mutex.new
  TIMEOUT_THREAD_MUTEX = Mutex.new
  @timeout_thread = nil
  private_constant :CONDVAR, :QUEUE, :QUEUE_MUTEX, :TIMEOUT_THREAD_MUTEX

  class Request
    attr_reader :deadline

    def initialize(thread, timeout, exception_class, message)
      @thread = thread
      @deadline = GET_TIME.call(Process::CLOCK_MONOTONIC) + timeout
      @exception_class = exception_class
      @message = message

      @mutex = Mutex.new
      @done = false # protected by @mutex
    end

    def done?
      @mutex.synchronize do
        @done
      end
    end

    def expired?(now)
      now >= @deadline
    end

    def interrupt
      @mutex.synchronize do
        unless @done
          @thread.raise @exception_class, @message
          @done = true
        end
      end
    end

    def finished
      @mutex.synchronize do
        @done = true
      end
    end
  end
  private_constant :Request

  def self.create_timeout_thread
    watcher = Thread.new do
      requests = []
      while true
        until QUEUE.empty? and !requests.empty? # wait to have at least one request
          req = QUEUE.pop
          requests << req unless req.done?
        end
        closest_deadline = requests.min_by(&:deadline).deadline

        now = 0.0
        QUEUE_MUTEX.synchronize do
          while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
            CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
          end
        end

        requests.each do |req|
          req.interrupt if req.expired?(now)
        end
        requests.reject!(&:done?)
      end
    end
    ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
    watcher.name = "Timeout stdlib thread"
    watcher.thread_variable_set(:"\0__detached_thread__", true)
    watcher
  end
  private_class_method :create_timeout_thread

  def self.ensure_timeout_thread_created
    unless @timeout_thread and @timeout_thread.alive?
      TIMEOUT_THREAD_MUTEX.synchronize do
        unless @timeout_thread and @timeout_thread.alive?
          @timeout_thread = create_timeout_thread
        end
      end
    end
  end

  # We keep a private reference so that time mocking libraries won't break
  # Timeout.
  GET_TIME = Process.method(:clock_gettime)
  private_constant :GET_TIME

  # :startdoc:

  # Perform an operation in a block, raising an error if it takes longer than
  # +sec+ seconds to complete.
  #
  # +sec+:: Number of seconds to wait for the block to terminate. Any non-negative number
  #         or nil may be used, including Floats to specify fractional seconds. A
  #         value of 0 or +nil+ will execute the block without any timeout.
  #         Any negative number will raise an ArgumentError.
  # +klass+:: Exception Class to raise if the block fails to terminate
  #           in +sec+ seconds.  Omitting will use the default, Timeout::Error
  # +message+:: Error message to raise with Exception Class.
  #             Omitting will use the default, "execution expired"
  #
  # Returns the result of the block *if* the block completed before
  # +sec+ seconds, otherwise throws an exception, based on the value of +klass+.
  #
  # The exception thrown to terminate the given block cannot be rescued inside
  # the block unless +klass+ is given explicitly. However, the block can use
  # ensure to prevent the handling of the exception.  For that reason, this
  # method cannot be relied on to enforce timeouts for untrusted blocks.
  #
  # If a scheduler is defined, it will be used to handle the timeout by invoking
  # Scheduler#timeout_after.
  #
  # 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, 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

    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
  module_function :timeout
end

Directory Contents

Dirs: 29 × Files: 53

Name Size Perms Modified Actions
- drwxr-xr-x 2026-05-14 20:42:20
Edit Download
cgi DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
digest DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
erb DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
fiddle DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
io DIR
- drwxr-xr-x 2026-04-20 12:15:54
Edit Download
json DIR
- drwxr-xr-x 2026-05-14 20:42:24
Edit Download
logger DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
net DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
objspace DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
open3 DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
openssl DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
optparse DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
prism DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
psych DIR
- drwxr-xr-x 2026-05-14 20:42:21
Edit Download
random DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
reline DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
ripper DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
ruby_vm DIR
- drwxr-xr-x 2025-03-29 07:09:38
Edit Download
set DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
strscan DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
uri DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
- drwxr-xr-x 2026-04-20 12:15:54
Edit Download
yaml DIR
- drwxr-xr-x 2026-05-14 20:42:17
Edit Download
18.66 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
7.28 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
9.83 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
368 B lrw-r--r-- 2026-04-20 12:16:12
Edit Download
1.17 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
11.68 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.51 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.30 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
5.54 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
14.53 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
84 B lrw-r--r-- 2026-04-20 12:16:12
Edit Download
2.19 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
3.67 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
78.80 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
2.52 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
9.03 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
22.40 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
19.58 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
22.49 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
92.63 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
6.97 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
4.14 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
28.38 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
47.51 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
1.06 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
59 B lrw-r--r-- 2026-04-20 12:16:13
Edit Download
64.17 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
14.22 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
17.20 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
18.36 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
15.93 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
3.03 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
20.36 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
25.10 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
215 B lrw-r--r-- 2026-04-20 12:16:13
Edit Download
14.93 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
87.96 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
2.44 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
2.28 KB lrw-r--r-- 2026-04-20 12:16:10
Edit Download
25.00 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
7.53 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
5.52 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
59.49 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
74 B lrw-r--r-- 2026-04-20 12:16:13
Edit Download
20.68 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
23.96 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
5.72 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
5.62 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
14.29 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
11.17 KB lrw-r--r-- 2026-04-20 12:16:13
Edit Download
3.09 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
1.36 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download
2.13 KB lrw-r--r-- 2026-04-20 12:16:12
Edit Download

If ZipArchive is unavailable, a .tar will be created (no compression).