From: Min RK Date: Wed, 19 May 2021 07:58:09 +0000 (+0200) Subject: Make AddThreadEventLoop.close() idempotent X-Git-Tag: v6.4.0b1~32^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63ae59dda4bc3d83f7a1265f3c17807d4bc7e78f;p=thirdparty%2Ftornado.git Make AddThreadEventLoop.close() idempotent according to spec: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.close The call to _wake_selector would fail with EBADF when close is called a second time --- diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index b07af3a95..3863e78f2 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -412,6 +412,8 @@ class SelectorThread: but can be attached to a running asyncio loop. """ + _closed = False + def __init__(self, real_loop: asyncio.AbstractEventLoop) -> None: self._real_loop = real_loop @@ -456,6 +458,8 @@ class SelectorThread: self._waker_w.close() def close(self) -> None: + if self._closed: + return with self._select_cond: self._closing_selector = True self._select_cond.notify() @@ -464,6 +468,7 @@ class SelectorThread: _selector_loops.discard(self) self._waker_r.close() self._waker_w.close() + self._closed = True def _wake_selector(self) -> None: try: diff --git a/tornado/test/asyncio_test.py b/tornado/test/asyncio_test.py index 3f9f3389a..59825e8f2 100644 --- a/tornado/test/asyncio_test.py +++ b/tornado/test/asyncio_test.py @@ -20,6 +20,7 @@ from tornado.platform.asyncio import ( AsyncIOLoop, to_asyncio_future, AnyThreadEventLoopPolicy, + AddThreadSelectorEventLoop, ) from tornado.testing import AsyncTestCase, gen_test @@ -107,6 +108,11 @@ class AsyncIOLoopTest(AsyncTestCase): 42, ) + def test_add_thread_close_idempotent(self): + loop = AddThreadSelectorEventLoop(asyncio.get_event_loop()) + loop.close() + loop.close() + class LeakTest(unittest.TestCase): def setUp(self):