class Typhoeus::Multi

def perform

def perform
  while @active > 0
    run
    while @running > 0
      # get the curl-suggested timeout
      code = Curl.multi_timeout(@handle, @timeout)
      raise RuntimeError.new("an error occured getting the timeout: #{code}: #{Curl.multi_strerror(code)}") if code != :ok
      timeout = @timeout.read_long
      if timeout == 0 # no delay
        run
        next
      elsif timeout < 0
        timeout = 1
      end
      # load the fd sets from the multi handle
      @fd_read.clear
      @fd_write.clear
      @fd_excep.clear
      code = Curl.multi_fdset(@handle, @fd_read, @fd_write, @fd_excep, @max_fd)
      raise RuntimeError.new("an error occured getting the fdset: #{code}: #{Curl.multi_strerror(code)}") if code != :ok
      max_fd = @max_fd.read_int
      if max_fd == -1
        # curl is doing something special so let it run for a moment
        sleep(0.001)
      else
        @timeval[:sec] = timeout / 1000
        @timeval[:usec] = (timeout * 1000) % 1000000
        code = Curl.select(max_fd + 1, @fd_read, @fd_write, @fd_excep, @timeval)
        raise RuntimeError.new("error on thread select: #{::FFI.errno}") if code < 0
      end
      run
    end
  end
  reset_easy_handles
end