summaryrefslogtreecommitdiff
path: root/Lib/concurrent/futures/_base.py
diff options
context:
space:
mode:
authorƁukasz Langa <lukasz@langa.pl>2022-07-29 14:36:58 +0200
committerGitHub <noreply@github.com>2022-07-29 14:36:58 +0200
commit18418858b2cfca221613af1c58bf657f8bfb6d6c (patch)
treee0d2c9030193381ce68b2a3c8865f25204ffe6c9 /Lib/concurrent/futures/_base.py
parenta41b51d2ea1926b60ea10d533dda54a5af7936ba (diff)
downloadcpython-git-18418858b2cfca221613af1c58bf657f8bfb6d6c.tar.gz
[3.10] gh-95166: cancel map waited on future on timeout (GH-95169) (GH-95375)
Co-authored-by: Thomas Grainger <tagrain@gmail.com> Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Diffstat (limited to 'Lib/concurrent/futures/_base.py')
-rw-r--r--Lib/concurrent/futures/_base.py16
1 files changed, 14 insertions, 2 deletions
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index cf119ac643..a329e74d11 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -312,6 +312,18 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
done.update(waiter.finished_futures)
return DoneAndNotDoneFutures(done, fs - done)
+
+def _result_or_cancel(fut, timeout=None):
+ try:
+ try:
+ return fut.result(timeout)
+ finally:
+ fut.cancel()
+ finally:
+ # Break a reference cycle with the exception in self._exception
+ del fut
+
+
class Future(object):
"""Represents the result of an asynchronous computation."""
@@ -606,9 +618,9 @@ class Executor(object):
while fs:
# Careful not to keep a reference to the popped future
if timeout is None:
- yield fs.pop().result()
+ yield _result_or_cancel(fs.pop())
else:
- yield fs.pop().result(end_time - time.monotonic())
+ yield _result_or_cancel(fs.pop(), end_time - time.monotonic())
finally:
for future in fs:
future.cancel()