On modern linux, signalfd can be used to convert sigchld into an event on a file descriptor. Looks like just what is wanted for processProtocol. There is also a python interface here: https://launchpad.net/python-signalfd/+download This test seems to work for me: import signalfd import signal import subprocess import select signalfd.sigprocmask (signalfd.SIG_BLOCK, [signal.SIGCHLD]) fd = signalfd.signalfd (-1, [signal.SIGCHLD]) child = subprocess.Popen (['sleep', '5']) while True: a,b,c, = select.select ([fd], [], []) print 'a:', a, 'b:', b, 'c:', c if child.poll() != None: break
On 01:45 am, ndbecker2@gmail.com wrote:
On modern linux, signalfd can be used to convert sigchld into an event on a file descriptor. Looks like just what is wanted for processProtocol.
It does, indeed. I'm not sure it's really worth bothering though. Here are the drawbacks of using signalfd(): - It only works on Linux - It works differently on older versions of Linux than on newer versions - You still can't have another SIGCHLD handler installed that will called (so it's not any more cooperative with other library code) As compared to using SA_RESTART with a normal SIGCHLD handler, this is two extra drawbacks. The advantages of signalfd() are: - It's just another fd, so the reactor doesn't need as much special support code But this advantage is negated by the fact that we still need the special support code for older versions of Linux and for other platforms. If anyone's aware of other advantages or drawbacks of one approach or the other, it would be interesting to hear about them. Otherwise, it doesn't seem like it's worth changing. Thanks for the suggestion! :) Jean-Paul
On Nov 3, 2010, at 10:23 PM, exarkun@twistedmatrix.com wrote:
On 01:45 am, ndbecker2@gmail.com wrote:
On modern linux, signalfd can be used to convert sigchld into an event on a file descriptor. Looks like just what is wanted for processProtocol.
It does, indeed. I'm not sure it's really worth bothering though. Here are the drawbacks of using signalfd():
- It only works on Linux - It works differently on older versions of Linux than on newer versions - You still can't have another SIGCHLD handler installed that will called (so it's not any more cooperative with other library code)
Another drawback is that spawned subprocesses will start with SIGCHLD blocked (because the sigprocmask is inherited across fork/exec, like SIG_IGN is, but unlike signal handlers), unless twisted adds a pthread_atfork handler (which there is no way to do from Python, so that'd have to be more custom C code). And even with that, system() would still remain broken, because system() inexplicably doesn't call atfork handlers on linux/glibc (notabug according to glibc maintainers). Of course, the Twisted process API could unblock SIGCHLD itself before calling exec, but this would leave spawning a process with any other API (subprocess/etc) broken. Many programs will not react well to starting with SIGCHLD blocked. Since Twisted just recently managed to make spawning subprocesses with non-Twisted APIs actually work right, it'd be quite poor to break that again. James
One more piece seems available: http://code.google.com/p/python-atfork/
On Nov 17, 2010, at 10:40 AM, Neal Becker wrote:
One more piece seems available:
Nope, that's not a "real" atfork: it only monkey-patches python's os.fork() function, so it doesn't catch any fork done by C code. So it's not good enough. (but of course, as mentioned previously, pthread_atfork itself isn't good enough either). See also a comment I wrote on lwn.net recently: http://lwn.net/Articles/415684/ James
participants (3)
-
exarkun@twistedmatrix.com
-
James Y Knight
-
Neal Becker