Reindent properly.
This commit is contained in:
parent
cef1f83c71
commit
1bb8109fe3
|
@ -540,87 +540,85 @@ class UDPServer(TCPServer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if hasattr(os, "fork"):
|
if hasattr(os, "fork"):
|
||||||
# Non-standard indentation on this statement to avoid reindenting the body.
|
class ForkingMixIn:
|
||||||
class ForkingMixIn:
|
"""Mix-in class to handle each request in a new process."""
|
||||||
|
|
||||||
"""Mix-in class to handle each request in a new process."""
|
timeout = 300
|
||||||
|
active_children = None
|
||||||
|
max_children = 40
|
||||||
|
|
||||||
timeout = 300
|
def collect_children(self):
|
||||||
active_children = None
|
"""Internal routine to wait for children that have exited."""
|
||||||
max_children = 40
|
|
||||||
|
|
||||||
def collect_children(self):
|
|
||||||
"""Internal routine to wait for children that have exited."""
|
|
||||||
if self.active_children is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
# If we're above the max number of children, wait and reap them until
|
|
||||||
# we go back below threshold. Note that we use waitpid(-1) below to be
|
|
||||||
# able to collect children in size(<defunct children>) syscalls instead
|
|
||||||
# of size(<children>): the downside is that this might reap children
|
|
||||||
# which we didn't spawn, which is why we only resort to this when we're
|
|
||||||
# above max_children.
|
|
||||||
while len(self.active_children) >= self.max_children:
|
|
||||||
try:
|
|
||||||
pid, _ = os.waitpid(-1, 0)
|
|
||||||
self.active_children.discard(pid)
|
|
||||||
except ChildProcessError:
|
|
||||||
# we don't have any children, we're done
|
|
||||||
self.active_children.clear()
|
|
||||||
except OSError:
|
|
||||||
break
|
|
||||||
|
|
||||||
# Now reap all defunct children.
|
|
||||||
for pid in self.active_children.copy():
|
|
||||||
try:
|
|
||||||
pid, _ = os.waitpid(pid, os.WNOHANG)
|
|
||||||
# if the child hasn't exited yet, pid will be 0 and ignored by
|
|
||||||
# discard() below
|
|
||||||
self.active_children.discard(pid)
|
|
||||||
except ChildProcessError:
|
|
||||||
# someone else reaped it
|
|
||||||
self.active_children.discard(pid)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def handle_timeout(self):
|
|
||||||
"""Wait for zombies after self.timeout seconds of inactivity.
|
|
||||||
|
|
||||||
May be extended, do not override.
|
|
||||||
"""
|
|
||||||
self.collect_children()
|
|
||||||
|
|
||||||
def service_actions(self):
|
|
||||||
"""Collect the zombie child processes regularly in the ForkingMixIn.
|
|
||||||
|
|
||||||
service_actions is called in the BaseServer's serve_forver loop.
|
|
||||||
"""
|
|
||||||
self.collect_children()
|
|
||||||
|
|
||||||
def process_request(self, request, client_address):
|
|
||||||
"""Fork a new subprocess to process the request."""
|
|
||||||
pid = os.fork()
|
|
||||||
if pid:
|
|
||||||
# Parent process
|
|
||||||
if self.active_children is None:
|
if self.active_children is None:
|
||||||
self.active_children = set()
|
return
|
||||||
self.active_children.add(pid)
|
|
||||||
self.close_request(request)
|
# If we're above the max number of children, wait and reap them until
|
||||||
return
|
# we go back below threshold. Note that we use waitpid(-1) below to be
|
||||||
else:
|
# able to collect children in size(<defunct children>) syscalls instead
|
||||||
# Child process.
|
# of size(<children>): the downside is that this might reap children
|
||||||
# This must never return, hence os._exit()!
|
# which we didn't spawn, which is why we only resort to this when we're
|
||||||
status = 1
|
# above max_children.
|
||||||
try:
|
while len(self.active_children) >= self.max_children:
|
||||||
self.finish_request(request, client_address)
|
|
||||||
status = 0
|
|
||||||
except Exception:
|
|
||||||
self.handle_error(request, client_address)
|
|
||||||
finally:
|
|
||||||
try:
|
try:
|
||||||
self.shutdown_request(request)
|
pid, _ = os.waitpid(-1, 0)
|
||||||
|
self.active_children.discard(pid)
|
||||||
|
except ChildProcessError:
|
||||||
|
# we don't have any children, we're done
|
||||||
|
self.active_children.clear()
|
||||||
|
except OSError:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Now reap all defunct children.
|
||||||
|
for pid in self.active_children.copy():
|
||||||
|
try:
|
||||||
|
pid, _ = os.waitpid(pid, os.WNOHANG)
|
||||||
|
# if the child hasn't exited yet, pid will be 0 and ignored by
|
||||||
|
# discard() below
|
||||||
|
self.active_children.discard(pid)
|
||||||
|
except ChildProcessError:
|
||||||
|
# someone else reaped it
|
||||||
|
self.active_children.discard(pid)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def handle_timeout(self):
|
||||||
|
"""Wait for zombies after self.timeout seconds of inactivity.
|
||||||
|
|
||||||
|
May be extended, do not override.
|
||||||
|
"""
|
||||||
|
self.collect_children()
|
||||||
|
|
||||||
|
def service_actions(self):
|
||||||
|
"""Collect the zombie child processes regularly in the ForkingMixIn.
|
||||||
|
|
||||||
|
service_actions is called in the BaseServer's serve_forver loop.
|
||||||
|
"""
|
||||||
|
self.collect_children()
|
||||||
|
|
||||||
|
def process_request(self, request, client_address):
|
||||||
|
"""Fork a new subprocess to process the request."""
|
||||||
|
pid = os.fork()
|
||||||
|
if pid:
|
||||||
|
# Parent process
|
||||||
|
if self.active_children is None:
|
||||||
|
self.active_children = set()
|
||||||
|
self.active_children.add(pid)
|
||||||
|
self.close_request(request)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
# Child process.
|
||||||
|
# This must never return, hence os._exit()!
|
||||||
|
status = 1
|
||||||
|
try:
|
||||||
|
self.finish_request(request, client_address)
|
||||||
|
status = 0
|
||||||
|
except Exception:
|
||||||
|
self.handle_error(request, client_address)
|
||||||
finally:
|
finally:
|
||||||
os._exit(status)
|
try:
|
||||||
|
self.shutdown_request(request)
|
||||||
|
finally:
|
||||||
|
os._exit(status)
|
||||||
|
|
||||||
|
|
||||||
class ThreadingMixIn:
|
class ThreadingMixIn:
|
||||||
|
|
Loading…
Reference in New Issue