From: Zac Medico Date: Mon, 31 Dec 2012 03:16:11 +0000 (-0800) Subject: EventLoop.iteration: no IO blocking if possible X-Git-Tag: v2.2.0_alpha150~71 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=46fca763f7d08171d5c08c1c5fd1f40ce340ba56;p=portage.git 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. --- 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)