Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Unified Diff: third_party/gtest-parallel/gtest-parallel

Issue 1526383002: Roll gtest-parallel. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/gtest-parallel/README.webrtc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/gtest-parallel/gtest-parallel
diff --git a/third_party/gtest-parallel/gtest-parallel b/third_party/gtest-parallel/gtest-parallel
index b847180939ab72feceb9fe30211d86d2c68ea453..b609ab93dc537eba7c1a97c9022d0ca9446a858c 100755
--- a/third_party/gtest-parallel/gtest-parallel
+++ b/third_party/gtest-parallel/gtest-parallel
@@ -18,13 +18,62 @@ import gzip
import multiprocessing
import optparse
import os
+import signal
import subprocess
import sys
import tempfile
+import thread
import threading
import time
import zlib
+# An object that catches SIGINT sent to the Python process and notices
+# if processes passed to wait() die by SIGINT (we need to look for
+# both of those cases, because pressing Ctrl+C can result in either
+# the main process or one of the subprocesses getting the signal).
+#
+# Before a SIGINT is seen, wait(p) will simply call p.wait() and
+# return the result. Once a SIGINT has been seen (in the main process
+# or a subprocess, including the one the current call is waiting for),
+# wait(p) will call p.terminate() and raise ProcessWasInterrupted.
+class SigintHandler(object):
+ class ProcessWasInterrupted(Exception): pass
+ sigint_returncodes = {-signal.SIGINT, # Unix
+ -1073741510, # Windows
+ }
+ def __init__(self):
+ self.__lock = threading.Lock()
+ self.__processes = set()
+ self.__got_sigint = False
+ signal.signal(signal.SIGINT, self.__sigint_handler)
+ def __on_sigint(self):
+ self.__got_sigint = True
+ while self.__processes:
+ try:
+ self.__processes.pop().terminate()
+ except OSError:
+ pass
+ def __sigint_handler(self, signal_num, frame):
+ with self.__lock:
+ self.__on_sigint()
+ def got_sigint(self):
+ with self.__lock:
+ return self.__got_sigint
+ def wait(self, p):
+ with self.__lock:
+ if self.__got_sigint:
+ p.terminate()
+ self.__processes.add(p)
+ code = p.wait()
+ with self.__lock:
+ self.__processes.discard(p)
+ if code in self.sigint_returncodes:
+ self.__on_sigint()
+ if self.__got_sigint:
+ raise self.ProcessWasInterrupted
+ return code
+sigint_handler = SigintHandler()
+
# Return the width of the terminal, or None if it couldn't be
# determined (e.g. because we're not being run interactively).
def term_width(out):
@@ -301,7 +350,10 @@ def run_job((command, job_id, test)):
['--gtest_color=' + options.gtest_color],
stdout=log.file,
stderr=log.file)
- code = sub.wait()
+ try:
+ code = sigint_handler.wait(sub)
+ except sigint_handler.ProcessWasInterrupted:
+ thread.exit()
runtime_ms = int(1000 * (time.time() - begin))
logger.logfile(job_id, log.name)
@@ -344,4 +396,4 @@ if options.print_test_times:
if times.get_test_time(test_binary, test) is not None)
for (time_ms, test_binary, test) in ts:
print "%8s %s" % ("%dms" % time_ms, test)
-sys.exit(exit_code)
+sys.exit(-signal.SIGINT if sigint_handler.got_sigint() else exit_code)
« no previous file with comments | « third_party/gtest-parallel/README.webrtc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698