From 43ba1c76dc1587760b2e8325dd6aeba8fef9c149 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Thu, 15 Feb 2018 16:11:11 +0545 Subject: [PATCH] core: wrap selects in EINTR handlers This isn't nearly enough, but it catches the most common victim of EINTR. --- mitogen/core.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/mitogen/core.py b/mitogen/core.py index 497e59a3..029d7106 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -158,6 +158,15 @@ def takes_router(func): return func +def restart(func, *args): + while True: + try: + return func(*args) + except (select.error, OSError), e: + if e[0] != errno.EINTR: + raise + + def set_cloexec(fd): flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) @@ -815,7 +824,7 @@ class Latch(object): finally: self.lock.release() - rfds, _, _ = select.select([_tls.rsock], [], [], timeout) + rfds, _, _ = restart(select.select, [_tls.rsock], [], [], timeout) assert len(rfds) or timeout is not None self.lock.acquire() @@ -1142,8 +1151,12 @@ class Broker(object): #IOLOG.debug('readers = %r', self._readers) #IOLOG.debug('writers = %r', self._writers) - rsides, wsides, _ = select.select(self._readers, self._writers, - (), timeout) + rsides, wsides, _ = restart(select.select, + self._readers, + self._writers, + (), timeout + ) + for side in rsides: _vv and IOLOG.debug('%r: POLLIN for %r', self, side) self._call(side.stream, side.stream.on_receive)