aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2018-06-05 18:52:59 -0700
committerZac Medico <zmedico@gentoo.org>2018-06-05 19:09:55 -0700
commit937d0156aa060bdba9095313dedbb62e0a993aea (patch)
tree0add6dfd2083cb75726dd65286d0506b7e6e3ed7 /pym/_emerge
parentemerge --depclean: 'str' has no attribute 'soname' (bug 657420) (diff)
downloadportage-937d0156aa060bdba9095313dedbb62e0a993aea.tar.gz
portage-937d0156aa060bdba9095313dedbb62e0a993aea.tar.bz2
portage-937d0156aa060bdba9095313dedbb62e0a993aea.zip
CompositeTask: handle SIGINT/TERM cancelled futures (bug 657436)
In order to avoid raising an unwanted CancelledError, make CompositeTask check for cancelled futures before attempting to call future.result(). The intention is only to handle failures triggered by SIGINT/TERM, since other types of expected failures should always be handled by catching the exception raised from future.result(). Bug: https://bugs.gentoo.org/657436
Diffstat (limited to 'pym/_emerge')
-rw-r--r--pym/_emerge/Binpkg.py10
-rw-r--r--pym/_emerge/BinpkgFetcher.py8
-rw-r--r--pym/_emerge/CompositeTask.py1
-rw-r--r--pym/_emerge/EbuildBuild.py16
-rw-r--r--pym/_emerge/EbuildFetcher.py12
-rw-r--r--pym/_emerge/EbuildPhase.py4
-rw-r--r--pym/_emerge/PackageUninstall.py8
7 files changed, 58 insertions, 1 deletions
diff --git a/pym/_emerge/Binpkg.py b/pym/_emerge/Binpkg.py
index 2b67816e8..7791ec236 100644
--- a/pym/_emerge/Binpkg.py
+++ b/pym/_emerge/Binpkg.py
@@ -122,6 +122,10 @@ class Binpkg(CompositeTask):
def _start_fetcher(self, lock_task=None):
if lock_task is not None:
self._assert_current(lock_task)
+ if lock_task.cancelled:
+ self._default_final_exit(lock_task)
+ return
+
lock_task.future.result()
# Initialize PORTAGE_LOG_FILE (clean_log won't work without it).
portage.prepare_build_dirs(self.settings["ROOT"], self.settings, 1)
@@ -411,8 +415,12 @@ class Binpkg(CompositeTask):
def _unlock_builddir_exit(self, unlock_task, returncode=None):
self._assert_current(unlock_task)
+ if unlock_task.cancelled and returncode is not None:
+ self._default_final_exit(unlock_task)
+ return
+
# Normally, async_unlock should not raise an exception here.
- unlock_task.future.result()
+ unlock_task.future.cancelled() or unlock_task.future.result()
if returncode is not None:
self.returncode = returncode
self._async_wait()
diff --git a/pym/_emerge/BinpkgFetcher.py b/pym/_emerge/BinpkgFetcher.py
index 8e651a1c7..36d027de3 100644
--- a/pym/_emerge/BinpkgFetcher.py
+++ b/pym/_emerge/BinpkgFetcher.py
@@ -48,6 +48,10 @@ class BinpkgFetcher(CompositeTask):
def _start_locked(self, fetcher, lock_task):
self._assert_current(lock_task)
+ if lock_task.cancelled:
+ self._default_final_exit(lock_task)
+ return
+
lock_task.future.result()
self._start_task(fetcher, self._fetcher_exit)
@@ -65,6 +69,10 @@ class BinpkgFetcher(CompositeTask):
def _fetcher_exit_unlocked(self, fetcher, unlock_task=None):
if unlock_task is not None:
self._assert_current(unlock_task)
+ if unlock_task.cancelled:
+ self._default_final_exit(unlock_task)
+ return
+
unlock_task.future.result()
self._current_task = None
diff --git a/pym/_emerge/CompositeTask.py b/pym/_emerge/CompositeTask.py
index 4662f0cf5..1edec4a17 100644
--- a/pym/_emerge/CompositeTask.py
+++ b/pym/_emerge/CompositeTask.py
@@ -69,6 +69,7 @@ class CompositeTask(AsynchronousTask):
self._assert_current(task)
if task.returncode != os.EX_OK:
self.returncode = task.returncode
+ self.cancelled = task.cancelled
self._current_task = None
return task.returncode
diff --git a/pym/_emerge/EbuildBuild.py b/pym/_emerge/EbuildBuild.py
index d9f7f6da7..8d264dd1c 100644
--- a/pym/_emerge/EbuildBuild.py
+++ b/pym/_emerge/EbuildBuild.py
@@ -54,6 +54,10 @@ class EbuildBuild(CompositeTask):
def _start_with_metadata(self, aux_get_task):
self._assert_current(aux_get_task)
+ if aux_get_task.cancelled:
+ self._default_final_exit(aux_get_task)
+ return
+
pkg = self.pkg
settings = self.settings
root_config = pkg.root_config
@@ -178,6 +182,10 @@ class EbuildBuild(CompositeTask):
def _start_pre_clean(self, lock_task):
self._assert_current(lock_task)
+ if lock_task.cancelled:
+ self._default_final_exit(lock_task)
+ return
+
lock_task.future.result()
# Cleaning needs to happen before fetch, since the build dir
# is used for log handling.
@@ -235,6 +243,10 @@ class EbuildBuild(CompositeTask):
def _start_fetch(self, fetcher, already_fetched_task):
self._assert_current(already_fetched_task)
+ if already_fetched_task.cancelled:
+ self._default_final_exit(already_fetched_task)
+ return
+
try:
already_fetched = already_fetched_task.future.result()
except portage.exception.InvalidDependString as e:
@@ -342,6 +354,10 @@ class EbuildBuild(CompositeTask):
def _unlock_builddir_exit(self, unlock_task, returncode=None):
self._assert_current(unlock_task)
+ if unlock_task.cancelled:
+ self._default_final_exit(unlock_task)
+ return
+
# Normally, async_unlock should not raise an exception here.
unlock_task.future.result()
if returncode is not None:
diff --git a/pym/_emerge/EbuildFetcher.py b/pym/_emerge/EbuildFetcher.py
index 3b30ebb59..ad5109c28 100644
--- a/pym/_emerge/EbuildFetcher.py
+++ b/pym/_emerge/EbuildFetcher.py
@@ -47,6 +47,10 @@ class EbuildFetcher(CompositeTask):
def _start_fetch(self, uri_map_task):
self._assert_current(uri_map_task)
+ if uri_map_task.cancelled:
+ self._default_final_exit(uri_map_task)
+ return
+
try:
uri_map = uri_map_task.future.result()
except portage.exception.InvalidDependString as e:
@@ -71,6 +75,10 @@ class EbuildFetcher(CompositeTask):
def _start_with_metadata(self, aux_get_task):
self._assert_current(aux_get_task)
+ if aux_get_task.cancelled:
+ self._default_final_exit(aux_get_task)
+ return
+
self._fetcher_proc.src_uri, = aux_get_task.future.result()
self._start_task(self._fetcher_proc, self._default_final_exit)
@@ -85,6 +93,10 @@ class _EbuildFetcherProcess(ForkProcess):
result = self.scheduler.create_future()
def uri_map_done(uri_map_future):
+ if uri_map_future.cancelled():
+ result.cancel()
+ return
+
if uri_map_future.exception() is not None or result.cancelled():
if not result.cancelled():
result.set_exception(uri_map_future.exception())
diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
index d057dc45e..4104cefa7 100644
--- a/pym/_emerge/EbuildPhase.py
+++ b/pym/_emerge/EbuildPhase.py
@@ -211,6 +211,10 @@ class EbuildPhase(CompositeTask):
def _ebuild_exit_unlocked(self, ebuild_process, unlock_task=None):
if unlock_task is not None:
self._assert_current(unlock_task)
+ if unlock_task.cancelled:
+ self._default_final_exit(unlock_task)
+ return
+
# Normally, async_unlock should not raise an exception here.
unlock_task.future.result()
diff --git a/pym/_emerge/PackageUninstall.py b/pym/_emerge/PackageUninstall.py
index 3fe1fb0a6..cb3413056 100644
--- a/pym/_emerge/PackageUninstall.py
+++ b/pym/_emerge/PackageUninstall.py
@@ -61,6 +61,10 @@ class PackageUninstall(CompositeTask):
def _start_unmerge(self, lock_task):
self._assert_current(lock_task)
+ if lock_task.cancelled:
+ self._default_final_exit(lock_task)
+ return
+
lock_task.future.result()
portage.prepare_build_dirs(
settings=self.settings, cleanup=True)
@@ -112,6 +116,10 @@ class PackageUninstall(CompositeTask):
def _unlock_builddir_exit(self, unlock_task, returncode=None):
self._assert_current(unlock_task)
+ if unlock_task.cancelled:
+ self._default_final_exit(unlock_task)
+ return
+
# Normally, async_unlock should not raise an exception here.
unlock_task.future.result()
if returncode is not None: