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] BinpkgFetcher: use async lock (bug 614110)
@ 2018-04-21 19:27 99% Zac Medico
  0 siblings, 0 replies; 1+ results
From: Zac Medico @ 2018-04-21 19:27 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

In order to avoid event loop recursion, convert the
_BinpkgFetcherProcess.lock() method to an async_lock
method for use by BinpkgFetcher.

Bug: https://bugs.gentoo.org/614110
---
 pym/_emerge/BinpkgFetcher.py | 53 +++++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 20 deletions(-)

diff --git a/pym/_emerge/BinpkgFetcher.py b/pym/_emerge/BinpkgFetcher.py
index 5ca7a45cf..2bbc0a26f 100644
--- a/pym/_emerge/BinpkgFetcher.py
+++ b/pym/_emerge/BinpkgFetcher.py
@@ -32,11 +32,24 @@ class BinpkgFetcher(CompositeTask):
 			pkg.cpv) + ".partial"
 
 	def _start(self):
-		self._start_task(
-			_BinpkgFetcherProcess(background=self.background,
-				logfile=self.logfile, pkg=self.pkg, pkg_path=self.pkg_path,
-				pretend=self.pretend, scheduler=self.scheduler),
-			self._fetcher_exit)
+		fetcher = _BinpkgFetcherProcess(background=self.background,
+			logfile=self.logfile, pkg=self.pkg, pkg_path=self.pkg_path,
+			pretend=self.pretend, scheduler=self.scheduler)
+
+		if not self.pretend:
+			portage.util.ensure_dirs(os.path.dirname(self.pkg_path))
+			if "distlocks" in self.pkg.root_config.settings.features:
+				self._start_task(
+					AsyncTaskFuture(future=fetcher.async_lock()),
+					functools.partial(self._start_locked, fetcher))
+				return
+
+		self._start_task(fetcher, self._fetcher_exit)
+
+	def _start_locked(self, fetcher, lock_task):
+		self._assert_current(lock_task)
+		lock_task.future.result()
+		self._start_task(fetcher, self._fetcher_exit)
 
 	def _fetcher_exit(self, fetcher):
 		self._assert_current(fetcher)
@@ -68,13 +81,8 @@ class _BinpkgFetcherProcess(SpawnProcess):
 		pretend = self.pretend
 		bintree = pkg.root_config.trees["bintree"]
 		settings = bintree.settings
-		use_locks = "distlocks" in settings.features
 		pkg_path = self.pkg_path
 
-		if not pretend:
-			portage.util.ensure_dirs(os.path.dirname(pkg_path))
-			if use_locks:
-				self.lock()
 		exists = os.path.exists(pkg_path)
 		resume = exists and os.path.basename(pkg_path) in bintree.invalids
 		if not (pretend or resume):
@@ -184,7 +192,7 @@ class _BinpkgFetcherProcess(SpawnProcess):
 								except OSError:
 									pass
 
-	def lock(self):
+	def async_lock(self):
 		"""
 		This raises an AlreadyLocked exception if lock() is called
 		while a lock is already held. In order to avoid this, call
@@ -194,17 +202,22 @@ class _BinpkgFetcherProcess(SpawnProcess):
 		if self._lock_obj is not None:
 			raise self.AlreadyLocked((self._lock_obj,))
 
-		async_lock = AsynchronousLock(path=self.pkg_path,
-			scheduler=self.scheduler)
-		async_lock.start()
+		result = self.scheduler.create_future()
 
-		if async_lock.wait() != os.EX_OK:
-			# TODO: Use CompositeTask for better handling, like in EbuildPhase.
-			raise AssertionError("AsynchronousLock failed with returncode %s" \
-				% (async_lock.returncode,))
+		def acquired_lock(async_lock):
+			if async_lock.wait() == os.EX_OK:
+				self.locked = True
+				result.set_result(None)
+			else:
+				result.set_exception(AssertionError(
+					"AsynchronousLock failed with returncode %s"
+					% (async_lock.returncode,)))
 
-		self._lock_obj = async_lock
-		self.locked = True
+		self._lock_obj = AsynchronousLock(path=self.pkg_path,
+			scheduler=self.scheduler)
+		self._lock_obj.addExitListener(acquired_lock)
+		self._lock_obj.start()
+		return result
 
 	class AlreadyLocked(portage.exception.PortageException):
 		pass
-- 
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-21 19:27 99% [gentoo-portage-dev] [PATCH] BinpkgFetcher: use async lock (bug 614110) Zac Medico

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