diff options
author | Ezio Melotti <ezio.melotti@gmail.com> | 2011-05-07 18:15:34 +0300 |
---|---|---|
committer | Ezio Melotti <ezio.melotti@gmail.com> | 2011-05-07 18:15:34 +0300 |
commit | 17736f19671fe9e3a1d0965abf6e0d022c3c7b7f (patch) | |
tree | 53cdecfea95a81b6ef7326980cf5e81328b32b06 /Lib/socketserver.py | |
parent | 2c515bbdb8fc7fd4cc3d01151d0b8dd8d5adccfd (diff) | |
parent | 496564fe5be17057671a373f4a1126352823ece5 (diff) | |
download | cpython-17736f19671fe9e3a1d0965abf6e0d022c3c7b7f.tar.gz |
#12017: merge with 3.1.
Diffstat (limited to 'Lib/socketserver.py')
-rw-r--r-- | Lib/socketserver.py | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 3d32c3ea19..089b3bac11 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -168,6 +168,7 @@ class BaseServer: - verify_request(request, client_address) - server_close() - process_request(request, client_address) + - shutdown_request(request) - close_request(request) - handle_error() @@ -283,7 +284,7 @@ class BaseServer: self.process_request(request, client_address) except: self.handle_error(request, client_address) - self.close_request(request) + self.shutdown_request(request) def handle_timeout(self): """Called if no new request arrives within self.timeout. @@ -307,7 +308,7 @@ class BaseServer: """ self.finish_request(request, client_address) - self.close_request(request) + self.shutdown_request(request) def server_close(self): """Called to clean-up the server. @@ -321,6 +322,10 @@ class BaseServer: """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass(request, client_address, self) + def shutdown_request(self, request): + """Called to shutdown and close an individual request.""" + self.close_request(request) + def close_request(self, request): """Called to clean up an individual request.""" pass @@ -361,6 +366,7 @@ class TCPServer(BaseServer): - handle_timeout() - verify_request(request, client_address) - process_request(request, client_address) + - shutdown_request(request) - close_request(request) - handle_error() @@ -445,6 +451,16 @@ class TCPServer(BaseServer): """ return self.socket.accept() + def shutdown_request(self, request): + """Called to shutdown and close an individual request.""" + try: + #explicitly shutdown. socket.close() merely releases + #the socket and waits for GC to perform the actual close. + request.shutdown(socket.SHUT_WR) + except socket.error: + pass #some platforms may raise ENOTCONN here + self.close_request(request) + def close_request(self, request): """Called to clean up an individual request.""" request.close() @@ -468,6 +484,10 @@ class UDPServer(TCPServer): # No need to call listen() for UDP. pass + def shutdown_request(self, request): + # No need to shutdown anything. + self.close_request(request) + def close_request(self, request): # No need to close anything. pass @@ -535,10 +555,12 @@ class ForkingMixIn: # This must never return, hence os._exit()! try: self.finish_request(request, client_address) + self.shutdown_request(request) os._exit(0) except: try: self.handle_error(request, client_address) + self.shutdown_request(request) finally: os._exit(1) @@ -558,10 +580,10 @@ class ThreadingMixIn: """ try: self.finish_request(request, client_address) - self.close_request(request) + self.shutdown_request(request) except: self.handle_error(request, client_address) - self.close_request(request) + self.shutdown_request(request) def process_request(self, request, client_address): """Start a new thread to process the request.""" @@ -613,8 +635,10 @@ class BaseRequestHandler: self.client_address = client_address self.server = server self.setup() - self.handle() - self.finish() + try: + self.handle() + finally: + self.finish() def setup(self): pass @@ -648,8 +672,20 @@ class StreamRequestHandler(BaseRequestHandler): rbufsize = -1 wbufsize = 0 + # A timeout to apply to the request socket, if not None. + timeout = None + + # Disable nagle algorithm for this socket, if True. + # Use only when wbufsize != 0, to avoid small packets. + disable_nagle_algorithm = False + def setup(self): self.connection = self.request + if self.timeout is not None: + self.connection.settimeout(self.timeout) + if self.disable_nagle_algorithm: + self.connection.setsockopt(socket.IPPROTO_TCP, + socket.TCP_NODELAY, True) self.rfile = self.connection.makefile('rb', self.rbufsize) self.wfile = self.connection.makefile('wb', self.wbufsize) |