]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-96827: Don't touch closed loops from executor threads (#96837)
authorGuido van Rossum <guido@python.org>
Fri, 30 Sep 2022 19:55:40 +0000 (12:55 -0700)
committerGitHub <noreply@github.com>
Fri, 30 Sep 2022 19:55:40 +0000 (12:55 -0700)
* When chaining futures, skip callback if loop closed.
* When shutting down an executor, don't wake a closed loop.

Lib/asyncio/base_events.py
Lib/asyncio/futures.py
Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst [new file with mode: 0644]

index 9c9d98dbb9c50985b035c40a6cbd3f591688e6c7..2df9dcac8f723f7e9000bedde860c2735ee5e924 100644 (file)
@@ -588,9 +588,11 @@ class BaseEventLoop(events.AbstractEventLoop):
     def _do_shutdown(self, future):
         try:
             self._default_executor.shutdown(wait=True)
-            self.call_soon_threadsafe(future.set_result, None)
+            if not self.is_closed():
+                self.call_soon_threadsafe(future.set_result, None)
         except Exception as ex:
-            self.call_soon_threadsafe(future.set_exception, ex)
+            if not self.is_closed():
+                self.call_soon_threadsafe(future.set_exception, ex)
 
     def _check_running(self):
         if self.is_running():
index 4bd9629e9eb62b6326e3db4ce7f9059a2c02f430..39776e3c2cce48c4125d812aa194d58adcc900b8 100644 (file)
@@ -404,6 +404,8 @@ def _chain_future(source, destination):
         if dest_loop is None or dest_loop is source_loop:
             _set_state(destination, source)
         else:
+            if dest_loop.is_closed():
+                return
             dest_loop.call_soon_threadsafe(_set_state, destination, source)
 
     destination.add_done_callback(_call_check_cancel)
diff --git a/Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst b/Misc/NEWS.d/next/Library/2022-09-30-15-56-20.gh-issue-96827.lzy1iw.rst
new file mode 100644 (file)
index 0000000..159ab32
--- /dev/null
@@ -0,0 +1 @@
+Avoid spurious tracebacks from :mod:`asyncio` when default executor cleanup is delayed until after the event loop is closed (e.g. as the result of a keyboard interrupt).