diff options
author | Jamie Phan <jamie@ordinarylab.dev> | 2024-02-19 00:01:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-19 00:01:00 (GMT) |
commit | 53d5e67804227d541ed2f9e8efea8de5d70cb1ec (patch) | |
tree | 7be39b738d6e8e039bc1507e2ebbc9dc0f080f08 /Lib/asyncio/base_events.py | |
parent | edea0e7d9938139d53af84de817097bc12bb8f92 (diff) | |
download | cpython-53d5e67804227d541ed2f9e8efea8de5d70cb1ec.zip cpython-53d5e67804227d541ed2f9e8efea8de5d70cb1ec.tar.gz cpython-53d5e67804227d541ed2f9e8efea8de5d70cb1ec.tar.bz2 |
gh-111358: Fix timeout behaviour in BaseEventLoop.shutdown_default_executor (#115622)
Diffstat (limited to 'Lib/asyncio/base_events.py')
-rw-r--r-- | Lib/asyncio/base_events.py | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index aadc4f4..6c5cf28 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -45,6 +45,7 @@ from . import protocols from . import sslproto from . import staggered from . import tasks +from . import timeouts from . import transports from . import trsock from .log import logger @@ -598,23 +599,24 @@ class BaseEventLoop(events.AbstractEventLoop): thread = threading.Thread(target=self._do_shutdown, args=(future,)) thread.start() try: - await future - finally: - thread.join(timeout) - - if thread.is_alive(): + async with timeouts.timeout(timeout): + await future + except TimeoutError: warnings.warn("The executor did not finishing joining " - f"its threads within {timeout} seconds.", - RuntimeWarning, stacklevel=2) + f"its threads within {timeout} seconds.", + RuntimeWarning, stacklevel=2) self._default_executor.shutdown(wait=False) + else: + thread.join() def _do_shutdown(self, future): try: self._default_executor.shutdown(wait=True) if not self.is_closed(): - self.call_soon_threadsafe(future.set_result, None) + self.call_soon_threadsafe(futures._set_result_unless_cancelled, + future, None) except Exception as ex: - if not self.is_closed(): + if not self.is_closed() and not future.cancelled(): self.call_soon_threadsafe(future.set_exception, ex) def _check_running(self): |