Comment #7 on issue 571737 by
cychi...@chromium.org: [chameleon perbuild]
contextlib is not the cause.
The root cause is in python2.7/SocketServer.py
In 2.7.10, handle_request of BaseServer wraps select.select with a retry
when error is EINTR.
So, when SIGINT raise the exception in select, it retries, and then it
blocks forever (because timeout is None) until the next call from client.
Using a different timeout value can solve the wait, but it delays the time
server should shutdown by that timeout amount.
I think we should let server receives a different signal so it does not get
retried.
Not sure how to achieve that.
def handle_request(self):
"""Handle one request, possibly blocking.
Respects self.timeout.
"""
# Support people who used socket.settimeout() to escape
# handle_request before self.timeout was available.
timeout = self.socket.gettimeout()
if timeout is None:
timeout = self.timeout
elif self.timeout is not None:
timeout = min(timeout, self.timeout)
fd_sets = _eintr_retry(select.select, [self], [], [], timeout)
if not fd_sets[0]:
self.handle_timeout()
return
self._handle_request_noblock()
def _eintr_retry(func, *args):
"""restart a system call interrupted by EINTR"""
while True:
try:
return func(*args)
except (OSError, select.error) as e:
if e.args[0] != errno.EINTR:
raise