<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;"><DIV>This may not be the correct list for this issue, if so I would appreciate if anyone could forward it to the correct list.</DIV>
<DIV> </DIV>
<DIV>I had experienced a number of problems with standard library SocketServer when implementing a tcp forking server under python 2.6.  I fixed every issue including some timing problems (e.g. socket request closed too fast before the last packet was grabbed) by overriding or extending methods as needed.</DIV>
<DIV> </DIV>
<DIV>Nonetheless, the one issue which may require a wider attention had to deal with method </DIV>
<DIV>collect_children() of class TCPServer.  This method makes the following os library call:</DIV>
<DIV> </DIV>
<DIV>pid, result = os.waitpid(child, options=0)</DIV>
<DIV> </DIV>
<DIV>Under some conditions the method breaks on this line with a message indicating that an unexpected keyword  argument "options" was provided.  In a continuous run reading thousands of packets from multiple client connects, this line seems to fail at times, but not always.  Unfortunately, I did not record the specific conditions that caused this "erroneous" error message, which happened unpredicatbly multiple times.</DIV>
<DIV> </DIV>
<DIV>To correct the problem the line of code may be changed by removing the keyword to:</DIV>
<DIV> </DIV>
<DIV>pid, result = os.waitpid(child, 0); this never fails.</DIV>
<DIV> </DIV>
<DIV>Nonetheless, I believe that method collect_children() is too cumbersome as written and I did override it with the following simpler strategy.  The developers of SocketServer may want to consider it as a replacement to the current code used for collect_children().</DIV>
<DIV> </DIV>
<DIV> def collect_children(self):<BR>   '''Collect Children - Overrides ForkingTCPServer collect_children method.<BR>   The provided method in SocketServer modules does not properly work for the<BR>   intended purpose.  This implementation is a complete replacement.<BR>   <BR>   Each new child process id (pid) is added to list active_children by method<BR>   process_request().  Each time a new connection is created by the method, a<BR>   call is then made here for cleanup of any inactive processes.</DIV>
<DIV>   Returns: None<BR>   '''<BR>   child = None<BR>   try:<BR>    if self.active_children:      # a list of active child processes<BR>     for child in self.active_children:<BR>      try:<BR>       val = os.waitpid(child, os.WNOHANG)  # val = (pid, status)<BR>       if not val[0]:            # pid 0; child is inactive<BR>        time.sleep(0.5)           # wait to kill<BR>        os.kill(child, signal.SIGKILL)   # make sure it is
 dead<BR>        self.active_children.remove(child) # remove from active list<BR>       else: continue<BR>      except OSError, err:<BR>       if errno.ECHILD != err.errno: # do not report; child not found<BR>        msg = '\tOS error attempting to terminate child process {0}.'<BR>        self.errlog.warning(msg.format(str(child)))<BR>       else: pass<BR>      except:<BR>       msg = '\tGeneral error attempting to terminate child process {0}.'<BR>       self.errlog.exception(msg.format(str(child)))<BR>     else:
 pass            # for child loop<BR>    else: pass<BR>   except:<BR>    msg = '\tGeneral error while attempting to terminate child process {0}.'<BR>    self.errlog.exception(msg.format(str(child)))<BR></DIV>
<DIV>Things to note are:</DIV>
<DIV>1. Using os.WNOHANG instead of 0 as options values to os.waitpid</DIV>
<DIV>2. Detecting if we get a returned pid==0; hence assume child is done</DIV>
<DIV>3. Attempt a os.kill for defunct children after a time.sleep(0.5); allow dependent processes to complete their job before totally closing down the request.</DIV>
<DIV>4. Report os errors as exceptions; but not errno.ECHILD, which means trying to kill none existing child; keep this as a warning.</DIV>
<DIV>This is more suscinct code and does the job.  At least it does it for me.</DIV>
<DIV> </DIV>
<DIV>Thanks,</DIV>
<DIV>Boris</DIV>
<DIV> </DIV></td></tr></table><br>