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