casaroli opened a new pull request, #21440:
URL: https://github.com/apache/nuttx/pull/21440

   ## Summary
   
   The default action of a signal that ends a process (SIGTERM, SIGINT, 
SIGSEGV, SIGKILL and the others of `CONFIG_SIG_SIGKILL_ACTION`) calls 
`group_kill_children()`. When `CONFIG_GROUP_KILL_CHILDREN_TIMEOUT_MS` is not 0 
(the default is -1), `group_kill_children()` first sends SIGTERM to each other 
thread and waits until these threads exit. A thread that blocks SIGTERM does 
not exit. So the process does not end: with -1 it stays until that thread exits 
by itself, and with a timeout it ends only after the timeout. POSIX says that 
the default action terminates the whole process.
   
   - **sched/signal: Cancel the other threads at once in a default action.** 
The thread that does the default action sets `TCB_FLAG_FORCED_CANCEL` before it 
calls `group_kill_children()`, as the exception handlers of arm64, armv7-a, 
risc-v and x86_64 do before they call `_exit()`. `group_kill_children()` then 
does not send SIGTERM and cancels the other threads at once (`pthread_cancel()` 
/ `nxtask_delete()` with the forced flag; `nxtask_terminate()` removes a thread 
that runs on another CPU). The Kconfig help of 
`CONFIG_GROUP_KILL_CHILDREN_TIMEOUT_MS` says that the default action does not 
use it.
   - **Documentation: The default action ends all threads of a task group.** 
One line in `Documentation/reference/user/07_signals.rst`.
   
   depends-on: apache/nuttx/pull/21436
   
   ## Impact
   
   Only builds with `CONFIG_SIG_DEFAULT` and pthreads. A fatal signal with the 
default action now ends a process at once, also when another thread blocks or 
catches SIGTERM. The other threads no longer get a SIGTERM before they end: 
before, a SIGTERM handler of the process ran in the other threads when, for 
example, SIGINT ended the process. All build modes and architectures (common 
code); no change to an interface or a structure.
   
   `exit()`, `_exit()` and the task restart do not change: they still send 
SIGTERM first and wait as `CONFIG_GROUP_KILL_CHILDREN_TIMEOUT_MS` says. With 
the default -1, `exit()` in a process with a thread that blocks SIGTERM still 
waits until that thread exits (the test below shows it as INFO).
   
   ## Testing
   
   Test program `twothrterm`: the parent starts itself as a child for each case 
and measures how long the child lives. The main thread of the child blocks 
SIGTERM, sends it to the process and unblocks it. A second thread blocks all 
signals and either sleeps 5 s (`sleep`) or runs 5 s at a lower priority 
(`spin`; on SMP it runs on another CPU); if it gets to the end, it prints FAIL 
and exits with 9. PASS: the child ends in less than 3 s and not with 9. The 
`exit` case does the same with `exit()` in place of the signal (INFO, not 
counted).
   
   QEMU with HVF, `CONFIG_SIG_DEFAULT` and `CONFIG_SCHED_CHILD_STATUS`; the 
flat builds also with `CONFIG_CANCELLATION_POINTS`. Time from the start of the 
child to its end:
   
   | Configuration | Case | master | this PR |
   |---|---|---|---|
   | qemu-armv8a:knsh (kernel) | sleep | 5006 ms: FAIL | 108 ms: PASS |
   | qemu-armv8a:knsh (kernel) | spin | 5015 ms: FAIL | 108 ms: PASS |
   | qemu-armv8a:knsh (kernel) | exit (INFO) | 5011 ms | 5004 ms |
   | qemu-armv8a:nsh (flat) | sleep | 5002 ms: FAIL | 101 ms: PASS |
   | qemu-armv8a:nsh (flat) | spin | 5001 ms: FAIL | 101 ms: PASS |
   | qemu-armv8a:nsh (flat) | exit (INFO) | 5001 ms | 5001 ms |
   | qemu-armv8a:nsh_smp (flat, SMP, 2 CPUs) | sleep | 5003 ms: FAIL | 101 ms: 
PASS |
   | qemu-armv8a:nsh_smp (flat, SMP, 2 CPUs) | spin | 5001 ms: FAIL | 101 ms: 
PASS |
   | qemu-armv8a:nsh_smp (flat, SMP, 2 CPUs) | exit (INFO) | 5003 ms | 5003 ms |
   
   ostest: qemu-armv8a:knsh 0, qemu-armv8a:nsh 0 and qemu-armv8a:nsh_smp 0, on 
master and with this PR.
   
   Build with `EXTRAFLAGS="-Wno-cpp -Werror"` as CI, each OK: qemu-armv8a:nsh 
(flat; also with `CONFIG_SIG_DEFAULT` and `CONFIG_CANCELLATION_POINTS`), 
qemu-armv8a:knsh (kernel), rv-virt:citest (flat, rv32), rv-virt:ksmp64 (kernel, 
SMP, rv64) and mps2-an500:knsh (protected, Cortex-M7), all with 
`CONFIG_SIG_DEFAULT`. With `CONFIG_DISABLE_PTHREAD` the kernel compiles and the 
link fails in apps (ostest and getprime use pthreads; not changed here).
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to