diff options
author | orlnub123 <orlnub123@gmail.com> | 2018-09-27 11:16:26 (GMT) |
---|---|---|
committer | Antoine Pitrou <pitrou@free.fr> | 2018-09-27 11:16:26 (GMT) |
commit | a94ee12c26aa8dd7dce01373779df8055aff765b (patch) | |
tree | 1b627f9fac54e8b0d6a88c8f62ecd785b40a5b8b /Lib/concurrent/futures | |
parent | 7291108d88ea31d205da4db19d202d6cbffc6d93 (diff) | |
download | cpython-a94ee12c26aa8dd7dce01373779df8055aff765b.zip cpython-a94ee12c26aa8dd7dce01373779df8055aff765b.tar.gz cpython-a94ee12c26aa8dd7dce01373779df8055aff765b.tar.bz2 |
bpo-34819: Use a monotonic clock to compute timeouts in concurrent.futures (GH-9599)
Use a monotonic clock to compute timeouts in :meth:`Executor.map` and :func:`as_completed`, in order to prevent timeouts from deviating when the system clock is adjusted.
This may not be sufficient on all systems. On POSIX for example, the actual waiting (e.g. in ``sem_timedwait``) is specified to rely on the CLOCK_REALTIME clock.
Diffstat (limited to 'Lib/concurrent/futures')
-rw-r--r-- | Lib/concurrent/futures/_base.py | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index d4416c6..8b9dc50 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -216,7 +216,7 @@ def as_completed(fs, timeout=None): before the given timeout. """ if timeout is not None: - end_time = timeout + time.time() + end_time = timeout + time.monotonic() fs = set(fs) total_futures = len(fs) @@ -235,7 +235,7 @@ def as_completed(fs, timeout=None): if timeout is None: wait_timeout = None else: - wait_timeout = end_time - time.time() + wait_timeout = end_time - time.monotonic() if wait_timeout < 0: raise TimeoutError( '%d (of %d) futures unfinished' % ( @@ -578,7 +578,7 @@ class Executor(object): Exception: If fn(*args) raises for any values. """ if timeout is not None: - end_time = timeout + time.time() + end_time = timeout + time.monotonic() fs = [self.submit(fn, *args) for args in zip(*iterables)] @@ -593,7 +593,7 @@ class Executor(object): if timeout is None: yield fs.pop().result() else: - yield fs.pop().result(end_time - time.time()) + yield fs.pop().result(end_time - time.monotonic()) finally: for future in fs: future.cancel() |