Thinking about it, you're right...  signals_caught[signum]++ is not
atomic, but it probably does not matter because no code other than the
handler for another signal (i.e., different signum) can run in the
middle of a signal handler.

[ Aside: just to clarify why the increment is not atomic:

SUSv3 is characteristically vague on the guarantees associated with 
sig_atomic_t:
"Possibly volatile-qualified integer type of an object that can be accessed as 
an atomic entity, even in the presence of asynchronous interrupts."

libc.info is slightly more explicit...
"Reading and writing this data type is guaranteed to happen in a single 
instruction"
but this also carries the (probably wrong) suggestion that a read-modify-write 
operation can be performed in a single instruction.

RISC-like architectures cannot do this:

x86:
        /* signum is in eax */
        incl signals_caught(%eax,4)

ARM:
        /* signum is in r0 */
        ldr r1, =signals_caught
        ldr r2, [r1, r0, LSL #2]
        add r2, r2, #1
        str r2, [r1, r0, LSL #2]

In the ARM code, an increment could be lost if this code interrupts some
other code (or vice versa).  This won't ever happen on x86, provided
that the other bit of code is atomic too.

End aside ]



Anyway, if there is a problem with the existing code, it would be that the 
signal handler can interrupt the code in nih_signal_poll(), after a given 
element in signals_caught is checked, but before the elements of 
signals_caught[] are reset to zero.  Could this cause a signal to be lost?

If so, simply blocking all signals around the critical code in
nih_signal_poll() might solve the problem (and elsewhere if
applicable... I haven't looked.)  However this does imply that all
signals are blocked during the signal->handler() calls, which might or
might not be acceptable.  An alternative could be to process the signals
one by one: for each, you block, check, dispatch, reset, then unblock
the signal.  Then only one signal will be blocked at any one time.

The third option is do increment and decrement the counters truly
atomically.  This will require architecture-specific code, or a library
such as pthreads which abstracts these operations.  Unfortunately, I
don't think the pthreads functions are oficially safe to call from
signal handlers (but there may be some exceptions).

Any good?

-- 
init stops respawning terminal logins after while
https://bugs.launchpad.net/bugs/347205
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to