module Ethon::Multi::Operations

def check

Returns:
  • (void) -

Other tags:
    Example: Check. -
def check
  msgs_left = ::FFI::MemoryPointer.new(:int)
  while true
    msg = Curl.multi_info_read(handle, msgs_left)
    break if msg.null?
    next if msg[:code] != :done
    easy = easy_handles.find{ |e| e.handle == msg[:easy_handle] }
    easy.return_code = msg[:data][:code]
    Ethon.logger.debug { "ETHON:         performed #{easy.log_inspect}" }
    delete(easy)
    easy.complete
  end
end

def get_timeout

Raises:
  • (Ethon::Errors::MultiTimeout) - If getting the timeout fails.

Returns:
  • (Integer) - The timeout.

Other tags:
    Example: Get timeout. -
def get_timeout
  code = Curl.multi_timeout(handle, @timeout)
  raise Errors::MultiTimeout.new(code) unless code == :ok
  timeout = @timeout.read_long
  timeout = 1 if timeout < 0
  timeout
end

def handle

Returns:
  • (FFI::Pointer) - The multi handle.

Other tags:
    Example: Return multi handle. -
def handle
  @handle ||= FFI::AutoPointer.new(Curl.multi_init, Curl.method(:multi_cleanup))
end

def init_vars

Returns:
  • (void) -

Other tags:
    Example: Initialize variables. -
def init_vars
  if @execution_mode == :perform
    @timeout = ::FFI::MemoryPointer.new(:long)
    @timeval = Curl::Timeval.new
    @fd_read = Curl::FDSet.new
    @fd_write = Curl::FDSet.new
    @fd_excep = Curl::FDSet.new
    @max_fd = ::FFI::MemoryPointer.new(:int)
  elsif @execution_mode == :socket_action
    @running_count_pointer = FFI::MemoryPointer.new(:int)
  end
end

def ongoing?

Returns:
  • (Boolean) - True if ongoing, else false.

Other tags:
    Example: Return if ongoing. -
def ongoing?
  easy_handles.size > 0 || (!defined?(@running_count) || running_count > 0)
end

def perform

Other tags:
    Example: Perform multi. -

Returns:
  • (nil) -
def perform
  ensure_execution_mode(:perform)
  Ethon.logger.debug(STARTED_MULTI)
  while ongoing?
    run
    timeout = get_timeout
    next if timeout == 0
    reset_fds
    set_fds(timeout)
  end
  Ethon.logger.debug(PERFORMED_MULTI)
  nil
end

def prepare

Deprecated:
  • It is no longer necessary to call prepare.

Other tags:
    Example: Prepare multi. -

Returns:
  • (nil) -
def prepare
  Ethon.logger.warn(
    "ETHON: It is no longer necessay to call "+
    "Multi#prepare. Its going to be removed "+
    "in future versions."
  )
end

def reset_fds

Returns:
  • (void) -

Other tags:
    Example: Reset fds. -
def reset_fds
  @fd_read.clear
  @fd_write.clear
  @fd_excep.clear
end

def run

Returns:
  • (void) -

Other tags:
    Example: Run -
def run
  running_count_pointer = FFI::MemoryPointer.new(:int)
  begin code = trigger(running_count_pointer) end while code == :call_multi_perform
  check
end

def running_count

Returns:
  • (Integer) - Number running requests.

Other tags:
    Example: Return count. -
def running_count
  @running_count ||= nil
end

def set_fds(timeout)

Raises:
  • (Ethon::Errors::Select) - If select fails.
  • (Ethon::Errors::MultiFdset) - If setting the file descriptors fails.

Returns:
  • (void) -

Other tags:
    Example: Set fds. -
def set_fds(timeout)
  code = Curl.multi_fdset(handle, @fd_read, @fd_write, @fd_excep, @max_fd)
  raise Errors::MultiFdset.new(code) unless code == :ok
  max_fd = @max_fd.read_int
  if max_fd == -1
    sleep(0.001)
  else
    @timeval[:sec] = timeout / 1000
    @timeval[:usec] = (timeout * 1000) % 1000000
    loop do
      code = Curl.select(max_fd + 1, @fd_read, @fd_write, @fd_excep, @timeval)
      break unless code < 0 && ::FFI.errno == Errno::EINTR::Errno
    end
    raise Errors::Select.new(::FFI.errno) if code < 0
  end
end

def socket_action(io = nil, readiness = 0)

Returns:
  • (Symbol) - The Curl.multi_socket_action return code.

Other tags:
    Example: When a socket is readable and writable -
    Example: When a socket is readable -
    Example: When no sockets are ready yet, or to begin. -
def socket_action(io = nil, readiness = 0)
  ensure_execution_mode(:socket_action)
  fd = if io.nil?
    ::Ethon::Curl::SOCKET_TIMEOUT
  elsif io.is_a?(Integer)
    io
  else
    io.fileno
  end
  code = Curl.multi_socket_action(handle, fd, readiness, @running_count_pointer)
  @running_count = @running_count_pointer.read_int
  check
  code
end

def trigger(running_count_pointer)

Returns:
  • (Symbol) - The Curl.multi_perform return code.

Other tags:
    Example: Trigger. -
def trigger(running_count_pointer)
  code = Curl.multi_perform(handle, running_count_pointer)
  @running_count = running_count_pointer.read_int
  code
end