commit:     459b3535baa416888b546cd1635ae28324259a70
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Wed Mar  4 08:17:28 2020 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed Mar  4 09:53:27 2020 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=459b3535

SequentialTaskQueue: update bool(self) sooner (bug 711322)

Use addExitListener to add a _task_exit callback that will be invoked
as soon as the task exits (before the future's done callback is called).
This is required in order for bool(self) to have an updated value for
Scheduler._schedule to base assumptions upon. Delayed updates to
bool(self) is what caused Scheduler to hang as in bug 711322.

This reverts changes in SequentialTaskQueue task queue exit listener
behavior from commit c7e52d046621, so that only the changes necessary
to support async_start remain.

Fixes: c7e52d046621 ("EbuildPhase: add _async_start coroutine")
Bug: https://bugs.gentoo.org/711322
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/_emerge/SequentialTaskQueue.py | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/lib/_emerge/SequentialTaskQueue.py 
b/lib/_emerge/SequentialTaskQueue.py
index a4555275f..318bd6c55 100644
--- a/lib/_emerge/SequentialTaskQueue.py
+++ b/lib/_emerge/SequentialTaskQueue.py
@@ -2,7 +2,6 @@
 # Distributed under the terms of the GNU General Public License v2
 
 from collections import deque
-import functools
 import sys
 
 from portage.util.futures import asyncio
@@ -45,7 +44,14 @@ class SequentialTaskQueue(SlotObject):
                                if not cancelled:
                                        self.running_tasks.add(task)
                                        future = 
asyncio.ensure_future(self._task_coroutine(task), loop=task.scheduler)
-                                       
future.add_done_callback(functools.partial(self._task_exit, task))
+                                       future.add_done_callback(lambda future: 
future.cancelled() or future.result())
+                                       # This callback will be invoked as soon 
as the task
+                                       # exits (before the future's done 
callback is called),
+                                       # and this is required in order for 
bool(self) to have
+                                       # an updated value for 
Scheduler._schedule to base
+                                       # assumptions upon. Delayed updates to 
bool(self) is
+                                       # what caused Scheduler to hang as in 
bug 709746.
+                                       task.addExitListener(self._task_exit)
                finally:
                        self._scheduling = False
 
@@ -54,17 +60,13 @@ class SequentialTaskQueue(SlotObject):
                yield task.async_start()
                yield task.async_wait()
 
-       def _task_exit(self, task, future):
+       def _task_exit(self, task):
                """
                Since we can always rely on exit listeners being called, the 
set of
                running tasks is always pruned automatically and there is never 
any need
                to actively prune it.
                """
                self.running_tasks.remove(task)
-               try:
-                       future.result()
-               except asyncio.CancelledError:
-                       self.clear()
                if self._task_queue:
                        self.schedule()
 

Reply via email to