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):
         """

Reply via email to