| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 # pylint: disable=W0212 |
| 6 |
| 5 import fcntl | 7 import fcntl |
| 6 import logging | 8 import logging |
| 7 import os | 9 import os |
| 8 import psutil | 10 import psutil |
| 9 import re | |
| 10 import sys | |
| 11 import time | |
| 12 | 11 |
| 13 import android_commands | 12 from pylib import cmd_helper |
| 14 import cmd_helper | 13 from pylib import constants |
| 15 import constants | |
| 16 | |
| 17 from pylib import valgrind_tools | 14 from pylib import valgrind_tools |
| 18 | 15 |
| 19 | 16 |
| 20 def _GetProcessStartTime(pid): | 17 def _GetProcessStartTime(pid): |
| 21 return psutil.Process(pid).create_time | 18 return psutil.Process(pid).create_time |
| 22 | 19 |
| 23 | 20 |
| 24 class _FileLock(object): | 21 class _FileLock(object): |
| 25 """With statement-aware implementation of a file lock. | 22 """With statement-aware implementation of a file lock. |
| 26 | 23 |
| 27 File locks are needed for cross-process synchronization when the | 24 File locks are needed for cross-process synchronization when the |
| 28 multiprocessing Python module is used. | 25 multiprocessing Python module is used. |
| 29 """ | 26 """ |
| 30 def __init__(self, path): | 27 def __init__(self, path): |
| 28 self._fd = -1 |
| 31 self._path = path | 29 self._path = path |
| 32 | 30 |
| 33 def __enter__(self): | 31 def __enter__(self): |
| 34 self._fd = os.open(self._path, os.O_RDONLY | os.O_CREAT) | 32 self._fd = os.open(self._path, os.O_RDONLY | os.O_CREAT) |
| 35 if self._fd < 0: | 33 if self._fd < 0: |
| 36 raise Exception('Could not open file %s for reading' % self._path) | 34 raise Exception('Could not open file %s for reading' % self._path) |
| 37 fcntl.flock(self._fd, fcntl.LOCK_EX) | 35 fcntl.flock(self._fd, fcntl.LOCK_EX) |
| 38 | 36 |
| 39 def __exit__(self, type, value, traceback): | 37 def __exit__(self, _exception_type, _exception_value, traceback): |
| 40 fcntl.flock(self._fd, fcntl.LOCK_UN) | 38 fcntl.flock(self._fd, fcntl.LOCK_UN) |
| 41 os.close(self._fd) | 39 os.close(self._fd) |
| 42 | 40 |
| 43 | 41 |
| 44 class Forwarder(object): | 42 class Forwarder(object): |
| 45 """Thread-safe class to manage port forwards from the device to the host.""" | 43 """Thread-safe class to manage port forwards from the device to the host.""" |
| 46 | 44 |
| 47 _DEVICE_FORWARDER_FOLDER = (constants.TEST_EXECUTABLE_DIR + | 45 _DEVICE_FORWARDER_FOLDER = (constants.TEST_EXECUTABLE_DIR + |
| 48 '/forwarder/') | 46 '/forwarder/') |
| 49 _DEVICE_FORWARDER_PATH = (constants.TEST_EXECUTABLE_DIR + | 47 _DEVICE_FORWARDER_PATH = (constants.TEST_EXECUTABLE_DIR + |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 # There are no more ports mapped, kill the device_forwarder. | 145 # There are no more ports mapped, kill the device_forwarder. |
| 148 tool = valgrind_tools.CreateTool(None, adb) | 146 tool = valgrind_tools.CreateTool(None, adb) |
| 149 Forwarder._KillDeviceLocked(adb, tool) | 147 Forwarder._KillDeviceLocked(adb, tool) |
| 150 Forwarder._instance._initialized_devices.remove(adb_serial) | 148 Forwarder._instance._initialized_devices.remove(adb_serial) |
| 151 | 149 |
| 152 | 150 |
| 153 @staticmethod | 151 @staticmethod |
| 154 def DevicePortForHostPort(host_port): | 152 def DevicePortForHostPort(host_port): |
| 155 """Returns the device port that corresponds to a given host port.""" | 153 """Returns the device port that corresponds to a given host port.""" |
| 156 with _FileLock(Forwarder._LOCK_PATH): | 154 with _FileLock(Forwarder._LOCK_PATH): |
| 157 (device_serial, device_port) = Forwarder._GetInstanceLocked( | 155 (_device_serial, device_port) = Forwarder._GetInstanceLocked( |
| 158 None)._host_to_device_port_map.get(host_port) | 156 None)._host_to_device_port_map.get(host_port) |
| 159 return device_port | 157 return device_port |
| 160 | 158 |
| 161 @staticmethod | 159 @staticmethod |
| 162 def RemoveHostLog(): | 160 def RemoveHostLog(): |
| 163 if os.path.exists(Forwarder._HOST_FORWARDER_LOG): | 161 if os.path.exists(Forwarder._HOST_FORWARDER_LOG): |
| 164 os.unlink(Forwarder._HOST_FORWARDER_LOG) | 162 os.unlink(Forwarder._HOST_FORWARDER_LOG) |
| 165 | 163 |
| 166 @staticmethod | 164 @staticmethod |
| 167 def GetHostLog(): | 165 def GetHostLog(): |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 Note that the global lock must be acquired before calling this method. | 310 Note that the global lock must be acquired before calling this method. |
| 313 | 311 |
| 314 Args: | 312 Args: |
| 315 adb: Instance of AndroidCommands for talking to the device. | 313 adb: Instance of AndroidCommands for talking to the device. |
| 316 tool: Wrapper tool (e.g. valgrind) that can be used to execute the device | 314 tool: Wrapper tool (e.g. valgrind) that can be used to execute the device |
| 317 forwarder (see valgrind_tools.py). | 315 forwarder (see valgrind_tools.py). |
| 318 """ | 316 """ |
| 319 logging.info('Killing device_forwarder.') | 317 logging.info('Killing device_forwarder.') |
| 320 if not adb.FileExistsOnDevice(Forwarder._DEVICE_FORWARDER_PATH): | 318 if not adb.FileExistsOnDevice(Forwarder._DEVICE_FORWARDER_PATH): |
| 321 return | 319 return |
| 322 (exit_code, output) = adb.GetShellCommandStatusAndOutput( | 320 adb.GetShellCommandStatusAndOutput( |
| 323 '%s %s --kill-server' % (tool.GetUtilWrapper(), | 321 '%s %s --kill-server' % (tool.GetUtilWrapper(), |
| 324 Forwarder._DEVICE_FORWARDER_PATH)) | 322 Forwarder._DEVICE_FORWARDER_PATH)) |
| 325 # TODO(pliard): Remove the following call to KillAllBlocking() when we are | 323 # TODO(pliard): Remove the following call to KillAllBlocking() when we are |
| 326 # sure that the old version of device_forwarder (not supporting | 324 # sure that the old version of device_forwarder (not supporting |
| 327 # 'kill-server') is not running on the bots anymore. | 325 # 'kill-server') is not running on the bots anymore. |
| 328 timeout_sec = 5 | 326 timeout_sec = 5 |
| 329 processes_killed = adb.KillAllBlocking('device_forwarder', timeout_sec) | 327 processes_killed = adb.KillAllBlocking('device_forwarder', timeout_sec) |
| 330 if not processes_killed: | 328 if not processes_killed: |
| 331 pids = adb.ExtractPid('device_forwarder') | 329 pids = adb.ExtractPid('device_forwarder') |
| 332 if pids: | 330 if pids: |
| 333 raise Exception('Timed out while killing device_forwarder') | 331 raise Exception('Timed out while killing device_forwarder') |
| OLD | NEW |