commit: 7d7ef237f3dddcf450fedab5aabfd57d1fb3406d Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Tue Feb 6 01:35:25 2024 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Wed Feb 7 00:36:56 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=7d7ef237
ForkProcess: Handle BrokenPipeError in _send_fd_pipes Convert _send_fd_pipes BrokenPipeError to asyncio.CancelledError, in order to gracefully handle a concurrently terminated child process as in testAsynchronousLockWaitCancel. Even if the child terminated abnormally, then there is no harm in suppressing the exception here, since the child error should have gone to stderr. Bug: https://bugs.gentoo.org/923852 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> lib/portage/util/_async/ForkProcess.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/portage/util/_async/ForkProcess.py b/lib/portage/util/_async/ForkProcess.py index cb240d0712..ebcbd94107 100644 --- a/lib/portage/util/_async/ForkProcess.py +++ b/lib/portage/util/_async/ForkProcess.py @@ -153,15 +153,24 @@ class ForkProcess(SpawnProcess): This performs blocking IO, intended for invocation via run_in_executor. """ fd_list = list(set(self._fd_pipes.values())) - self._files.connection.send( - (self._fd_pipes, fd_list), - ) - for fd in fd_list: - multiprocessing.reduction.send_handle( - self._files.connection, - fd, - self.pid, + try: + self._files.connection.send( + (self._fd_pipes, fd_list), ) + for fd in fd_list: + multiprocessing.reduction.send_handle( + self._files.connection, + fd, + self.pid, + ) + except BrokenPipeError as e: + # This case is triggered by testAsynchronousLockWaitCancel + # when the test case terminates the child process while + # this thread is still sending the fd_pipes (bug 923852). + # Even if the child terminated abnormally, then there is + # no harm in suppressing the exception here, since the + # child error should have gone to stderr. + raise asyncio.CancelledError from e # self._fd_pipes contains duplicates that must be closed. for fd in fd_list:
