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()
 

Reply via email to