Index: build/android/pylib/chrome_test_server_spawner.py |
diff --git a/build/android/pylib/chrome_test_server_spawner.py b/build/android/pylib/chrome_test_server_spawner.py |
index 4fea07aef883ba58350e2bddf692492c066e5049..0ff79973593c4409dd55be4e3cdc8983c73b8b3f 100644 |
--- a/build/android/pylib/chrome_test_server_spawner.py |
+++ b/build/android/pylib/chrome_test_server_spawner.py |
@@ -23,6 +23,7 @@ import urlparse |
import constants |
import ports |
+from pylib.forwarder import Forwarder |
# Path that are needed to import necessary modules when launching a testserver. |
os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + (':%s:%s:%s:%s:%s' |
@@ -99,7 +100,7 @@ def _GetServerTypeCommandLine(server_type): |
class TestServerThread(threading.Thread): |
"""A thread to run the test server in a separate process.""" |
- def __init__(self, ready_event, arguments, adb, tool, forwarder, build_type): |
+ def __init__(self, ready_event, arguments, adb, tool, build_type): |
"""Initialize TestServerThread with the following argument. |
Args: |
@@ -107,7 +108,6 @@ class TestServerThread(threading.Thread): |
arguments: dictionary of arguments to run the test server. |
adb: instance of AndroidCommands. |
tool: instance of runtime error detection tool. |
- forwarder: instance of Forwarder. |
build_type: 'Release' or 'Debug'. |
""" |
threading.Thread.__init__(self) |
@@ -122,7 +122,6 @@ class TestServerThread(threading.Thread): |
self.is_ready = False |
self.host_port = self.arguments['port'] |
assert isinstance(self.host_port, int) |
- self._test_server_forwarder = forwarder |
# The forwarder device port now is dynamically allocated. |
self.forwarder_device_port = 0 |
# Anonymous pipe in order to get port info from test server. |
@@ -221,6 +220,17 @@ class TestServerThread(threading.Thread): |
for bulk_cipher in self.arguments['ssl-bulk-cipher']: |
self.command_line.append('--ssl-bulk-cipher=%s' % bulk_cipher) |
+ def _CloseUnnecessaryFDsForTestServerProcess(self): |
+ # This is required to avoid subtle deadlocks that could be caused by the |
+ # test server child process inheriting undesirable file descriptors such as |
+ # file lock file descriptors. |
+ for fd in xrange(0, 1024): |
+ if fd != self.pipe_out: |
+ try: |
+ os.close(fd) |
+ except: |
+ pass |
+ |
def run(self): |
logging.info('Start running the thread!') |
self.wait_event.clear() |
@@ -233,18 +243,18 @@ class TestServerThread(threading.Thread): |
command = [os.path.join(command, 'net', 'tools', 'testserver', |
'testserver.py')] + self.command_line |
logging.info('Running: %s', command) |
- self.process = subprocess.Popen(command) |
+ self.process = subprocess.Popen( |
+ command, preexec_fn=self._CloseUnnecessaryFDsForTestServerProcess) |
if self.process: |
if self.pipe_out: |
self.is_ready = self._WaitToStartAndGetPortFromTestServer() |
else: |
self.is_ready = _CheckPortStatus(self.host_port, True) |
if self.is_ready: |
- self._test_server_forwarder.Run([(0, self.host_port)], self.tool) |
+ Forwarder.Map([(0, self.host_port)], self.adb, self.build_type, self.tool) |
# Check whether the forwarder is ready on the device. |
self.is_ready = False |
- device_port = self._test_server_forwarder.DevicePortForHostPort( |
- self.host_port) |
+ device_port = Forwarder.DevicePortForHostPort(self.host_port) |
if device_port and _CheckDevicePortStatus(self.adb, device_port): |
self.is_ready = True |
self.forwarder_device_port = device_port |
@@ -254,7 +264,7 @@ class TestServerThread(threading.Thread): |
_WaitUntil(lambda: self.stop_flag, max_attempts=sys.maxint) |
if self.process.poll() is None: |
self.process.kill() |
- self._test_server_forwarder.UnmapDevicePort(self.forwarder_device_port) |
+ Forwarder.UnmapDevicePort(self.forwarder_device_port, self.adb) |
self.process = None |
self.is_ready = False |
if self.pipe_out: |
@@ -324,7 +334,6 @@ class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
json.loads(test_server_argument_json), |
self.server.adb, |
self.server.tool, |
- self.server.forwarder, |
self.server.build_type) |
self.server.test_server_instance.setDaemon(True) |
self.server.test_server_instance.start() |
@@ -392,14 +401,12 @@ class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
class SpawningServer(object): |
"""The class used to start/stop a http server.""" |
- def __init__(self, test_server_spawner_port, adb, tool, forwarder, |
- build_type): |
+ def __init__(self, test_server_spawner_port, adb, tool, build_type): |
logging.info('Creating new spawner on port: %d.', test_server_spawner_port) |
self.server = BaseHTTPServer.HTTPServer(('', test_server_spawner_port), |
SpawningServerRequestHandler) |
self.server.adb = adb |
self.server.tool = tool |
- self.server.forwarder = forwarder |
self.server.test_server_instance = None |
self.server.build_type = build_type |