From 636b9ea053ba4aafb83c12941735d3c3afebb4ae Mon Sep 17 00:00:00 2001 From: Jens Reidel Date: Fri, 7 Apr 2023 21:57:35 +0200 Subject: [PATCH] Add thread timeout for loop.shutdown_default_executor Ref: https://github.com/python/cpython/commit/575a253b5c203e8d2ebfd239ed5a613179f8984f Signed-off-by: Jens Reidel --- uvloop/loop.pyi | 2 +- uvloop/loop.pyx | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/uvloop/loop.pyi b/uvloop/loop.pyi index 05d7714b..efee9884 100644 --- a/uvloop/loop.pyi +++ b/uvloop/loop.pyi @@ -271,7 +271,7 @@ class Loop: sock: Optional[socket] = ..., ) -> tuple[asyncio.BaseProtocol, _ProtocolT]: ... async def shutdown_asyncgens(self) -> None: ... - async def shutdown_default_executor(self) -> None: ... + async def shutdown_default_executor(self, timeout: Optional[int] = ...) -> None: ... # Loop doesn't implement these, but since they are marked as abstract in typeshed, # we have to put them in so mypy thinks the base methods are overridden async def sendfile( diff --git a/uvloop/loop.pyx b/uvloop/loop.pyx index f6cb4fca..a62a02d2 100644 --- a/uvloop/loop.pyx +++ b/uvloop/loop.pyx @@ -3200,8 +3200,13 @@ cdef class Loop: }) @cython.iterable_coroutine - async def shutdown_default_executor(self): - """Schedule the shutdown of the default executor.""" + async def shutdown_default_executor(self, timeout=None): + """Schedule the shutdown of the default executor. + + The timeout parameter specifies the amount of time the executor will + be given to finish joining. The default value is None, which means + that the executor will be given an unlimited amount of time. + """ self._executor_shutdown_called = True if self._default_executor is None: return @@ -3211,7 +3216,13 @@ cdef class Loop: try: await future finally: - thread.join() + thread.join(timeout) + + if thread.is_alive(): + warnings_warn("The executor did not finishing joining " + f"its threads within {timeout} seconds.", + RuntimeWarning, stacklevel=2) + self._default_executor.shutdown(wait=False) def _do_shutdown(self, future): try: