diff options
author | Zac Medico <zmedico@gentoo.org> | 2018-04-21 10:32:49 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2018-04-21 11:41:58 -0700 |
commit | 87a21a06c8829be6ded41a4c06dcfc19f8ffefc2 (patch) | |
tree | f96fbb3bae9003f7b31551b86b5fb9f2f504e0de | |
parent | EbuildBuildDir: remove synchronous unlock method (bug 614108) (diff) | |
download | portage-87a21a06c8829be6ded41a4c06dcfc19f8ffefc2.tar.gz portage-87a21a06c8829be6ded41a4c06dcfc19f8ffefc2.tar.bz2 portage-87a21a06c8829be6ded41a4c06dcfc19f8ffefc2.zip |
BinpkgFetcher: use async_unlock (bug 614108)
Convert BinpkgFetcher to a CompositeTask in order to handle asynchronous
unlock, and move remaining BinpkgFetcher code to a _BinpkgFetcherProcess
class that still inherits SpawnProcess.
Bug: https://bugs.gentoo.org/614108
-rw-r--r-- | pym/_emerge/BinpkgFetcher.py | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/pym/_emerge/BinpkgFetcher.py b/pym/_emerge/BinpkgFetcher.py index c8fd64487..5ca7a45cf 100644 --- a/pym/_emerge/BinpkgFetcher.py +++ b/pym/_emerge/BinpkgFetcher.py @@ -1,7 +1,10 @@ # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +import functools + from _emerge.AsynchronousLock import AsynchronousLock +from _emerge.CompositeTask import CompositeTask from _emerge.SpawnProcess import SpawnProcess try: from urllib.parse import urlparse as urllib_parse_urlparse @@ -11,24 +14,56 @@ import stat import sys import portage from portage import os +from portage.util._async.AsyncTaskFuture import AsyncTaskFuture from portage.util._pty import _create_pty_or_pipe if sys.hexversion >= 0x3000000: long = int -class BinpkgFetcher(SpawnProcess): - __slots__ = ("pkg", "pretend", - "locked", "pkg_path", "_lock_obj") +class BinpkgFetcher(CompositeTask): + + __slots__ = ("pkg", "pretend", "logfile", "pkg_path") def __init__(self, **kwargs): - SpawnProcess.__init__(self, **kwargs) + CompositeTask.__init__(self, **kwargs) pkg = self.pkg self.pkg_path = pkg.root_config.trees["bintree"].getname( 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) + + def _fetcher_exit(self, fetcher): + self._assert_current(fetcher) + if not self.pretend and fetcher.returncode == os.EX_OK: + fetcher.sync_timestamp() + if fetcher.locked: + self._start_task( + AsyncTaskFuture(future=fetcher.async_unlock()), + functools.partial(self._fetcher_exit_unlocked, fetcher)) + else: + self._fetcher_exit_unlocked(fetcher) + + def _fetcher_exit_unlocked(self, fetcher, unlock_task=None): + if unlock_task is not None: + self._assert_current(unlock_task) + unlock_task.future.result() + + self._current_task = None + self.returncode = fetcher.returncode + self._async_wait() + +class _BinpkgFetcherProcess(SpawnProcess): + + __slots__ = ("pkg", "pretend", "locked", "pkg_path", "_lock_obj") + + def _start(self): pkg = self.pkg pretend = self.pretend bintree = pkg.root_config.trees["bintree"] @@ -123,9 +158,7 @@ class BinpkgFetcher(SpawnProcess): _create_pty_or_pipe(copy_term_size=stdout_pipe) return (master_fd, slave_fd) - def _set_returncode(self, wait_retval): - SpawnProcess._set_returncode(self, wait_retval) - if not self.pretend and self.returncode == os.EX_OK: + def sync_timestamp(self): # If possible, update the mtime to match the remote package if # the fetcher didn't already do it automatically. bintree = self.pkg.root_config.trees["bintree"] @@ -151,9 +184,6 @@ class BinpkgFetcher(SpawnProcess): except OSError: pass - if self.locked: - self.unlock() - def lock(self): """ This raises an AlreadyLocked exception if lock() is called @@ -179,10 +209,11 @@ class BinpkgFetcher(SpawnProcess): class AlreadyLocked(portage.exception.PortageException): pass - def unlock(self): + def async_unlock(self): if self._lock_obj is None: - return - self._lock_obj.unlock() + raise AssertionError('already unlocked') + result = self._lock_obj.async_unlock() self._lock_obj = None self.locked = False + return result |