From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 39DC31382C5 for ; Sun, 22 Apr 2018 00:56:21 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 33BC9E082D; Sun, 22 Apr 2018 00:56:20 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 024ECE082D for ; Sun, 22 Apr 2018 00:56:19 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 67533335C60 for ; Sun, 22 Apr 2018 00:56:18 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id A9AF7257 for ; Sun, 22 Apr 2018 00:56:16 +0000 (UTC) From: "Zac Medico" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" Message-ID: <1524358257.adf2e6dd57b5bcaa4a668e3085024ebc3224a2ca.zmedico@gentoo> Subject: [gentoo-commits] proj/portage:master commit in: pym/_emerge/ X-VCS-Repository: proj/portage X-VCS-Files: pym/_emerge/BinpkgFetcher.py X-VCS-Directories: pym/_emerge/ X-VCS-Committer: zmedico X-VCS-Committer-Name: Zac Medico X-VCS-Revision: adf2e6dd57b5bcaa4a668e3085024ebc3224a2ca X-VCS-Branch: master Date: Sun, 22 Apr 2018 00:56:16 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: e114dd57-260e-4657-a694-7f6f49866eaf X-Archives-Hash: 6f40a808cb7e172cad0e9f07abd18ec5 commit: adf2e6dd57b5bcaa4a668e3085024ebc3224a2ca Author: Zac Medico gentoo org> AuthorDate: Sat Apr 21 19:18:08 2018 +0000 Commit: Zac Medico gentoo org> CommitDate: Sun Apr 22 00:50:57 2018 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=adf2e6dd BinpkgFetcher: use async lock (bug 614110) 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 Reviewed-by: Brian Dolbec gentoo.org> 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