diff options
author | Zac Medico <zmedico@gentoo.org> | 2012-12-30 19:16:11 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2012-12-30 19:16:11 -0800 |
commit | 46fca763f7d08171d5c08c1c5fd1f40ce340ba56 (patch) | |
tree | 8106bd838ef715e48aaa2e105f78030aad36aa6b | |
parent | a3100be184ba1cac2f672f0a1cadcf01690c6d3f (diff) | |
download | portage-46fca763f7d08171d5c08c1c5fd1f40ce340ba56.tar.gz portage-46fca763f7d08171d5c08c1c5fd1f40ce340ba56.tar.bz2 portage-46fca763f7d08171d5c08c1c5fd1f40ce340ba56.zip |
EventLoop.iteration: no IO blocking if possible
Avoid blocking for IO if there are any timeout or idle callback events
available to process. This will prevent starvation of the idle
callbacks, which are much more common since commit
a3100be184ba1cac2f672f0a1cadcf01690c6d3f. We don't want these idle
callbacks to be delayed by long periods of IO blocking.
-rw-r--r-- | pym/portage/util/_eventloop/EventLoop.py | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py index b77e8191b..d2d49636d 100644 --- a/pym/portage/util/_eventloop/EventLoop.py +++ b/pym/portage/util/_eventloop/EventLoop.py @@ -182,11 +182,13 @@ class EventLoop(object): event_queue = self._poll_event_queue event_handlers = self._poll_event_handlers events_handled = 0 + timeouts_checked = False if not event_handlers: with self._thread_condition: if self._run_timeouts(): events_handled += 1 + timeouts_checked = True if not event_handlers and not events_handled and may_block: # Block so that we don't waste cpu time by looping too # quickly. This makes EventLoop useful for code that needs @@ -205,6 +207,7 @@ class EventLoop(object): self._thread_condition.wait(wait_timeout) if self._run_timeouts(): events_handled += 1 + timeouts_checked = True # If any timeouts have executed, then return immediately, # in order to minimize latency in termination of iteration @@ -216,6 +219,17 @@ class EventLoop(object): if may_block: timeout = self._get_poll_timeout() + + # Avoid blocking for IO if there are any timeout + # or idle callbacks available to process. + if timeout != 0 and not timeouts_checked: + if self._run_timeouts(): + events_handled += 1 + timeouts_checked = True + if events_handled: + # Minimize latency for loops controlled + # by timeout or idle callback events. + timeout = 0 else: timeout = 0 @@ -235,10 +249,10 @@ class EventLoop(object): if not x.callback(f, event, *x.args): self.source_remove(x.source_id) - # Run timeouts last, in order to minimize latency in - # termination of iteration loops that they may control. - if self._run_timeouts(): - events_handled += 1 + if not timeouts_checked: + if self._run_timeouts(): + events_handled += 1 + timeouts_checked = True return bool(events_handled) |