* [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