diff options
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/timer_routines.c')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/timer_routines.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/timer_routines.c b/nptl/sysdeps/unix/sysv/linux/timer_routines.c index e9ece9f488..b0d6ef91bf 100644 --- a/nptl/sysdeps/unix/sysv/linux/timer_routines.c +++ b/nptl/sysdeps/unix/sysv/linux/timer_routines.c @@ -49,6 +49,11 @@ timer_helper_thread (void *arg) sigset_t ss; sigemptyset (&ss); sigaddset (&ss, SIGTIMER); + /* SIGTIMER is the same signal as SIGCANCEL and it is therefore + unblocked so far. Block it for this thread, we handle + cancellation explicitly. */ + INTERNAL_SYSCALL_DECL (err); + INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_BLOCK, &ss, NULL, _NSIG / 8); /* Endless loop of waiting for signals. The loop is only ended when the thread is canceled. */ @@ -56,14 +61,19 @@ timer_helper_thread (void *arg) { siginfo_t si; - if (sigwaitinfo (&ss, &si) > 0 && si.si_code == SI_TIMER) + if (sigwaitinfo (&ss, &si) > 0) { - - struct timer *tk = (struct timer *) si.si_ptr; - - /* That the signal we are waiting for. */ - pthread_t th; - (void) pthread_create (&th, &tk->attr, timer_sigev_thread, tk); + if (si.si_code == SI_TIMER) + { + struct timer *tk = (struct timer *) si.si_ptr; + + /* That the signal we are waiting for. */ + pthread_t th; + (void) pthread_create (&th, &tk->attr, timer_sigev_thread, tk); + } + else if (si.si_code == SI_TKILL) + /* The thread is canceled. */ + pthread_exit (NULL); } } } |