summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2012-02-13 19:06:29 -0800
committerZac Medico <zmedico@gentoo.org>2012-02-13 19:06:29 -0800
commitfe3960b69c326bc779bdf5ec34d56630b3e188ae (patch)
tree4ab9a0dd4f0503003d3a630b3d8aa7c473db1d7e
parent07823ba56f63309da9547e02e96b043005932be0 (diff)
downloadportage-fe3960b69c326bc779bdf5ec34d56630b3e188ae.tar.gz
portage-fe3960b69c326bc779bdf5ec34d56630b3e188ae.tar.bz2
portage-fe3960b69c326bc779bdf5ec34d56630b3e188ae.zip
EventLoop._do_poll: tweak EINTR handling
Silently handle EINTR, which is normal when we have received a signal such as SIGINT. Also, raise StopIteration in order to break out of our current iteration and respond appropriately to the signal as soon as possible.
-rw-r--r--pym/portage/util/_eventloop/EventLoop.py27
1 files changed, 14 insertions, 13 deletions
diff --git a/pym/portage/util/_eventloop/EventLoop.py b/pym/portage/util/_eventloop/EventLoop.py
index 6c6a1b75d..37839ab2d 100644
--- a/pym/portage/util/_eventloop/EventLoop.py
+++ b/pym/portage/util/_eventloop/EventLoop.py
@@ -1,6 +1,7 @@
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import errno
import logging
import select
import time
@@ -100,24 +101,23 @@ class EventLoop(object):
raise StopIteration(
"timeout is None and there are no poll() event handlers")
- # The following error is known to occur with Linux kernel versions
- # less than 2.6.24:
- #
- # select.error: (4, 'Interrupted system call')
- #
- # This error has been observed after a SIGSTOP, followed by SIGCONT.
- # Treat it similar to EAGAIN if timeout is None, otherwise just return
- # without any events.
while True:
try:
self._poll_event_queue.extend(self._poll_obj.poll(timeout))
break
except select.error as e:
- writemsg_level("\n!!! select error: %s\n" % (e,),
- level=logging.ERROR, noiselevel=-1)
+ # Silently handle EINTR, which is normal when we have
+ # received a signal such as SIGINT.
+ if not (e.args and e.args[0] == errno.EINTR):
+ writemsg_level("\n!!! select error: %s\n" % (e,),
+ level=logging.ERROR, noiselevel=-1)
del e
- if timeout is not None:
- break
+
+ # This typically means that we've received a SIGINT, so
+ # raise StopIteration in order to break out of our current
+ # iteration and respond appropriately to the signal as soon
+ # as possible.
+ raise StopIteration("interrupted")
def _next_poll_event(self, timeout=None):
"""
@@ -170,7 +170,8 @@ class EventLoop(object):
except StopIteration:
# This could happen if there are no IO event handlers
# after _poll() calls _run_timeouts(), due to them
- # being removed by timeout or idle callbacks.
+ # being removed by timeout or idle callbacks. It can
+ # also be triggered by EINTR which is caused by signals.
events_handled += 1
try: