diff options
author | Zac Medico <zmedico@gentoo.org> | 2008-07-15 02:11:39 +0000 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2008-07-15 02:11:39 +0000 |
commit | 9d7e398c9ff275d4baced57f29540cef084e66a1 (patch) | |
tree | 001f8025fb77c3fb0392aafa118cb0d1d46ec194 | |
parent | 77497106fbcb7626ecdf7ef4882aef7690f6f6a9 (diff) | |
download | portage-9d7e398c9ff275d4baced57f29540cef084e66a1.tar.gz portage-9d7e398c9ff275d4baced57f29540cef084e66a1.tar.bz2 portage-9d7e398c9ff275d4baced57f29540cef084e66a1.zip |
Add a PollScheduler._next_poll_event() method to maintain a central event
queue between _poll_loop() and _schedule_wait(). This solves an intermittent
KeyError from _poll_loop() which occured when an event handler called
_schedule_wait() which unregistered an event handler for an event that
_poll_loop() had already recieved but hadn't processed yet.
svn path=/main/trunk/; revision=11051
-rw-r--r-- | pym/_emerge/__init__.py | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index a2c7b19e7..ef16f477c 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -8085,6 +8085,7 @@ class PollScheduler(object): self._max_jobs = 1 self._max_load = None self._jobs = 0 + self._poll_event_queue = [] self._poll_event_handlers = {} self._poll_event_handler_ids = {} # Increment id for each new handler. @@ -8132,19 +8133,29 @@ class PollScheduler(object): return True + def _next_poll_event(self): + """ + 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 + poll() call. + """ + if not self._poll_event_queue: + self._poll_event_queue.extend(self._poll.poll()) + return self._poll_event_queue.pop() + def _poll_loop(self): event_handlers = self._poll_event_handlers - poll = self._poll.poll - state_change = 0 + event_handled = False while event_handlers: - for f, event in poll(): - handler, reg_id = event_handlers[f] - if not handler(f, event): - state_change += 1 + f, event = self._next_poll_event() + handler, reg_id = event_handlers[f] + handler(f, event) + event_handled = True - if not state_change: + if not event_handled: raise AssertionError("tight loop") def _register(self, f, eventmask, handler): @@ -8177,15 +8188,18 @@ class PollScheduler(object): """ event_handlers = self._poll_event_handlers handler_ids = self._poll_event_handler_ids - poll = self._poll.poll + event_handled = False if isinstance(wait_ids, int): wait_ids = frozenset([wait_ids]) while wait_ids.intersection(handler_ids): - for f, event in poll(): - handler, reg_id = event_handlers[f] - handler(f, event) + f, event = self._next_poll_event() + handler, reg_id = event_handlers[f] + handler(f, event) + event_handled = True + + return event_handled class QueueScheduler(PollScheduler): |