From 46fca763f7d08171d5c08c1c5fd1f40ce340ba56 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Sun, 30 Dec 2012 19:16:11 -0800 Subject: 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. --- pym/portage/util/_eventloop/EventLoop.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'pym') 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) -- cgit v1.2.3-1-g7c22