diff options
-rw-r--r-- | lib/_emerge/SequentialTaskQueue.py | 16 |
1 files 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() |