commit: ca8d46112c5b0f7ab9f298915b1cee5a39523173 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Wed Feb 7 04:33:16 2024 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Wed Feb 7 15:31:30 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=ca8d4611
LockNonblockTestCase: Use multiprocessing.Process instead of os.fork() Since os.fork() is unsafe in threaded processes, use multiprocessing.Process instead. This way the fork will be eliminated when the default multiprocessing start method changes to "spawn". Bug: https://bugs.gentoo.org/914876 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> lib/portage/tests/locks/test_lock_nonblock.py | 52 +++++++++++++-------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/portage/tests/locks/test_lock_nonblock.py b/lib/portage/tests/locks/test_lock_nonblock.py index 9bb91b428e..d30dfe113b 100644 --- a/lib/portage/tests/locks/test_lock_nonblock.py +++ b/lib/portage/tests/locks/test_lock_nonblock.py @@ -1,6 +1,8 @@ # Copyright 2011-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 +import multiprocessing +import sys import tempfile import traceback @@ -17,37 +19,35 @@ class LockNonblockTestCase(TestCase): try: path = os.path.join(tempdir, "lock_me") lock1 = portage.locks.lockfile(path) - pid = os.fork() - if pid == 0: - portage.locks._close_fds() - # Disable close_fds since we don't exec - # (see _setup_pipes docstring). - portage.process._setup_pipes({0: 0, 1: 1, 2: 2}, close_fds=False) - rval = 2 - try: - try: - lock2 = portage.locks.lockfile(path, flags=os.O_NONBLOCK) - except portage.exception.TryAgain: - rval = os.EX_OK - else: - rval = 1 - portage.locks.unlockfile(lock2) - except SystemExit: - raise - except: - traceback.print_exc() - finally: - os._exit(rval) - - self.assertEqual(pid > 0, True) - pid, status = os.waitpid(pid, 0) - self.assertEqual(os.WIFEXITED(status), True) - self.assertEqual(os.WEXITSTATUS(status), os.EX_OK) + proc = multiprocessing.Process(target=self._lock_subprocess, args=(path,)) + proc.start() + self.assertEqual(proc.pid > 0, True) + proc.join() + self.assertEqual(proc.exitcode, os.EX_OK) portage.locks.unlockfile(lock1) finally: shutil.rmtree(tempdir) + @staticmethod + def _lock_subprocess(path): + portage.locks._close_fds() + # Disable close_fds since we don't exec + # (see _setup_pipes docstring). + portage.process._setup_pipes({0: 0, 1: 1, 2: 2}, close_fds=False) + rval = 2 + try: + try: + lock2 = portage.locks.lockfile(path, flags=os.O_NONBLOCK) + except portage.exception.TryAgain: + rval = os.EX_OK + else: + rval = 1 + portage.locks.unlockfile(lock2) + except Exception: + traceback.print_exc() + sys.exit(rval) + def testLockNonblock(self): self._testLockNonblock()
