aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-06-17 09:45:03 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2021-06-23 13:45:13 -0300
commitbf6749a7f87c54e62db26b24c63b27004a110847 (patch)
tree9f847757df91f3ab89914c10dd00f9cc8e9c9154 /nptl
parent03caacbc7f3004ad21fc00bf883f00421a211130 (diff)
downloadglibc-bf6749a7f87c54e62db26b24c63b27004a110847.zip
glibc-bf6749a7f87c54e62db26b24c63b27004a110847.tar.gz
glibc-bf6749a7f87c54e62db26b24c63b27004a110847.tar.bz2
nptl: Use SA_RESTART for SIGCANCEL handler
The usage of signals to implementation pthread cancellation is an implementation detail and should not be visible through cancellation entrypoints. However now that pthread_cancel always send the SIGCANCEL, some entrypoint might be interruptable and return EINTR to the caller (for instance on sem_wait). Using SA_RESTART hides this, since the cancellation handler should either act uppon cancellation (if asynchronous cancellation is enable) or ignore the cancellation internal signal. Checked on x86_64-linux-gnu and i686-linux-gnu.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/pthread_cancel.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 0698cd2..cc25ff2 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -72,7 +72,11 @@ __pthread_cancel (pthread_t th)
{
struct sigaction sa;
sa.sa_sigaction = sigcancel_handler;
- sa.sa_flags = SA_SIGINFO;
+ /* The signal handle should be non-interruptible to avoid the risk of
+ spurious EINTR caused by SIGCANCEL sent to process or if
+ pthread_cancel() is called while cancellation is disabled in the
+ target thread. */
+ sa.sa_flags = SA_SIGINFO | SA_RESTART;
__sigemptyset (&sa.sa_mask);
__libc_sigaction (SIGCANCEL, &sa, NULL);
atomic_store_relaxed (&init_sigcancel, 1);