aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/_emerge/SequentialTaskQueue.py16
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()