summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2019-09-04 08:15:30 +0200
committerJürg Billeter <j@bitron.ch>2019-09-04 10:50:25 +0200
commit1ec8fbf8dba33111b890fdec9c109b208e5da1ef (patch)
treed9866666d86958e1a82180ba1490d2f827a37349
parent1568268d749bc5ce14a418e5d2d45d621ec84e1d (diff)
downloadbuildstream-1ec8fbf8dba33111b890fdec9c109b208e5da1ef.tar.gz
utils.py: Wait for threads to exit in _is_single_threaded()
gRPC threads are not joined when shut down.
-rw-r--r--src/buildstream/utils.py18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/buildstream/utils.py b/src/buildstream/utils.py
index 872b5bd59..c9b64aa52 100644
--- a/src/buildstream/utils.py
+++ b/src/buildstream/utils.py
@@ -32,6 +32,7 @@ import stat
from stat import S_ISDIR
import subprocess
import tempfile
+import time
import itertools
from contextlib import contextmanager
from pathlib import Path
@@ -61,6 +62,9 @@ _MAIN_PID = os.getpid()
# This is 1 except for certain test environments (xdist/execnet).
_INITIAL_NUM_THREADS_IN_MAIN_PROCESS = 1
+# Number of seconds to wait for background threads to exit.
+_AWAIT_THREADS_TIMEOUT_SECONDS = 5
+
class UtilError(BstError):
"""Raised by utility functions when system calls fail.
@@ -1406,8 +1410,16 @@ def _get_compression(tar):
def _is_single_threaded():
# Use psutil as threading.active_count() doesn't include gRPC threads.
process = psutil.Process()
- num_threads = process.num_threads()
+
if process.pid == _MAIN_PID:
- return num_threads == _INITIAL_NUM_THREADS_IN_MAIN_PROCESS
+ expected_num_threads = _INITIAL_NUM_THREADS_IN_MAIN_PROCESS
else:
- return num_threads == 1
+ expected_num_threads = 1
+
+ # gRPC threads are not joined when shut down. Wait for them to exit.
+ wait = 0.1
+ for _ in range(0, int(_AWAIT_THREADS_TIMEOUT_SECONDS / wait)):
+ if process.num_threads() == expected_num_threads:
+ return True
+ time.sleep(wait)
+ return False