in tools/android/emulator/emulated_device.py [0:0]
def _WatchdogLoop(self, new_process_group, emu_args, emu_env, emu_wd,
services_dir):
"""The main loop of the watchdog process."""
if new_process_group:
os.setsid()
os.closerange(-1, subprocess.MAXFD)
watchdog_dir = None
if 'TEST_UNDECLARED_OUTPUTS_DIR' in os.environ:
watchdog_dir = tempfile.mkdtemp(
dir=os.environ['TEST_UNDECLARED_OUTPUTS_DIR'])
else:
watchdog_dir = self._TempDir('watchdog')
sys.stdin = open(os.devnull)
sys.stdout = open(os.path.join(watchdog_dir, 'watchdog.out'), 'w+b', 0)
sys.stderr = open(os.path.join(watchdog_dir, 'watchdog.err'), 'w+b', 0)
def WaterfallForwarder():
return self._Forward(
services_dir, 'unix:@h2o_localhost:%s' % self.emulator_adb_port,
'qemu:%s:sockets/h2o' % self._emulator_exec_dir)
def WaterfallTelnetForwarder():
return self._Forward(
services_dir, 'qemu:%s:sockets/qemu.mgmt' % self._emulator_exec_dir,
'tcp:localhost:%d' % self.emulator_telnet_port)
def WaterfallPortForwarder():
return self._StartPortForwarderServices(
services_dir,
'unix:@h2o_localhost:%s_xforward' % self.emulator_adb_port,
'unix:@h2o_localhost:%s' % self.emulator_adb_port)
waterfall_fns = [
WaterfallForwarder, WaterfallTelnetForwarder, WaterfallPortForwarder]
tn_pipe_services_fn = lambda: self._StartTelnetPipeServices(services_dir)
pids_to_fns = {}
killable = {}
pipe_service_processes = []
if self._use_waterfall:
logging.info('Starting waterfall processes.')
for fn in waterfall_fns:
p = fn()
pids_to_fns[p.pid] = fn
killable[p.pid] = p
logging.info('Started waterfall process %d', p.pid)
else:
logging.info('Starting pipe services.')
pipe_service_processes = self._StartPipeServices(services_dir)
for p in pipe_service_processes:
killable[p.pid] = p
tn_service_process = tn_pipe_services_fn()
killable[tn_service_process.pid] = tn_service_process
logging.info('Started pipe telnet forwarding service %d.',
tn_service_process.pid)
if self._display:
# Try starting the Xserver three times before giving up.
for _ in range(3):
try:
self._display.Start()
emu_env.update(self._display.environment)
break
except (xserver.ProcessCrashedError, xserver.TimeoutError) as e:
logging.error('Failed to start XServer..Retrying.. %s', e)
def WatchdogCleanup():
logging.info('Killing emu services')
for p in killable.values():
try:
p.terminate()
except OSError as e:
logging.info('Error killing services: %s - continue', e)
if self._display:
try:
logging.info('Killing display: Xvfb, x11vnc, if they were started.')
self._display.Kill()
logging.info('Display terminated')
except OSError as e:
logging.info('Error killing display: %s - continue', e)
if self.delete_temp_on_exit and self._emulator_tmp_dir:
logging.info('Cleaning up data dirs.')
print 'cleanup data dirs...'
self.CleanUp()
logging.info('Clean up done.')
try:
emu_process = common.Spawn(
emu_args,
exec_env=emu_env,
exec_dir=emu_wd,
proc_input=True,
proc_output=self._EmulatorLogFile('wb+'))
except (ValueError, OSError) as e:
logging.error('Failed to start process: %s', e)
WatchdogCleanup()
return -1
with open(os.path.join(self._images_dir, EMULATOR_PID), 'w') as f:
f.write('%s' % emu_process.pid)
while True:
logging.info('Processes launched - babysitting!')
dead_pid, status = os.wait()
logging.info('Dead pid: %s - exit status %d, signal %d', dead_pid,
status >> 8, status & 0xF)
if self._display.x11_pid == dead_pid:
logging.info('XServer has died')
WatchdogCleanup()
return status
elif emu_process.pid == dead_pid:
logging.info('Emulator has died')
WatchdogCleanup()
return status
elif dead_pid in [p.pid for p in pipe_service_processes]:
try:
logging.info('Pipe traversal daemon died - attempting to revive')
for p in pipe_service_processes:
try:
del killable[p.pid]
p.terminate()
except OSError as e:
# ignore.
pass
pipe_service_processes = self._StartPipeServices(services_dir)
for p in pipe_service_processes:
killable[p.pid] = p
logging.info('restarted Pipe traversal daemon')
except OSError as e:
logging.info('Failed to restart pipe traversal daemon. %s', e)
elif dead_pid in pids_to_fns:
fn = pids_to_fns[dead_pid]
del pids_to_fns[dead_pid]
del killable[dead_pid]
try:
p = fn()
pids_to_fns[p.pid] = fn
killable[p.pid] = p
except OSError as e:
logging.info('Failed to restart process %d. %s', p.pid, e)