Allow to setup timeout instead of waiting for OOM.

Bug: 111622837
Change-Id: I975f9f855ae06a0ace210862f74dcac6f97d2284
diff --git a/tools/toolhelper.py b/tools/toolhelper.py
index d7cf222..9371fb9 100644
--- a/tools/toolhelper.py
+++ b/tools/toolhelper.py
@@ -6,11 +6,12 @@
 import gradle
 import os
 import subprocess
+from threading import Timer
 import utils
 
 def run(tool, args, build=None, debug=True,
         profile=False, track_memory_file=None, extra_args=None,
-        stderr=None, stdout=None, return_stdout=False):
+        stderr=None, stdout=None, return_stdout=False, timeout=0):
   if build is None:
     build, args = extract_build_from_args(args)
   if build:
@@ -36,9 +37,20 @@
     cmd.extend(["--lib", lib])
   cmd.extend(args)
   utils.PrintCmd(cmd)
-  if return_stdout:
-    return subprocess.check_output(cmd)
-  return subprocess.call(cmd, stdout=stdout, stderr=stderr)
+  if timeout > 0:
+    kill = lambda process: process.kill()
+    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    timer = Timer(timeout, kill, [proc])
+    try:
+      timer.start()
+      stdout, stderr = proc.communicate()
+    finally:
+      timer.cancel()
+    return stdout if return_stdout else proc.returncode
+  else:
+    if return_stdout:
+      return subprocess.check_output(cmd)
+    return subprocess.call(cmd, stdout=stdout, stderr=stderr)
 
 def run_in_tests(tool, args, build=None, debug=True, extra_args=None):
   if build is None: