Mercurial > cpython-lru_cache-weakref
diff Lib/SocketServer.py @ 45551:cc220745e4e5 legacy-trunk
Prevent SocketServer.ForkingMixIn from waiting on child processes that it
didn't create, in most cases. When there are max_children handlers running, it
will still wait for any child process, not just handler processes.
| author | Jeffrey Yasskin <jyasskin@gmail.com> |
|---|---|
| date | Thu, 28 Feb 2008 18:03:15 +0000 |
| parents | e518e39f4a9e |
| children | a8754c0db53f |
line wrap: on
line diff
--- a/Lib/SocketServer.py Thu Feb 28 14:03:03 2008 +0000 +++ b/Lib/SocketServer.py Thu Feb 28 18:03:15 2008 +0000 @@ -440,18 +440,30 @@ def collect_children(self): """Internal routine to wait for children that have exited.""" - while self.active_children: - if len(self.active_children) < self.max_children: - options = os.WNOHANG - else: - # If the maximum number of children are already - # running, block while waiting for a child to exit - options = 0 + if self.active_children is None: return + while len(self.active_children) >= self.max_children: + # XXX: This will wait for any child process, not just ones + # spawned by this library. This could confuse other + # libraries that expect to be able to wait for their own + # children. try: - pid, status = os.waitpid(0, options) + pid, status = os.waitpid(0, options=0) except os.error: pid = None - if not pid: break + if pid not in self.active_children: continue + self.active_children.remove(pid) + + # XXX: This loop runs more system calls than it ought + # to. There should be a way to put the active_children into a + # process group and then use os.waitpid(-pgid) to wait for any + # of that set, but I couldn't find a way to allocate pgids + # that couldn't collide. + for child in self.active_children: + try: + pid, status = os.waitpid(child, os.WNOHANG) + except os.error: + pid = None + if not pid: continue try: self.active_children.remove(pid) except ValueError, e:
