2010-04-28 Eric Seidel <eric@webkit.org>
[WebKit-https.git] / WebKitTools / Scripts / webkitpy / layout_tests / port / server_process.py
index d072587..62ca693 100644 (file)
@@ -38,6 +38,8 @@ import subprocess
 import sys
 import time
 
+from webkitpy.common.system.executive import Executive
+
 _log = logging.getLogger("webkitpy.layout_tests.port.server_process")
 
 
@@ -48,12 +50,13 @@ class ServerProcess:
     indefinitely. The class also handles transparently restarting processes
     as necessary to keep issuing commands."""
 
-    def __init__(self, port_obj, name, cmd, env=None):
+    def __init__(self, port_obj, name, cmd, env=None, executive=Executive()):
         self._port = port_obj
         self._name = name
         self._cmd = cmd
         self._env = env
         self._reset()
+        self._executive = executive
 
     def _reset(self):
         self._proc = None
@@ -66,6 +69,7 @@ class ServerProcess:
         if self._proc:
             raise ValueError("%s already running" % self._name)
         self._reset()
+        # close_fds is a workaround for http://bugs.python.org/issue2320
         close_fds = sys.platform not in ('win32', 'cygwin')
         self._proc = subprocess.Popen(self._cmd, stdin=subprocess.PIPE,
                                       stdout=subprocess.PIPE,
@@ -86,7 +90,7 @@ class ServerProcess:
         if self.crashed:
             # This is hex code 0xc000001d, which is used for abrupt
             # termination. This happens if we hit ctrl+c from the prompt
-            # and we happen to be waiting on the test_shell.
+            # and we happen to be waiting on the DumpRenderTree.
             # sdoyon: Not sure for which OS and in what circumstances the
             # above code is valid. What works for me under Linux to detect
             # ctrl+c is for the subprocess returncode to be negative
@@ -100,6 +104,8 @@ class ServerProcess:
         """Check to see if the underlying process is running; returns None
         if it still is (wrapper around subprocess.poll)."""
         if self._proc:
+            # poll() is not threadsafe and can throw OSError due to:
+            # http://bugs.python.org/issue1731717
             return self._proc.poll()
         return None
 
@@ -164,6 +170,8 @@ class ServerProcess:
         select_fds = (out_fd, err_fd)
         deadline = time.time() + timeout
         while not self.timed_out and not self.crashed:
+            # poll() is not threadsafe and can throw OSError due to:
+            # http://bugs.python.org/issue1731717
             if self._proc.poll() != None:
                 self.crashed = True
                 self.handle_interrupt()
@@ -205,19 +213,20 @@ class ServerProcess:
         if sys.platform not in ('win32', 'cygwin'):
             # Closing stdin/stdout/stderr hangs sometimes on OS X,
             # (see restart(), above), and anyway we don't want to hang
-            # the harness if test_shell is buggy, so we wait a couple
-            # seconds to give test_shell a chance to clean up, but then
+            # the harness if DumpRenderTree is buggy, so we wait a couple
+            # seconds to give DumpRenderTree a chance to clean up, but then
             # force-kill the process if necessary.
             KILL_TIMEOUT = 3.0
             timeout = time.time() + KILL_TIMEOUT
+            # poll() is not threadsafe and can throw OSError due to:
+            # http://bugs.python.org/issue1731717
             while self._proc.poll() is None and time.time() < timeout:
                 time.sleep(0.1)
+            # poll() is not threadsafe and can throw OSError due to:
+            # http://bugs.python.org/issue1731717
             if self._proc.poll() is None:
                 _log.warning('stopping %s timed out, killing it' %
                              self._name)
-                null = open(os.devnull, "w")
-                subprocess.Popen(["kill", "-9",
-                                  str(self._proc.pid)], stderr=null)
-                null.close()
+                self._executive.kill_process(self._proc.pid)
                 _log.warning('killed')
         self._reset()