module WEBrick

module Utils
  #
  # Sets IO operations on +io+ to be non-blocking
  def self?.set_non_blocking: (IO io) -> void

  #
  # Sets the close on exec flag for +io+
  def self?.set_close_on_exec: (IO io) -> void

  #
  # Changes the process's uid and gid to the ones of +user+
  def self?.su: (String user) -> void

  #
  # The server hostname
  def self?.getservername: () -> String

  #
  # Creates TCP server sockets bound to +address+:+port+ and returns them.
  #
  # It will create IPV4 and IPV6 sockets on all interfaces.
  def self?.create_listeners: (String host, Integer port) -> Array[TCPServer]

  #
  # Characters used to generate random strings
  RAND_CHARS: String

  #
  # Generates a random string of length +len+
  def self?.random_string: (Integer len) -> String

  #
  # Class used to manage timeout handlers across multiple threads.
  #
  # Timeout handlers should be managed by using the class methods which are
  # synchronized.
  #
  #   id = TimeoutHandler.register(10, Timeout::Error)
  #   begin
  #     sleep 20
  #     puts 'foo'
  #   ensure
  #     TimeoutHandler.cancel(id)
  #   end
  #
  # will raise Timeout::Error
  #
  #   id = TimeoutHandler.register(10, Timeout::Error)
  #   begin
  #     sleep 5
  #     puts 'foo'
  #   ensure
  #     TimeoutHandler.cancel(id)
  #   end
  #
  # will print 'foo'
  #
  class TimeoutHandler
    @queue: Thread::Queue

    @watcher: Thread?

    include Singleton

    #
    # Mutex used to synchronize access across threads
    TimeoutMutex: Thread::Mutex

    #
    # Registers a new timeout handler
    #
    # +time+:: Timeout in seconds
    # +exception+:: Exception to raise when timeout elapsed
    def self.register: (Numeric seconds, singleton(Exception) exception) -> Integer

    #
    # Cancels the timeout handler +id+
    def self.cancel: (Integer id) -> bool

    def self.terminate: () -> Thread?

    #
    # Creates a new TimeoutHandler.  You should use ::register and ::cancel
    # instead of creating the timeout handler directly.
    def initialize: () -> void

    private

    def watch: () -> bot

    def watcher: () -> Thread

    public

    #
    # Interrupts the timeout handler +id+ and raises +exception+
    def interrupt: (Thread thread, Integer id, singleton(Exception) exception) -> nil

    #
    # Registers a new timeout handler
    #
    # +time+:: Timeout in seconds
    # +exception+:: Exception to raise when timeout elapsed
    def register: (Thread thread, Numeric time, singleton(Exception) exception) -> Integer

    #
    # Cancels the timeout handler +id+
    def cancel: (Thread thread, Integer id) -> bool

    #
    def terminate: () -> Thread?
  end

  #
  # Executes the passed block and raises +exception+ if execution takes more
  # than +seconds+.
  #
  # If +seconds+ is zero or nil, simply executes the block
  def self?.timeout: [T] (Numeric? seconds, ?singleton(Exception) exception) { (?Numeric) -> T } -> T
end

end