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:
David Xu 2008-03-04 04:28:59 +00:00
parent 54c9b47c2b
commit 76a9679f8e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=176784
3 changed files with 24 additions and 1 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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