Ticket #2535 enhancement closed wontfix
Allow Twisted to work without interfering with libraries which use SIGCHLD on posix
|Reported by:||spiv||Owned by:|
Description (last modified by glyph) (diff)
Twisted currently needs to install a SIGCHLD handler for reactor.spawnProcess to work reliably. This is problematic when Twisted is used with other libraries that depend on handling SIGCHLD in their own way. Currently, the reactor can be run with the installSignalHandlers=False flag to cooperate with such libraries, but then reactor.spawnProcess isn't reliable.
There are a couple of ways to work around this.
- When run with installSignalHandlers=False Twisted could use a different strategy for notifications of subprocess termination. spawnProcess could first fork a process that keeps a single file descriptor back to the parent open, and then forks the child that the caller of spawnProcess requested. Then first subprocess could simply do:
pid = os.fork() if pid: returnVal = wait(pid) os.write(fd, str(returnVal)) os.close(fd) os._exit()
i.e. wait for the child process to finish, and then let the original process know the return value and exit. The original process would know that the subprocess was done when it saw the fd get closed, and would know what the return value was.
This does come at the unfortunate cost of having an additional process (an additional Python process, even!) per running subprocess, which is not insubstantial. However, it is only in a fairly unusual case that you'd need it.
- Another option is to repeatedly poll processes, at a timed interval, to see if they've exited yet. Since most processes end up being either very short or very long running, we could probably come up with an heuristic for calculating the next polling interval that wouldn't be too inefficient.
- Apparently some reactors (kqueue? epoll? iocp maybe?) may be able to specifically identify process-exited events independent of signals; this may be preferable to listening to SIGCHLD even if we don't need to cooperate with other software which uses it. (Someone else please fill this in, since I'm not familiar with these APIs.)