From: Zac Medico <zmedico@gentoo.org>
To: gentoo-portage-dev@lists.gentoo.org
Cc: Zac Medico <zmedico@gentoo.org>
Subject: [gentoo-portage-dev] [PATCH 1/3 v2] Add cached portage.getpid() function
Date: Fri, 7 Aug 2020 23:07:27 -0700 [thread overview]
Message-ID: <20200808060727.80682-1-zmedico@gentoo.org> (raw)
In-Reply-To: <20200808040857.77352-2-zmedico@gentoo.org>
Since getpid is a syscall, cache results, and update them
via an after fork hook.
Signed-off-by: Zac Medico <zmedico@gentoo.org>
---
lib/portage/__init__.py | 16 +++++++++++++
.../tests/process/test_AsyncFunction.py | 24 +++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
index 916c93510..4d4b590a8 100644
--- a/lib/portage/__init__.py
+++ b/lib/portage/__init__.py
@@ -14,6 +14,7 @@ try:
if not hasattr(errno, 'ESTALE'):
# ESTALE may not be defined on some systems, such as interix.
errno.ESTALE = -1
+ import multiprocessing.util
import re
import types
import platform
@@ -368,6 +369,21 @@ _internal_caller = False
_sync_mode = False
+class _ForkWatcher:
+ @staticmethod
+ def hook(_ForkWatcher):
+ _ForkWatcher.current_pid = _os.getpid()
+
+_ForkWatcher.hook(_ForkWatcher)
+
+multiprocessing.util.register_after_fork(_ForkWatcher, _ForkWatcher.hook)
+
+def getpid():
+ """
+ Cached version of os.getpid(). ForkProcess updates the cache.
+ """
+ return _ForkWatcher.current_pid
+
def _get_stdin():
"""
Buggy code in python's multiprocessing/process.py closes sys.stdin
diff --git a/lib/portage/tests/process/test_AsyncFunction.py b/lib/portage/tests/process/test_AsyncFunction.py
index 55857026d..3b360e02f 100644
--- a/lib/portage/tests/process/test_AsyncFunction.py
+++ b/lib/portage/tests/process/test_AsyncFunction.py
@@ -3,6 +3,7 @@
import sys
+import portage
from portage import os
from portage.tests import TestCase
from portage.util._async.AsyncFunction import AsyncFunction
@@ -36,3 +37,26 @@ class AsyncFunctionTestCase(TestCase):
def testAsyncFunctionStdin(self):
loop = asyncio._wrap_loop()
loop.run_until_complete(self._testAsyncFunctionStdin(loop))
+
+ def _test_getpid_fork(self):
+ """
+ Verify that portage.getpid() cache is updated in a forked child process.
+ """
+ loop = asyncio._wrap_loop()
+ proc = AsyncFunction(scheduler=loop, target=portage.getpid)
+ proc.start()
+ proc.wait()
+ self.assertEqual(proc.pid, proc.result)
+
+ def test_getpid_fork(self):
+ self._test_getpid_fork()
+
+ def test_getpid_double_fork(self):
+ """
+ Verify that portage.getpid() cache is updated correctly after
+ two forks.
+ """
+ loop = asyncio._wrap_loop()
+ proc = AsyncFunction(scheduler=loop, target=self._test_getpid_fork)
+ proc.start()
+ self.assertEqual(proc.wait(), 0)
--
2.25.3
next prev parent reply other threads:[~2020-08-08 6:09 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-08 4:08 [gentoo-portage-dev] [PATCH 0/3] sqlite: fork safety (bug 736334) Zac Medico
2020-08-08 4:08 ` [gentoo-portage-dev] [PATCH 1/3] Add cached portage.getpid() function Zac Medico
2020-08-08 5:51 ` Michał Górny
2020-08-08 6:07 ` Zac Medico [this message]
2020-08-08 4:08 ` [gentoo-portage-dev] [PATCH 2/3] sqlite: add lazy connection init Zac Medico
2020-08-08 4:08 ` [gentoo-portage-dev] [PATCH 3/3] sqlite: fork safety (bug 736334) Zac Medico
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200808060727.80682-1-zmedico@gentoo.org \
--to=zmedico@gentoo.org \
--cc=gentoo-portage-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox