class Selenium::WebDriver::ChildProcess

@api private

Constants

POLL_INTERVAL
SIGKILL
SIGTERM
TimeoutError

Attributes

detach[RW]
io[W]

Public Class Methods

build(*command) click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 37
def self.build(*command)
  new(*command)
end
new(*command) click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 41
def initialize(*command)
  @command = command
  @detach = false
  @pid = nil
  @status = nil
end

Public Instance Methods

alive?() click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 79
def alive?
  @pid && !exited?
end
exited?() click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 83
def exited?
  return unless @pid

  WebDriver.logger.debug("Checking if #{@pid} is exited:")
  _, @status = Process.waitpid2(@pid, Process::WNOHANG | Process::WUNTRACED) if @status.nil?
  return if @status.nil?

  exit_code = @status.exitstatus || @status.termsig
  WebDriver.logger.debug("  -> exit code is #{exit_code.inspect}")

  !!exit_code
end
io() click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 48
def io
  @io ||= Platform.null_device
end
poll_for_exit(timeout) click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 96
def poll_for_exit(timeout)
  WebDriver.logger.debug("Polling #{timeout} seconds for exit of #{@pid}")

  end_time = Time.now + timeout
  sleep POLL_INTERVAL until exited? || Time.now > end_time

  raise TimeoutError, "  ->  #{@pid} still alive after #{timeout} seconds" unless exited?
end
start() click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 52
def start
  options = {%i[out err] => io}
  options[:pgroup] = true unless Platform.windows? # NOTE: this is a bug only in Windows 7

  WebDriver.logger.debug("Starting process: #{@command} with #{options}")
  @pid = Process.spawn(*@command, options)
  WebDriver.logger.debug("  -> pid: #{@pid}")

  Process.detach(@pid) if detach
end
stop(timeout = 3) click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 63
def stop(timeout = 3)
  return unless @pid
  return if exited?

  WebDriver.logger.debug("Sending TERM to process: #{@pid}")
  terminate(@pid)
  poll_for_exit(timeout)

  WebDriver.logger.debug("  -> stopped #{@pid}")
rescue TimeoutError, Errno::EINVAL
  WebDriver.logger.debug("    -> sending KILL to process: #{@pid}")
  kill(@pid)
  wait
  WebDriver.logger.debug("      -> killed #{@pid}")
end
wait() click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 105
def wait
  return if exited?

  _, @status = Process.waitpid2(@pid)
end

Private Instance Methods

kill(pid) click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 117
def kill(pid)
  Process.kill(SIGKILL, pid)
rescue Errno::ECHILD, Errno::ESRCH
  # already dead
end
terminate(pid) click to toggle source
# File lib/selenium/webdriver/common/child_process.rb, line 113
def terminate(pid)
  Process.kill(SIGTERM, pid)
end