diff options
author | Zac Medico <zmedico@gentoo.org> | 2018-06-05 18:52:59 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2018-06-05 19:09:55 -0700 |
commit | 937d0156aa060bdba9095313dedbb62e0a993aea (patch) | |
tree | 0add6dfd2083cb75726dd65286d0506b7e6e3ed7 /pym/_emerge | |
parent | emerge --depclean: 'str' has no attribute 'soname' (bug 657420) (diff) | |
download | portage-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.py | 10 | ||||
-rw-r--r-- | pym/_emerge/BinpkgFetcher.py | 8 | ||||
-rw-r--r-- | pym/_emerge/CompositeTask.py | 1 | ||||
-rw-r--r-- | pym/_emerge/EbuildBuild.py | 16 | ||||
-rw-r--r-- | pym/_emerge/EbuildFetcher.py | 12 | ||||
-rw-r--r-- | pym/_emerge/EbuildPhase.py | 4 | ||||
-rw-r--r-- | pym/_emerge/PackageUninstall.py | 8 |
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: |