On 2020-08-16 12:49, Johnny Billquist wrote:
On 2020-08-15 22:46, Mouse wrote:
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.
Historically, "no": in some older systems, a second SIGCHLD delivered
when there's already one pending delivery gets, lost same as any other
signal.
Then someone - POSIX? SVR4? I don't know - decided to invent a flavour
of signal that's more like writes to a pipe: multiple of them can be
pending at once. Some systems decided this was sane and implemented
it.
Personally, I don't like it; I think signals should be much like
hardware interrupts in that a second instance happening before the
first is serviced gets silently merged.
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. 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).
The problem goes like this:
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.
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.
In real hardware this usually don't happen, because the actual interrupt
request can be reissued by the device while you are in the interrupt
handler. There are some hardware interrupt designs, with edge triggered
interrupts, where similar problems can exist, and those you have to be
very careful with how you handle them so you don't get to the same kind
of race condition.
Now, have I misunderstood something about how non-queued signal handling
works, or is/was there a problem there?
Reading the current documentation, I would assume that at the call to
the signal handler, the signal is blocked, and also removed from pending
signals, so a new even would queue up a new signal to be delivered when
returning from the signal handler. However, the text above is from
trying to recall how it used to be going back in time, to when you had
to re-install the signal handler after each activation. I can't seem to
find documentation for how it worked back in the day. I can't even
remember when/where I was reading up on that and thinking there might be
a problem here, but it was a long time ago. So this is possibly just of
historical interest.
By the way, I haven't seen any explicit mention of the pending signal
being cleared at signal handler entry, so that is just my assumption
right now. If that is wrong, then I would expect there is a race
condition in there. Maybe someone else knows where that detail is
documented?
Johnny
--
Johnny Billquist || "I'm on a bus
|| on a psychedelic trip
email: [email protected] || Reading murder books
pdp is alive! || tryin' to stay hip" - B. Idol