From 8522ebe36b57dbfffb74dab8de3369dbe7737d0b Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Tue, 12 Jan 2021 16:02:26 -0300 Subject: [PATCH 1/2] Fix osrf.py_common.process_utils.get_loop() implementation On Windows, avoid loops closing during garbage collection and reuse existing ones if possible. Signed-off-by: Michel Hidalgo --- osrf_pycommon/process_utils/get_loop_impl.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osrf_pycommon/process_utils/get_loop_impl.py b/osrf_pycommon/process_utils/get_loop_impl.py index aa154f1..9b855ca 100644 --- a/osrf_pycommon/process_utils/get_loop_impl.py +++ b/osrf_pycommon/process_utils/get_loop_impl.py @@ -24,8 +24,15 @@ def get_loop_impl(asyncio): return asyncio.get_event_loop() # Setup this thread's loop and return it if os.name == 'nt': - loop = asyncio.ProactorEventLoop() - asyncio.set_event_loop(loop) + try: + loop = asyncio.get_event_loop() + if not isinstance(loop, asyncio.ProactorEventLoop): + loop.close() # avoid closing during garbage collection + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + except (RuntimeError, AssertionError): + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) else: try: loop = asyncio.get_event_loop() From 12e7d990f5bfc0bf0cb2c5b7be601c077b628855 Mon Sep 17 00:00:00 2001 From: Michel Hidalgo Date: Tue, 12 Jan 2021 17:03:00 -0300 Subject: [PATCH 2/2] Address peer review comments. Signed-off-by: Michel Hidalgo --- osrf_pycommon/process_utils/get_loop_impl.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osrf_pycommon/process_utils/get_loop_impl.py b/osrf_pycommon/process_utils/get_loop_impl.py index 9b855ca..a9d6349 100644 --- a/osrf_pycommon/process_utils/get_loop_impl.py +++ b/osrf_pycommon/process_utils/get_loop_impl.py @@ -27,7 +27,11 @@ def get_loop_impl(asyncio): try: loop = asyncio.get_event_loop() if not isinstance(loop, asyncio.ProactorEventLoop): - loop.close() # avoid closing during garbage collection + # Before replacing the existing loop, explicitly + # close it to prevent an implicit close during + # garbage collection, which may or may not be a + # problem depending on the loop implementation. + loop.close() loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) except (RuntimeError, AssertionError):