summaryrefslogtreecommitdiffstats
path: root/Lib/SocketServer.py
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-04-08 22:47:24 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-04-08 22:47:24 (GMT)
commitfa1d84107a22de80ee35a38e0c68ad988ebc66db (patch)
tree123903f9c68bd40f26a1cb08d896a770b7a61580 /Lib/SocketServer.py
parent088a874c7ff4e90d5b6efc16d37a53a57f368fea (diff)
downloadcpython-fa1d84107a22de80ee35a38e0c68ad988ebc66db.zip
cpython-fa1d84107a22de80ee35a38e0c68ad988ebc66db.tar.gz
cpython-fa1d84107a22de80ee35a38e0c68ad988ebc66db.tar.bz2
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.
Diffstat (limited to 'Lib/SocketServer.py')
-rw-r--r--Lib/SocketServer.py15
1 files changed, 13 insertions, 2 deletions
diff --git a/Lib/SocketServer.py b/Lib/SocketServer.py
index 2ff3888..a44e137 100644
--- a/Lib/SocketServer.py
+++ b/Lib/SocketServer.py
@@ -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