self.returncode = os.EX_OK
self._error_count = 0
self._running_tasks = set()
+ self._remaining_tasks = True
def _terminate_tasks(self):
while self._running_tasks:
from portage.cache.cache_errors import CacheError
dead_nodes = {}
- while self._schedule():
- self.sched_iface.run()
+ self._schedule()
+ while self._remaining_tasks and not self._terminated_tasks:
+ self.sched_iface.iteration()
while self._jobs:
- self.sched_iface.run()
+ self.sched_iface.iteration()
if self._terminated_tasks:
self.returncode = 1
try:
metadata_process = next(self._process_iter)
except StopIteration:
+ self._remaining_tasks = False
return False
self._jobs += 1
def _next_poll_event(self, timeout=None):
"""
- Since the _schedule_wait() loop is called by event
- handlers from _poll_loop(), maintain a central event
- queue for both of them to share events from a single
+ Since iteration() can be called recursively, maintain
+ a central event queue to share events from a single
poll() call. In order to avoid endless blocking, this
raises StopIteration if timeout is None and there are
no file descriptors to poll.
raise StopIteration()
return self._poll_event_queue.pop()
- def _poll_loop(self):
-
- event_handlers = self._poll_event_handlers
- event_handled = False
-
- try:
- while event_handlers:
- f, event = self._next_poll_event()
- x = event_handlers[f]
- if not x.callback(f, event, *x.args):
- self.source_remove(x.source_id)
- event_handled = True
- except StopIteration:
- event_handled = True
-
- if not event_handled:
- raise AssertionError("tight loop")
-
def iteration(self, *args):
"""
Like glib.MainContext.iteration(), runs a single iteration.
iteration=self._event_loop.iteration,
output=self._task_output,
register=self._event_loop.io_add_watch,
- run=self._event_loop._poll_loop,
source_remove=self._event_loop.source_remove,
timeout_add=self._event_loop.timeout_add,
unregister=self._event_loop.source_remove)
io_add_watch=self._event_loop.io_add_watch,
iteration=self._event_loop.iteration,
register=self._event_loop.io_add_watch,
- schedule=self._event_loop._poll_loop,
scheduleSetup=self._schedule_setup,
scheduleUnpack=self._schedule_unpack,
source_remove=self._event_loop.source_remove,
if self._opts_no_background.intersection(self.myopts):
self._set_max_jobs(1)
- while self._schedule():
- self.sched_iface.run()
+ self._schedule()
+ while self._keep_scheduling():
+ self.sched_iface.iteration()
- while True:
- self._schedule()
- if not self._is_work_scheduled():
- break
- self.sched_iface.run()
+ while self._is_work_scheduled():
+ self.sched_iface.iteration()
def _keep_scheduling(self):
return bool(not self._terminated_tasks and self._pkg_queue and \