summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Schubert <contact@benschubert.me>2020-08-29 09:36:16 +0000
committerBenjamin Schubert <contact@benschubert.me>2020-10-06 19:06:03 +0000
commitdd596f416e180659ab23b21cb4810cdfc5027166 (patch)
tree3f5273377dbaa6a5cd69d989acf790ee01c09aee
parent779ff74c42f68895390081fad38ce56c7db3acb3 (diff)
downloadbuildstream-dd596f416e180659ab23b21cb4810cdfc5027166.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.py16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/buildstream/utils.py b/src/buildstream/utils.py
index 94ff931ad..1d1336cb4 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
@@ -1397,7 +1398,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)