class Py25TCPServer(SocketServer.ThreadingTCPServer):
def __init__(self, address_tuple, handler):
SocketServer.ThreadingTCPServer.__init__(self, address_tuple, handler)
self.__is_shut_down = threading.Event()
self.__shutdown_request = False
def serve_forever(self, poll_interval=0.5):
"""Handle one request at a time until shutdown.
Polls for shutdown every poll_interval seconds. Ignores
self.timeout. If you need to do periodic tasks, do them in
another thread.
"""
self.__is_shut_down.clear()
try:
while not self.__shutdown_request:
r, w, e = select.select([self], [], [], poll_interval)
if self in r:
self._handle_request_noblock()
finally:
self.__shutdown_request = False
self.__is_shut_down.set()
def shutdown(self):
"""Stops the serve_forever loop.
Blocks until the loop has finished. This must be called while
serve_forever() is running in another thread, or it will
deadlock.
"""
self.__shutdown_request = True
self.__is_shut_down.wait()
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().
"""
try:
request, client_address = self.get_request()
except socket.error:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address)
except:
self.handle_error(request, client_address)
self.close_request(request)
To make our program work in both Python 2.5 and 2.6+, we can do something like this.
import sys
python_version = sys.version_info
server = None
if python_version[1] < 6:
server = Py25TCPServer((self.host, self.port), MyHandler)
else:
server = SocketServer.TCPServer((self.host, self.port), MyHandler)
server.server_forever()