tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: SIGCHLD and sigaction()



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: bqt%softjar.se@localhost             ||  Reading murder books
pdp is alive!                     ||  tryin' to stay hip" - B. Idol


Home | Main Index | Thread Index | Old Index