commit:     c98240fba21b319e27fe595d70c671c9ddfb7fd0
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Thu Oct  5 08:20:14 2023 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Thu Oct  5 08:21:47 2023 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=c98240fb

AsyncioEventLoop: Put back _ChildWatcherThreadSafetyWrapper

In case there are multiple loops running in different threads,
use _ChildWatcherThreadSafetyWrapper. This partially reverts
commit 690ac6e78c4099e83b84ef11c0b4064b077a8ef0.

Bug: https://bugs.gentoo.org/914873
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/util/_eventloop/asyncio_event_loop.py | 30 ++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/lib/portage/util/_eventloop/asyncio_event_loop.py 
b/lib/portage/util/_eventloop/asyncio_event_loop.py
index fe941b420a..2b21e6dfaf 100644
--- a/lib/portage/util/_eventloop/asyncio_event_loop.py
+++ b/lib/portage/util/_eventloop/asyncio_event_loop.py
@@ -112,7 +112,7 @@ class AsyncioEventLoop(_AbstractEventLoop):
                 watcher = ThreadedChildWatcher()
 
             watcher.attach_loop(self._loop)
-            self._child_watcher = watcher
+            self._child_watcher = _ChildWatcherThreadSafetyWrapper(self, 
watcher)
 
         return self._child_watcher
 
@@ -153,3 +153,31 @@ class AsyncioEventLoop(_AbstractEventLoop):
             except ValueError:
                 # This is intended to fail when not called in the main thread.
                 pass
+
+
+class _ChildWatcherThreadSafetyWrapper:
+    """
+    This class provides safety if multiple loops are running in different 
threads.
+    """
+
+    def __init__(self, loop, real_watcher):
+        self._loop = loop
+        self._real_watcher = real_watcher
+
+    def close(self):
+        pass
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, a, b, c):
+        pass
+
+    def _child_exit(self, pid, status, callback, *args):
+        self._loop.call_soon_threadsafe(callback, pid, status, *args)
+
+    def add_child_handler(self, pid, callback, *args):
+        self._real_watcher.add_child_handler(pid, self._child_exit, callback, 
*args)
+
+    def remove_child_handler(self, pid):
+        return self._real_watcher.remove_child_handler(pid)

Reply via email to