Index: build/android/devil/utils/reraiser_thread.py |
diff --git a/build/android/devil/utils/reraiser_thread.py b/build/android/devil/utils/reraiser_thread.py |
index e6a101b2dc66c2ab1ebfec9c2180dce9b09d4949..7607352b73a598f32fc4db87ff0c0f3d5d7e9460 100644 |
--- a/build/android/devil/utils/reraiser_thread.py |
+++ b/build/android/devil/utils/reraiser_thread.py |
@@ -8,6 +8,7 @@ |
import logging |
import sys |
import threading |
+import time |
import traceback |
from devil.utils import watchdog_timer |
@@ -104,19 +105,23 @@ class ReraiserThreadGroup(object): |
for thread in self._threads: |
thread.start() |
- def _JoinAll(self, watcher=None): |
+ def _JoinAll(self, watcher=None, timeout=None): |
"""Join all threads without stack dumps. |
Reraises exceptions raised by the child threads and supports breaking |
immediately on exceptions raised on the main thread. |
Args: |
- watcher: Watchdog object providing timeout, by default waits forever. |
+ watcher: Watchdog object providing the thread timeout. If none is |
+ provided, the thread will never be timed out. |
+ timeout: An optional number of seconds to wait before timing out the join |
+ operation. This will not time out the threads. |
""" |
if watcher is None: |
watcher = watchdog_timer.WatchdogTimer(None) |
alive_threads = self._threads[:] |
- while alive_threads: |
+ end_time = (time.time() + timeout) if timeout else None |
+ while alive_threads and (end_time is None or end_time > time.time()): |
for thread in alive_threads[:]: |
if watcher.IsTimedOut(): |
raise TimeoutError('Timed out waiting for %d of %d threads.' % |
@@ -129,7 +134,15 @@ class ReraiserThreadGroup(object): |
for thread in self._threads: |
thread.ReraiseIfException() |
- def JoinAll(self, watcher=None): |
+ def IsAlive(self): |
+ """Check whether any of the threads are still alive. |
+ |
+ Returns: |
+ Whether any of the threads are still alive. |
+ """ |
+ return any(t.isAlive() for t in self._threads) |
+ |
+ def JoinAll(self, watcher=None, timeout=None): |
"""Join all threads. |
Reraises exceptions raised by the child threads and supports breaking |
@@ -137,10 +150,13 @@ class ReraiserThreadGroup(object): |
stacks will be logged on watchdog timeout. |
Args: |
- watcher: Watchdog object providing timeout, by default waits forever. |
+ watcher: Watchdog object providing the thread timeout. If none is |
+ provided, the thread will never be timed out. |
+ timeout: An optional number of seconds to wait before timing out the join |
+ operation. This will not time out the threads. |
""" |
try: |
- self._JoinAll(watcher) |
+ self._JoinAll(watcher, timeout) |
except TimeoutError: |
logging.critical('Timed out. Dumping threads.') |
for thread in (t for t in self._threads if t.isAlive()): |