blob: e10e6b5336ff679076010e0116b31047b4f0bdad [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import signal
import subprocess
import time
class BrowserProcessBase(object):
def __init__(self, handle):
self.handle = handle
print 'PID', self.handle.pid
def GetReturnCode(self):
return self.handle.returncode
def IsRunning(self):
return self.handle.poll() is None
def Wait(self, wait_steps, sleep_time):
try:
self.term()
except Exception:
# Terminating the handle can raise an exception. There is likely no point
# in waiting if the termination didn't succeed.
return
i = 0
# subprocess.wait() doesn't have a timeout, unfortunately.
while self.IsRunning() and i < wait_steps:
time.sleep(sleep_time)
i += 1
def Kill(self):
if self.IsRunning():
print 'KILLING the browser'
try:
self.kill()
# If it doesn't die, we hang. Oh well.
self.handle.wait()
except Exception:
# If it is already dead, then it's ok.
# This may happen if the browser dies after the first poll, but
# before the kill.
if self.IsRunning():
raise
class BrowserProcess(BrowserProcessBase):
def term(self):
self.handle.terminate()
def kill(self):
self.handle.kill()
class BrowserProcessPosix(BrowserProcessBase):
""" This variant of BrowserProcess uses process groups to manage browser
life time. """
def term(self):
os.killpg(self.handle.pid, signal.SIGTERM)
def kill(self):
os.killpg(self.handle.pid, signal.SIGKILL)
def RunCommandWithSubprocess(cmd, env=None):
handle = subprocess.Popen(cmd, env=env)
return BrowserProcess(handle)
def RunCommandInProcessGroup(cmd, env=None):
def SetPGrp():
os.setpgrp()
print 'I\'M THE SESSION LEADER!'
handle = subprocess.Popen(cmd, env=env, preexec_fn=SetPGrp)
return BrowserProcessPosix(handle)