mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #7978: socketserver now restarts the select() call when EINTR is returned.
This avoids crashing the server loop when a signal is received. Patch by Jerzy Kozera.
This commit is contained in:
parent
317c8d257e
commit
b0a9c66a49
4 changed files with 52 additions and 2 deletions
|
@ -133,6 +133,7 @@ import socket
|
|||
import select
|
||||
import sys
|
||||
import os
|
||||
import errno
|
||||
try:
|
||||
import threading
|
||||
except ImportError:
|
||||
|
@ -147,6 +148,15 @@ if hasattr(socket, "AF_UNIX"):
|
|||
"ThreadingUnixStreamServer",
|
||||
"ThreadingUnixDatagramServer"])
|
||||
|
||||
def _eintr_retry(func, *args):
|
||||
"""restart a system call interrupted by EINTR"""
|
||||
while True:
|
||||
try:
|
||||
return func(*args)
|
||||
except OSError as e:
|
||||
if e.errno != errno.EINTR:
|
||||
raise
|
||||
|
||||
class BaseServer:
|
||||
|
||||
"""Base class for server classes.
|
||||
|
@ -222,7 +232,8 @@ class BaseServer:
|
|||
# connecting to the socket to wake this up instead of
|
||||
# polling. Polling reduces our responsiveness to a
|
||||
# shutdown request and wastes cpu at all other times.
|
||||
r, w, e = select.select([self], [], [], poll_interval)
|
||||
r, w, e = _eintr_retry(select.select, [self], [], [],
|
||||
poll_interval)
|
||||
if self in r:
|
||||
self._handle_request_noblock()
|
||||
finally:
|
||||
|
@ -262,7 +273,7 @@ class BaseServer:
|
|||
timeout = self.timeout
|
||||
elif self.timeout is not None:
|
||||
timeout = min(timeout, self.timeout)
|
||||
fd_sets = select.select([self], [], [], timeout)
|
||||
fd_sets = _eintr_retry(select.select, [self], [], [], timeout)
|
||||
if not fd_sets[0]:
|
||||
self.handle_timeout()
|
||||
return
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue