mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
If a new thread is created, it inherits current thread's signal masks,
however if current thread is executing cancellation handler, signal SIGCANCEL may have already been blocked, this is unexpected, unblock the signal in new thread if this happens. MFC after: 1 week
This commit is contained in:
parent
54c9b47c2b
commit
76a9679f8e
3 changed files with 24 additions and 1 deletions
|
|
@ -123,6 +123,11 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
|
|||
if (new_thread->attr.flags & PTHREAD_CREATE_DETACHED)
|
||||
new_thread->tlflags |= TLFLAGS_DETACHED;
|
||||
|
||||
if (curthread->in_sigcancel_handler)
|
||||
new_thread->unblock_sigcancel = 1;
|
||||
else
|
||||
new_thread->unblock_sigcancel = 0;
|
||||
|
||||
/* Add the new thread. */
|
||||
new_thread->refcount = 1;
|
||||
_thr_link(curthread, new_thread);
|
||||
|
|
@ -172,8 +177,10 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
|
|||
ret = EAGAIN;
|
||||
}
|
||||
|
||||
if (create_suspended)
|
||||
if (create_suspended) {
|
||||
__sys_sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
SIGDELSET(oset, SIGCANCEL);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
if (!locked)
|
||||
|
|
@ -217,6 +224,14 @@ create_stack(struct pthread_attr *pattr)
|
|||
static void
|
||||
thread_start(struct pthread *curthread)
|
||||
{
|
||||
if (curthread->unblock_sigcancel) {
|
||||
sigset_t set;
|
||||
|
||||
SIGEMPTYSET(set);
|
||||
SIGADDSET(set, SIGCANCEL);
|
||||
sigprocmask(SIG_UNBLOCK, &set, NULL);
|
||||
}
|
||||
|
||||
if (curthread->attr.suspend == THR_CREATE_SUSPENDED) {
|
||||
sigset_t set = curthread->sigmask;
|
||||
|
||||
|
|
|
|||
|
|
@ -378,6 +378,12 @@ struct pthread {
|
|||
/* Thread temporary signal mask. */
|
||||
sigset_t sigmask;
|
||||
|
||||
/* Thread is in SIGCANCEL handler. */
|
||||
int in_sigcancel_handler;
|
||||
|
||||
/* New thread should unblock SIGCANCEL. */
|
||||
int unblock_sigcancel;
|
||||
|
||||
/* Thread state: */
|
||||
enum pthread_state state;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,9 @@ sigcancel_handler(int sig __unused,
|
|||
|
||||
if (curthread->cancel_defer && curthread->cancel_pending)
|
||||
thr_wake(curthread->tid);
|
||||
curthread->in_sigcancel_handler = 1;
|
||||
_thr_ast(curthread);
|
||||
curthread->in_sigcancel_handler = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Reference in a new issue