aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2018-04-21 10:32:49 -0700
committerZac Medico <zmedico@gentoo.org>2018-04-21 11:41:58 -0700
commit87a21a06c8829be6ded41a4c06dcfc19f8ffefc2 (patch)
treef96fbb3bae9003f7b31551b86b5fb9f2f504e0de
parentEbuildBuildDir: remove synchronous unlock method (bug 614108) (diff)
downloadportage-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.py57
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