Skip to content

Commit 3a4aa6a

Browse files
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. (cherry picked from commit a94ee12) Co-authored-by: orlnub123 <[email protected]>
1 parent 6475c05 commit 3a4aa6a

File tree

2 files changed

+5
-4
lines changed

2 files changed

+5
-4
lines changed

Lib/concurrent/futures/_base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def as_completed(fs, timeout=None):
212212
before the given timeout.
213213
"""
214214
if timeout is not None:
215-
end_time = timeout + time.time()
215+
end_time = timeout + time.monotonic()
216216

217217
fs = set(fs)
218218
total_futures = len(fs)
@@ -231,7 +231,7 @@ def as_completed(fs, timeout=None):
231231
if timeout is None:
232232
wait_timeout = None
233233
else:
234-
wait_timeout = end_time - time.time()
234+
wait_timeout = end_time - time.monotonic()
235235
if wait_timeout < 0:
236236
raise TimeoutError(
237237
'%d (of %d) futures unfinished' % (
@@ -570,7 +570,7 @@ def map(self, fn, *iterables, timeout=None, chunksize=1):
570570
Exception: If fn(*args) raises for any values.
571571
"""
572572
if timeout is not None:
573-
end_time = timeout + time.time()
573+
end_time = timeout + time.monotonic()
574574

575575
fs = [self.submit(fn, *args) for args in zip(*iterables)]
576576

@@ -585,7 +585,7 @@ def result_iterator():
585585
if timeout is None:
586586
yield fs.pop().result()
587587
else:
588-
yield fs.pop().result(end_time - time.time())
588+
yield fs.pop().result(end_time - time.monotonic())
589589
finally:
590590
for future in fs:
591591
future.cancel()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
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.

0 commit comments

Comments
 (0)