commit:     8cc84cea654238676f7edc04b9c75c001535c0b4
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat Mar  7 21:52:53 2020 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sat Mar  7 22:01:22 2020 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=8cc84cea

SequentialTaskQueue: cancel unstarted tasks when appropriate (bug 711322)

When the clear method is called, cancel any tasks which have not
started yet, in order to ensure that their start/exit listeners are
called. This fixes a case where emerge would hang after SIGINT.

Also fix the CompositeTask _cancel method to react appropriately to
the cancel event when the task has not started yet.

Bug: https://bugs.gentoo.org/711322
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/_emerge/CompositeTask.py       | 4 ++++
 lib/_emerge/SequentialTaskQueue.py | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/lib/_emerge/CompositeTask.py b/lib/_emerge/CompositeTask.py
index 1d199d19b..2ad1d783d 100644
--- a/lib/_emerge/CompositeTask.py
+++ b/lib/_emerge/CompositeTask.py
@@ -20,6 +20,10 @@ class CompositeTask(AsynchronousTask):
                                self._async_wait()
                        else:
                                self._current_task.cancel()
+               elif self.returncode is None:
+                       # Assume that the task has not started yet.
+                       self._was_cancelled()
+                       self._async_wait()
 
        def _poll(self):
                """

diff --git a/lib/_emerge/SequentialTaskQueue.py 
b/lib/_emerge/SequentialTaskQueue.py
index 318bd6c55..38ebb98d8 100644
--- a/lib/_emerge/SequentialTaskQueue.py
+++ b/lib/_emerge/SequentialTaskQueue.py
@@ -74,7 +74,10 @@ class SequentialTaskQueue(SlotObject):
                """
                Clear the task queue and asynchronously terminate any running 
tasks.
                """
+               for task in self._task_queue:
+                       task.cancel()
                self._task_queue.clear()
+
                for task in list(self.running_tasks):
                        task.cancel()
 

Reply via email to