>>> When I install a SIGCHLD handler via sigaction() using SA_SIGINFO, >>> is it guaranteed that my handler is called (at least) once per >>> death-of-a-child? >> "Maybe." It depends on how portable you want to be. >> [...] > While we're on this topic. Unix signals don't exactly work like > hardware interrupts anyhow, I suspect, and it's a thing that have > constantly befuddled me.
(Caveat: this is all just my understanding. I think it's accurate, but I welcome corrections.) No, they don't. To the extent that they do, they work like (latched) edge-triggered interrupts. There is no signal analog to a level-triggered interrupt. And, as you say, there are some important differences even beyond that. > As far as I can tell, there is a problematic race condition in the > old signal mechanism, and that is the reason (I believe) why the new > semantics were introduced). I think you are right. But it's not just "old" and "new". There are really old signal semantics, where the handler is uninstalled, I think it is, when the signal is delivered, and it's up to the code to reinstall it. This is vulnerable to, if nothing else, the race where a second signal arrives before the handler gets reinstalled, though that's less important for SIGCHLD (see below). (There may be an even older form of signal handling, but if so I know nothing about it.) This then led to (so-called) reliable signals, where the handler stays installed (or at least can be set to do so) but signals can be blocked, and get blocked (or, again, at least can be set to be) when the handler is called. However, there is still only a single pending bit per signal. I think these came in sometime in the 4BSD era, but I don't recall details - indeed, I'm not sure I ever knew details. Turning SIGCHLD into something queued, something more like bytes in a pipe, is, in my perception, more recent yet. I'm not sure who invented them (but see below). There are traces of the first form in modern NetBSD, in the form of the SA_RESETHAND bit. I don't *think* that gives full unreliable-signal semantics, but I haven't checked in enough detail to be sure - I think you'd also need an SA_DONTBLOCK flag or something of the sort, or the handler would have to explicitly unblock the signal. > You have two child processes. One exit, and you get into your signal > handler. In there you then call wait to reap the child and process > things. You then call wait again, and repeat until there are no > children left to reap, as you only get one signal, even if you get > multiple children that exits. When no more unreaped children exist, > you exit the signal handler, and a new signal can be delivered. Right. > However, what happens if the second child exists between the call to > wait, and the exit from the signal handler? It would seem the signal > would get lost, since we are in the process of handling the signal, > and a new signal is not delivered during this time. If you're using unreliable signals - the first sort I outlined above - then yes, there is either this race, or, if you reinstall the handler before you do your last wait call, a different race. (Provided your handler doesn't mind being called recursively between reinstall and return, this may be tolerable.) If you're using reliable signals but without queued SIGCHLD, this is not a problem, because the second SIGCHLD (and any additional later SIGCHLDs) will set the pending bit for SIGCHLD. As soon as you return from the handler (or explicitly unblock the signal), it will be delivered. > Now, have I misunderstood something about how non-queued signal > handling works, or is/was there a problem there? There was, but it was a problem with the oldest of the above three kinds of signal. Queued SIGCHLD was not necessary for it - I don't understand what problem queued SIGCHLD was invented to address. The only thing I can think of was that it came from SRV4, which had a NIH attitude towards BSD reliable signals, so they invented queued SIGCHLD to get reliable child death handling, and then someone (POSIX maybe?) decided it would be good to include all of both mechanisms. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML [email protected] / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
