summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-15 02:11:39 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-15 02:11:39 +0000
commit9d7e398c9ff275d4baced57f29540cef084e66a1 (patch)
tree001f8025fb77c3fb0392aafa118cb0d1d46ec194 /pym
parent77497106fbcb7626ecdf7ef4882aef7690f6f6a9 (diff)
downloadportage-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
Diffstat (limited to 'pym')
-rw-r--r--pym/_emerge/__init__.py36
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):