Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Lib/multiprocessing/forkserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,22 +150,25 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
util._close_stdin()

sig_r, sig_w = os.pipe()
os.set_blocking(sig_r, False)
os.set_blocking(sig_w, False)

def sigchld_handler(*_unused):
try:
os.write(sig_w, b'.')
except BlockingIOError:
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this change :-) Using the existing C signal handler for the write is probably more reliable ;-)

# Dummy signal handler, doesn't do anything
pass

# letting SIGINT through avoids KeyboardInterrupt tracebacks
# unblocking SIGCHLD allows the wakeup fd to notify our event loop
handlers = {
signal.SIGCHLD: sigchld_handler,
signal.SIGINT: signal.SIG_DFL,
}
old_handlers = {sig: signal.signal(sig, val)
for (sig, val) in handlers.items()}

# calling os.write() in the Python signal handler is racy
signal.set_wakeup_fd(sig_w)

# map child pids to client fds
pid_to_fd = {}

Expand Down Expand Up @@ -252,6 +255,7 @@ def sigchld_handler(*_unused):

def _serve_one(child_r, fds, unused_fds, handlers):
# close unnecessary stuff and reset signal handlers
signal.set_wakeup_fd(-1)
for sig, val in handlers.items():
signal.signal(sig, val)
for fd in unused_fds:
Expand Down