Problem in multithreading Socketserver explained (should apply to *nix, too)

Gerson Kurz gerson.kurz at t-online.de
Wed Aug 29 02:02:31 EDT 2001


The BaseHTTPServer is derived from SocketServer.TCPServer.
This class serves up data using the handle_request() member function.
It looks like this (comments added by me):
    
-----------------------
def handle_request(self):
    try:
        request, client_address = self.get_request()
    except socket.error:
        return
    if self.verify_request(request, client_address):
        try:
            # this will start a new thread
            self.process_request(request, client_address)
        except:
            self.handle_error(request, client_address)
    # this will close the socket still in use by the new thread
    self.close_request(request)
-----------------------
The ThreadingTCPServer, which can be mixed in at a higher point in the
hierarchy, overloads self.process_request() to startup a new thread
for that request. However, once the thread has started, if the thread
running self.handle_request() gets the CPU before the other thread has
finished reading from the request, it will close the request, even
while a thread serving the request is running in the background.
And, self.close_request() closes the socket, so the error message
about _sock being a number is completely explainable. 

So I don't think just adding ThreadingTCPServer could've worked from
the start; and the same problem could possibly happen on the *nix
implementation of ThreadingTCPServer, too.

Solution: 

1) the derived TCPServer has to implement close_request(self) as a
stub function
2) the request class has to implement handle() and at the end of the
function, close the socket.



More information about the Python-list mailing list