[PATCH] Use default asyncio event loop implementation in child processes

Zac Medico <[email protected]> Sun, 6 Dec 2020 00:59:04 -0800
Newsgroups gmane.linux.gentoo.portage.devel
Message-ID <[email protected]>
Use the default asyncio event loop implementation in child
processes, instead of portage's internal EventLoop. After
fork, instantiate a new asyncio.DefaultEventLoopPolicy as
a workaround for https://bugs.python.org/issue22087, which
is necessary for RetryTestCase to succeed.

Bug: https://bugs.gentoo.org/758740
Signed-off-by: Zac Medico <[email protected]>
---
 lib/portage/__init__.py                          | 4 ++++
 lib/portage/util/_eventloop/global_event_loop.py | 7 -------
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
index 4d4b590a8..2b821e81a 100644
--- a/lib/portage/__init__.py
+++ b/lib/portage/__init__.py
@@ -9,6 +9,7 @@ VERSION = "HEAD"
 # ===========================================================================
 
 try:
+	import asyncio
 	import sys
 	import errno
 	if not hasattr(errno, 'ESTALE'):
@@ -373,6 +374,9 @@ class _ForkWatcher:
 	@staticmethod
 	def hook(_ForkWatcher):
 		_ForkWatcher.current_pid = _os.getpid()
+		# Force instantiation of a new event loop as a workaround for
+		# https://bugs.python.org/issue22087.
+		asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
 
 _ForkWatcher.hook(_ForkWatcher)
 
diff --git a/lib/portage/util/_eventloop/global_event_loop.py b/lib/portage/util/_eventloop/global_event_loop.py
index 21a1d1970..413011178 100644
--- a/lib/portage/util/_eventloop/global_event_loop.py
+++ b/lib/portage/util/_eventloop/global_event_loop.py
@@ -2,11 +2,8 @@
 # Distributed under the terms of the GNU General Public License v2
 
 import portage
-from .EventLoop import EventLoop
 from portage.util._eventloop.asyncio_event_loop import AsyncioEventLoop
 
-
-_MAIN_PID = portage.getpid()
 _instances = {}
 
 
@@ -22,10 +19,6 @@ def global_event_loop():
 		return instance
 
 	constructor = AsyncioEventLoop
-	# If the default constructor doesn't support multiprocessing,
-	# then multiprocessing constructor is used in subprocesses.
-	if not constructor.supports_multiprocessing and pid != _MAIN_PID:
-		constructor = EventLoop
 
 	# Use the _asyncio_wrapper attribute, so that unit tests can compare
 	# the reference to one retured from _wrap_loop(), since they should
-- 
2.26.2