From 8074127bbc213fde75d51309c8fb4ee33ad278aa Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sat, 29 Feb 2020 00:33:46 -0800 Subject: [PATCH] SpawnProcess: add _main coroutine Add a _main coroutine method and make the PipeLogger instance a local variable. Signed-off-by: Zac Medico --- lib/_emerge/SpawnProcess.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/_emerge/SpawnProcess.py b/lib/_emerge/SpawnProcess.py index ba58d9d0e7..cda615dede 100644 --- a/lib/_emerge/SpawnProcess.py +++ b/lib/_emerge/SpawnProcess.py @@ -20,6 +20,7 @@ from portage.output import EOutput from portage.util import writemsg_level from portage.util._async.PipeLogger import PipeLogger +from portage.util.futures import asyncio from portage.util.futures.compat_coroutine import coroutine class SpawnProcess(SubProcess): @@ -36,7 +37,7 @@ class SpawnProcess(SubProcess): "unshare_ipc", "unshare_mount", "unshare_pid", "unshare_net") __slots__ = ("args",) + \ - _spawn_kwarg_names + ("_pipe_logger", "_selinux_type",) + _spawn_kwarg_names + ("_main_task", "_selinux_type",) # Max number of attempts to kill the processes listed in cgroup.procs, # given that processes may fork before they can be killed. @@ -141,13 +142,28 @@ def _async_start(self): fcntl.fcntl(stdout_fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC) - self._pipe_logger = PipeLogger(background=self.background, + pipe_logger = PipeLogger(background=self.background, scheduler=self.scheduler, input_fd=master_fd, log_file_path=log_file_path, stdout_fd=stdout_fd) - self._pipe_logger.addExitListener(self._pipe_logger_exit) self._registered = True - yield self._pipe_logger.async_start() + yield pipe_logger.async_start() + + self._main_task = asyncio.ensure_future( + self._main(pipe_logger), loop=self.scheduler) + self._main_task.add_done_callback(self._main_exit) + + @coroutine + def _main(self, pipe_logger): + if pipe_logger.poll() is None: + yield pipe_logger.async_wait() + + def _main_exit(self, main_task): + try: + main_task.result() + except asyncio.CancelledError: + self.cancel() + self._async_waitpid() def _can_log(self, slave_fd): return True @@ -171,21 +187,16 @@ def _spawn(self, args, **kwargs): return spawn_func(args, **kwargs) - def _pipe_logger_exit(self, pipe_logger): - self._pipe_logger = None - self._async_waitpid() - def _unregister(self): SubProcess._unregister(self) if self.cgroup is not None: self._cgroup_cleanup() self.cgroup = None - if self._pipe_logger is not None: - self._pipe_logger.cancel() - self._pipe_logger = None def _cancel(self): SubProcess._cancel(self) + if self._main_task is not None: + self._main_task.cancel() self._cgroup_cleanup() def _cgroup_cleanup(self):