mirror of https://github.com/python/cpython
GH-96827: Don't touch closed loops from executor threads (#96837)
* When chaining futures, skip callback if loop closed. * When shutting down an executor, don't wake a closed loop.
This commit is contained in:
parent
b05dd79649
commit
e9d63760fe
|
@ -588,9 +588,11 @@ class BaseEventLoop(events.AbstractEventLoop):
|
||||||
def _do_shutdown(self, future):
|
def _do_shutdown(self, future):
|
||||||
try:
|
try:
|
||||||
self._default_executor.shutdown(wait=True)
|
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:
|
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):
|
def _check_running(self):
|
||||||
if self.is_running():
|
if self.is_running():
|
||||||
|
|
|
@ -404,6 +404,8 @@ def _chain_future(source, destination):
|
||||||
if dest_loop is None or dest_loop is source_loop:
|
if dest_loop is None or dest_loop is source_loop:
|
||||||
_set_state(destination, source)
|
_set_state(destination, source)
|
||||||
else:
|
else:
|
||||||
|
if dest_loop.is_closed():
|
||||||
|
return
|
||||||
dest_loop.call_soon_threadsafe(_set_state, destination, source)
|
dest_loop.call_soon_threadsafe(_set_state, destination, source)
|
||||||
|
|
||||||
destination.add_done_callback(_call_check_cancel)
|
destination.add_done_callback(_call_check_cancel)
|
||||||
|
|
|
@ -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).
|
Loading…
Reference in New Issue