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)
