diff options
author | Jeffrey Yasskin <jyasskin@gmail.com> | 2008-02-28 18:03:15 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@gmail.com> | 2008-02-28 18:03:15 +0000 |
commit | 392c159ad6a0a622c5d78b6783039e836829a6d9 (patch) | |
tree | 2febe0ccd983074bcb4cc7700b268e2ea61070aa /Lib/SocketServer.py | |
parent | a6298528e1f5c10abd0d4255ef911179e9b1b912 (diff) | |
download | cpython-git-392c159ad6a0a622c5d78b6783039e836829a6d9.tar.gz |
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.
Diffstat (limited to 'Lib/SocketServer.py')
-rw-r--r-- | Lib/SocketServer.py | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/Lib/SocketServer.py b/Lib/SocketServer.py index 1763c1d5e4..0a194e5de8 100644 --- a/Lib/SocketServer.py +++ b/Lib/SocketServer.py @@ -440,18 +440,30 @@ class ForkingMixIn: 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: |