public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download: 
* [gentoo-portage-dev] [PATCH] AsynchronousTask: disable event loop recursion (bug 653856)
@ 2018-04-28 14:41 99% Zac Medico
  0 siblings, 0 replies; 1+ results
From: Zac Medico @ 2018-04-28 14:41 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

Make the wait() and _async_wait() methods raise InvalidStateError
when the event loop is running and the returncode is not available,
since these cases would trigger event loop recursion. There are no
known remaining cases that cause event loop recursion via wait()
and _async_wait(), and this patch protects against changes that would
accidentally re-introduce event loop recursion.

Since the wait() method now raises InvalidStateError in cases where
it previously would have called the _wait() method, this patch makes
it possible to remove the _wait() method implementations from all
subclasses of AsynchronousTask.

Bug: https://bugs.gentoo.org/653856
---
 pym/_emerge/AbstractEbuildProcess.py |  3 +++
 pym/_emerge/AsynchronousTask.py      | 15 +++++++--------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/pym/_emerge/AbstractEbuildProcess.py b/pym/_emerge/AbstractEbuildProcess.py
index d481e6046..606c909e8 100644
--- a/pym/_emerge/AbstractEbuildProcess.py
+++ b/pym/_emerge/AbstractEbuildProcess.py
@@ -18,6 +18,7 @@ from portage.localization import _
 from portage.package.ebuild._ipc.ExitCommand import ExitCommand
 from portage.package.ebuild._ipc.QueryCommand import QueryCommand
 from portage import shutil, os
+from portage.util.futures import asyncio
 from portage.util._pty import _create_pty_or_pipe
 from portage.util import apply_secpass_permissions
 
@@ -420,6 +421,8 @@ class AbstractEbuildProcess(SpawnProcess):
 		if self._build_dir is None:
 			SpawnProcess._async_wait(self)
 		elif self._build_dir_unlock is None:
+			if self.returncode is None:
+				raise asyncio.InvalidStateError('Result is not ready.')
 			self._async_unlock_builddir(returncode=self.returncode)
 
 	def _async_unlock_builddir(self, returncode=None):
diff --git a/pym/_emerge/AsynchronousTask.py b/pym/_emerge/AsynchronousTask.py
index 7d2e6253b..5cc6d3b7d 100644
--- a/pym/_emerge/AsynchronousTask.py
+++ b/pym/_emerge/AsynchronousTask.py
@@ -4,6 +4,7 @@
 import signal
 
 from portage import os
+from portage.util.futures import asyncio
 from portage.util.SlotObject import SlotObject
 
 class AsynchronousTask(SlotObject):
@@ -17,8 +18,7 @@ class AsynchronousTask(SlotObject):
 	"""
 
 	__slots__ = ("background", "cancelled", "returncode", "scheduler") + \
-		("_exit_listeners", "_exit_listener_stack", "_start_listeners",
-		"_waiting")
+		("_exit_listeners", "_exit_listener_stack", "_start_listeners")
 
 	_cancelled_returncode = - signal.SIGINT
 
@@ -71,12 +71,9 @@ class AsynchronousTask(SlotObject):
 		Deprecated. Use async_wait() instead.
 		"""
 		if self.returncode is None:
-			if not self._waiting:
-				self._waiting = True
-				try:
-					self._wait()
-				finally:
-					self._waiting = False
+			if self.scheduler.is_running():
+				raise asyncio.InvalidStateError('Result is not ready.')
+			self.scheduler.run_until_complete(self.async_wait())
 		self._wait_hook()
 		return self.returncode
 
@@ -91,6 +88,8 @@ class AsynchronousTask(SlotObject):
 		loop recursion (or stack overflow) that synchronous calling of
 		exit listeners can cause. This method is thread-safe.
 		"""
+		if self.returncode is None:
+			raise asyncio.InvalidStateError('Result is not ready.')
 		self.scheduler.idle_add(self._async_wait_cb)
 
 	def _async_wait_cb(self):
-- 
2.13.6



^ permalink raw reply related	[relevance 99%]

Results 1-1 of 1 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2018-04-28 14:41 99% [gentoo-portage-dev] [PATCH] AsynchronousTask: disable event loop recursion (bug 653856) Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox