mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									a6298528e1
								
							
						
					
					
						commit
						392c159ad6
					
				
					 2 changed files with 47 additions and 19 deletions
				
			
		|  | @ -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: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeffrey Yasskin
						Jeffrey Yasskin