commit:     72760ab948047cf1f5b9e1c1fcf9d2c4934afc8c
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Tue Oct  3 06:24:21 2023 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue Oct  3 14:47:37 2023 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=72760ab9

ForkProcess: Add target constructor parameter

If the _run method is not implemented, then use a new
"target" constructor parameter like multiprocessing.Process.
Support "args" and "kwargs" constructor parameters as well.

If the _run method is implemented, then behave in a backward
compatible manner, and ignore the "args" and "kwargs" constructor
parameters which are used by the AsyncFunction subclass.

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

 lib/portage/util/_async/AsyncFunction.py |  7 +------
 lib/portage/util/_async/ForkProcess.py   | 35 +++++++++++++++++++++++++++-----
 2 files changed, 31 insertions(+), 11 deletions(-)

diff --git a/lib/portage/util/_async/AsyncFunction.py 
b/lib/portage/util/_async/AsyncFunction.py
index 8c13b3f5ba..f27b255a55 100644
--- a/lib/portage/util/_async/AsyncFunction.py
+++ b/lib/portage/util/_async/AsyncFunction.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2020 Gentoo Authors
+# Copyright 2015-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 import pickle
@@ -16,13 +16,8 @@ class AsyncFunction(ForkProcess):
     "result" attribute after the forked process has exited.
     """
 
-    # NOTE: This class overrides the meaning of the SpawnProcess 'args'
-    # attribute, and uses it to hold the positional arguments for the
-    # 'target' function.
     __slots__ = (
-        "kwargs",
         "result",
-        "target",
         "_async_func_reader",
         "_async_func_reader_pw",
     )

diff --git a/lib/portage/util/_async/ForkProcess.py 
b/lib/portage/util/_async/ForkProcess.py
index 22a0e0cd85..3deaf18fd0 100644
--- a/lib/portage/util/_async/ForkProcess.py
+++ b/lib/portage/util/_async/ForkProcess.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2021 Gentoo Authors
+# Copyright 2012-2023 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
 
 import fcntl
@@ -14,7 +14,15 @@ from _emerge.SpawnProcess import SpawnProcess
 
 
 class ForkProcess(SpawnProcess):
-    __slots__ = ("_proc", "_proc_join_task")
+    # NOTE: This class overrides the meaning of the SpawnProcess 'args'
+    # attribute, and uses it to hold the positional arguments for the
+    # 'target' function.
+    __slots__ = (
+        "kwargs",
+        "target",
+        "_proc",
+        "_proc_join_task",
+    )
 
     # Number of seconds between poll attempts for process exit status
     # (after the sentinel has become ready).
@@ -27,6 +35,18 @@ class ForkProcess(SpawnProcess):
         any pre-fork and post-fork interpreter housekeeping that it provides,
         promoting a healthy state for the forked interpreter.
         """
+
+        if self.__class__._run is ForkProcess._run:
+            # target replaces the deprecated self._run method
+            target = self.target
+            args = self.args
+            kwargs = self.kwargs
+        else:
+            # _run implementation triggers backward-compatibility mode
+            target = self._run
+            args = None
+            kwargs = None
+
         # Since multiprocessing.Process closes sys.__stdin__, create a
         # temporary duplicate of fd_pipes[0] so that sys.__stdin__ can
         # be restored in the subprocess, in case this is needed for
@@ -41,7 +61,8 @@ class ForkProcess(SpawnProcess):
                 )
                 fd_pipes[0] = stdin_dup
             self._proc = multiprocessing.Process(
-                target=self._bootstrap, args=(fd_pipes,)
+                target=self._bootstrap,
+                args=(fd_pipes, target, args, kwargs),
             )
             self._proc.start()
         finally:
@@ -122,7 +143,8 @@ class ForkProcess(SpawnProcess):
             self._proc_join_task.cancel()
             self._proc_join_task = None
 
-    def _bootstrap(self, fd_pipes):
+    @staticmethod
+    def _bootstrap(fd_pipes, target, args, kwargs):
         # Use default signal handlers in order to avoid problems
         # killing subprocesses as reported in bug #353239.
         signal.signal(signal.SIGINT, signal.SIG_DFL)
@@ -159,7 +181,10 @@ class ForkProcess(SpawnProcess):
                 )
             sys.__stdin__ = sys.stdin
 
-        sys.exit(self._run())
+        sys.exit(target(*(args or []), **(kwargs or {})))
 
     def _run(self):
+        """
+        Deprecated and replaced with the "target" constructor parameter.
+        """
         raise NotImplementedError(self)

Reply via email to