I played a little bit with the new clone flags and wrote a small test
program using two threads: The first (initial) thread blocks all signals. The
second thread is created with all signals blocked and inherits the signal
mask of the initial thread. It unblocks SIGINT and calls sys_rt_sigtimedwait
with the remaining signal mask. Therefore it waits for all signals with
exception of SIGINT. In the kernel this yields to an empty signal mask for
this thread during the sigwait. No signal handler is installed by the
process. Now an external SIGINT is delivered to the whole process: The
signal delivery code decides to send this signal directly to the initial thread
because no user handler is installed and the signal mask for this thread
blocks the signal. The second thread never receives the SIGINT.
The main signal dispatching function send_sig_info in kernel/signal.c
requires at the moment an installed signal handler for delivery of signals
to members of the thread group.
Therefore NPTL/NPT must install signal handlers for all signals
during startup to allow signal delivery to other threads and must restore
these default handlers to SIG_DFL after first delivery and raise
the signal to create the correct exit code.
IMHO, the current signal system is not a clean solution (yet), but of course
much better than the ugly signal forwarding required by the thread group
leader only working as signal thread in 2.4.X.