Index: gclient_utils.py |
diff --git a/gclient_utils.py b/gclient_utils.py |
index ddcce9b17746568b242c6fead28287c1ea834c5f..76edafff40f6554bf151ec0ca26b1347cb64abe2 100644 |
--- a/gclient_utils.py |
+++ b/gclient_utils.py |
@@ -325,7 +325,7 @@ def MakeFileAnnotated(fileobj, include_zero=False): |
def CheckCallAndFilter(args, stdout=None, filter_fn=None, |
print_stdout=None, call_filter_on_first_line=False, |
- **kwargs): |
+ nag_timer=None, nag_max=None, **kwargs): |
"""Runs a command and calls back a filter function if needed. |
Accepts all subprocess2.Popen() parameters plus: |
@@ -347,6 +347,21 @@ def CheckCallAndFilter(args, stdout=None, filter_fn=None, |
# Do a flush of stdout before we begin reading from the subprocess2's stdout |
stdout.flush() |
+ nag = None |
+ if nag_timer: |
+ # Hack thread.index to force correct annotation. |
+ index = getattr(threading.currentThread(), 'index', 0) |
+ def _nag_cb(elapsed): |
+ setattr(threading.currentThread(), 'index', index) |
+ stdout.write(' No output for %.0f seconds from command:\n' % elapsed) |
+ stdout.write(' %s\n' % kid.cmd_str) |
+ if (nag_max and |
+ int('%.0f' % (elapsed / nag_timer)) >= nag_max): |
+ stdout.write(' ... killing it!\n') |
+ kid.kill() |
+ nag = subprocess2.NagTimer(nag_timer, _nag_cb) |
+ nag.start() |
+ |
# Also, we need to forward stdout to prevent weird re-ordering of output. |
# This has to be done on a per byte basis to make sure it is not buffered: |
# normally buffering is done for each line, but if svn requests input, no |
@@ -354,6 +369,8 @@ def CheckCallAndFilter(args, stdout=None, filter_fn=None, |
try: |
in_byte = kid.stdout.read(1) |
if in_byte: |
+ if nag: |
+ nag.event() |
if call_filter_on_first_line: |
filter_fn(None) |
in_line = '' |
@@ -370,6 +387,8 @@ def CheckCallAndFilter(args, stdout=None, filter_fn=None, |
filter_fn(in_line) |
in_line = '' |
in_byte = kid.stdout.read(1) |
+ if in_byte and nag: |
+ nag.event() |
# Flush the rest of buffered output. This is only an issue with |
# stdout/stderr not ending with a \n. |
if len(in_line): |
@@ -378,6 +397,9 @@ def CheckCallAndFilter(args, stdout=None, filter_fn=None, |
except KeyboardInterrupt: |
print >> sys.stderr, 'Failed while running "%s"' % ' '.join(args) |
raise |
+ finally: |
+ if nag: |
+ nag.cancel() |
if rv: |
raise subprocess2.CalledProcessError( |