# HG changeset patch # User Kristján Valur Jónsson # Date 1331766787 25200 # Node ID aac602bd8ec39e39c4fd74257bef6cabc574dbe0 # Parent 8943649201c57fd357560d5c6aca1d01fc8fa567 different approach, allowing subclassng diff --git a/Lib/socketserver.py b/Lib/socketserver.py --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -223,10 +223,7 @@ # 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) - if self in r: - self._handle_request_noblock() - + self._handle_request_timeout(poll_interval) self.service_actions() finally: self.__shutdown_request = False @@ -266,30 +263,21 @@ 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 = select.select([self], [], [], timeout) - if not fd_sets[0]: + if self._handle_request_timeout(self.timeout): self.handle_timeout() - return - self._handle_request_noblock() - def _handle_request_noblock(self): - """Handle one request, without blocking. - - I assume that select.select has returned that the socket is - readable before this function was called, so there should be - no risk of blocking in get_request(). + def _handle_request_timeout(self, timeout): + """Handle one request, timing out while accepting request. + + returns True if a request wasn't received during the timeout period. """ try: - request, client_address = self.get_request() + request = self._get_request_timeout(timeout) except socket.error: return + if request is None: + return True + request, client_address = request if self.verify_request(request, client_address): try: self.process_request(request, client_address) @@ -297,6 +285,22 @@ self.handle_error(request, client_address) self.shutdown_request(request) + def _get_request_timeout(self, timeout): + """Get one request, with timeout.""" + # Support people who used socket.settimeout() to escape + # handle_request before self.timeout was available. + sock_timeout = self.socket.gettimeout() + if timeout is None: + timeout = sock_timeout + elif sock_timeout is not None: + timeout = min(timeout, sock_timeout) + #use select so that we don't have to mess with the attributes + #of sockets or catch timeout exceptions. + fd_sets = select.select([self], [], [], timeout) + if not fd_sets[0]: + return None + return self.get_request() + def handle_timeout(self): """Called if no new request arrives within self.timeout.