Re: [PATCH 1/3] Add cached portage.getpid() function

Michał Górny <[email protected]>
Newsgroups gmane.linux.gentoo.portage.devel
Organization Gentoo
Message-ID <[email protected]>
On Fri, 2020-08-07 at 21:08 -0700, Zac Medico wrote:
> Since getpid is a syscall, cache results, and update them
> via an after fork hook.
> 
> Signed-off-by: Zac Medico <[email protected]>
> ---
>  lib/portage/__init__.py                       | 14 +++++++++++
>  .../tests/process/test_AsyncFunction.py       | 24 +++++++++++++++++++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
> index 916c93510..52902ba7d 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,19 @@ _internal_caller = False
>  
>  _sync_mode = False
>  
> +def _fork_watcher(_fork_watcher):
> +	_fork_watcher.current_pid = _os.getpid()

I don't really like the idea of putting variables on functions.  Would
there be any problem with using a proper class here?

> +
> +_fork_watcher(_fork_watcher)
> +
> +multiprocessing.util.register_after_fork(_fork_watcher, _fork_watcher)
> +
> +def getpid():
> +	"""
> +	Cached version of os.getpid(). ForkProcess updates the cache.
> +	"""
> +	return _fork_watcher.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)

-- 
Best regards,
Michał Górny
signature.asc (application/pgp-signature, 618 B)
-----BEGIN PGP SIGNATURE-----

iQGTBAABCgB9FiEEx2qEUJQJjSjMiybFY5ra4jKeJA4FAl8uPURfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEM3
NkE4NDUwOTQwOThEMjhDQzhCMjZDNTYzOUFEQUUyMzI5RTI0MEUACgkQY5ra4jKe
JA6FIggAhiIK84kQK8ngNR5X584vzS919ygm7qIqgOFeeSOlLGHd5i/ZDZvLwdBm
riVgK+GZKk8CkYb3gzRj1ymR45Me/93SnRfHXu33znXLoUF592a+5uVigllegKFJ
7+LQKM3oaGovNsFbJGn12SOc2tO3FcqlEUbJ8DAq8pVN4hk1GXVkhiWqmTjpAY4O
nmAeX5/xQVd8QyIs3CmPW/zr3s77Iop/RG89QOw67bSPmeAapzSk7qhvethfCTkn
Sz60HyKWKSss8stPpYHW4oEmTb7lRJTxpCpgDCNvnR7rVKM4cgVEpNvB8LIoXFgK
gpNhIiNfS7B95nPxB4yWLi60MsMB9A==
=VWoG
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.