diff options
author | Benjamin Schubert <bschubert15@bloomberg.net> | 2020-08-29 09:36:16 +0000 |
---|---|---|
committer | Benjamin Schubert <bschubert15@bloomberg.net> | 2020-12-01 10:57:30 +0000 |
commit | 7a9735ddb73c2d1b94eaf1a73b277259fdc37628 (patch) | |
tree | 301d4a90e93dcf70c96d91b13e1ab61b68423ecd | |
parent | 6b961f20a8b2174a342e9b92e68752b2ff19da29 (diff) | |
download | buildstream-7a9735ddb73c2d1b94eaf1a73b277259fdc37628.tar.gz |
utils.py: Don't block on the call's `communicate` call
This ensures that, if we were to receive signals or other things while
we are on this blocking call, we would be able to process them instead
of waiting for the end of the process
-rw-r--r-- | src/buildstream/utils.py | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/buildstream/utils.py b/src/buildstream/utils.py index 9c6761ccc..4eb62d988 100644 --- a/src/buildstream/utils.py +++ b/src/buildstream/utils.py @@ -32,6 +32,7 @@ import signal import stat from stat import S_ISDIR import subprocess +from subprocess import TimeoutExpired import tempfile import time import datetime @@ -1392,7 +1393,20 @@ def _call(*popenargs, terminate=False, **kwargs): process = subprocess.Popen( # pylint: disable=subprocess-popen-preexec-fn *popenargs, preexec_fn=preexec_fn, universal_newlines=True, **kwargs ) - output, _ = process.communicate() + # Here, we don't use `process.communicate()` directly without a timeout + # This is because, if we were to do that, and the process would never + # output anything, the control would never be given back to the python + # process, which might thus not be able to check for request to + # shutdown, or kill the process. + # We therefore loop with a timeout, to ensure the python process + # can act if it needs. + while True: + try: + output, _ = process.communicate(timeout=1) + break + except TimeoutExpired: + continue + exit_code = process.poll() return (exit_code, output) |