commit: 11c65496bd951c3b7778a3c1ea240e347b1f4c38 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Sun Mar 3 21:06:13 2024 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Sun Mar 3 21:10:49 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=11c65496
socks5: Use run_coroutine_exitfuncs() Since commit c3ebdbb42e72 the atexit_register(proxy.stop) call in the get_socks5_proxy function can accept a coroutine function to execute in run_coroutine_exitfuncs(), so convert the ProxyManager stop method to a coroutine and use run_coroutine_exitfuncs(). Bug: https://bugs.gentoo.org/925240 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> lib/portage/tests/util/test_socks5.py | 5 ++- lib/portage/util/_eventloop/asyncio_event_loop.py | 12 ------- lib/portage/util/socks5.py | 39 +++-------------------- 3 files changed, 7 insertions(+), 49 deletions(-) diff --git a/lib/portage/tests/util/test_socks5.py b/lib/portage/tests/util/test_socks5.py index 4a6d08169d..a8cd0c46c4 100644 --- a/lib/portage/tests/util/test_socks5.py +++ b/lib/portage/tests/util/test_socks5.py @@ -216,10 +216,9 @@ class Socks5ServerTestCase(TestCase): self.assertEqual(result, content) finally: try: - # Also run_exitfuncs to test atexit hook cleanup. - await socks5.proxy.stop() + # Also run_coroutine_exitfuncs to test atexit hook cleanup. self.assertNotEqual(portage.process._exithandlers, []) - portage.process.run_exitfuncs() + await portage.process.run_coroutine_exitfuncs() self.assertEqual(portage.process._exithandlers, []) finally: portage.process._exithandlers = previous_exithandlers diff --git a/lib/portage/util/_eventloop/asyncio_event_loop.py b/lib/portage/util/_eventloop/asyncio_event_loop.py index a598b1b516..821cc7f102 100644 --- a/lib/portage/util/_eventloop/asyncio_event_loop.py +++ b/lib/portage/util/_eventloop/asyncio_event_loop.py @@ -15,7 +15,6 @@ except ImportError: PidfdChildWatcher = None import portage -from portage.util import socks5 class AsyncioEventLoop(_AbstractEventLoop): @@ -75,17 +74,6 @@ class AsyncioEventLoop(_AbstractEventLoop): self._closing = False async def _close_main(self): - # Even though this has an exit hook, invoke it here so that - # we can properly wait for it and avoid messages like this: - # [ERROR] Task was destroyed but it is pending! - if socks5.proxy.is_running(): - # TODO: Convert socks5.proxy.stop() to a regular coroutine - # function so that it doesn't need to be wrapped like this. - async def stop_socks5_proxy(): - await socks5.proxy.stop() - - portage.process.atexit_register(stop_socks5_proxy) - await portage.process.run_coroutine_exitfuncs() portage.process.run_exitfuncs() diff --git a/lib/portage/util/socks5.py b/lib/portage/util/socks5.py index f8fcdf9fca..c32ba77674 100644 --- a/lib/portage/util/socks5.py +++ b/lib/portage/util/socks5.py @@ -6,15 +6,8 @@ import asyncio import errno import os import socket -from typing import Union import portage - -portage.proxy.lazyimport.lazyimport( - globals(), - "portage.util._eventloop.global_event_loop:global_event_loop", -) - import portage.data from portage import _python_interpreter from portage.data import portage_gid, portage_uid, userpriv_groups @@ -65,41 +58,19 @@ class ProxyManager: **spawn_kwargs, ) - def stop(self) -> Union[None, asyncio.Future]: + async def stop(self): """ - Stop the SOCKSv5 server. - - If there is a running asyncio event loop then asyncio.Future is - returned which should be used to wait for the server process - to exit. + Stop the SOCKSv5 server. This method is a coroutine. """ - future = None - try: - loop = asyncio.get_running_loop() - except RuntimeError: - loop = None if self._proc is not None: self._proc.terminate() - if loop is None: - # In this case spawn internals would have used - # portage's global loop when attaching a waiter to - # self._proc, so we are obligated to use that. - global_event_loop().run_until_complete(self._proc.wait()) - else: - if self._proc_waiter is None: - self._proc_waiter = asyncio.ensure_future( - self._proc.wait(), loop=loop - ) - future = asyncio.shield(self._proc_waiter) - - if loop is not None and future is None: - future = loop.create_future() - future.set_result(None) + if self._proc_waiter is None: + self._proc_waiter = asyncio.ensure_future(self._proc.wait()) + await self._proc_waiter self.socket_path = None self._proc = None self._proc_waiter = None - return future def is_running(self): """