diff options
author | davidxu <davidxu@FreeBSD.org> | 2008-03-04 04:28:59 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2008-03-04 04:28:59 +0000 |
commit | 8ead1ed2f9013c5815c4c1db7a3cfe8ba641cf58 (patch) | |
tree | 5a3c84004ac145a232bef7db666578efa5dd21e8 /lib/libthr/thread/thr_create.c | |
parent | e0d98325b4da9160dd1e0041c794b99e37ddb7df (diff) | |
download | FreeBSD-src-8ead1ed2f9013c5815c4c1db7a3cfe8ba641cf58.zip FreeBSD-src-8ead1ed2f9013c5815c4c1db7a3cfe8ba641cf58.tar.gz |
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
Diffstat (limited to 'lib/libthr/thread/thr_create.c')
-rw-r--r-- | lib/libthr/thread/thr_create.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c index 03f0584..3bfd3b3 100644 --- a/lib/libthr/thread/thr_create.c +++ b/lib/libthr/thread/thr_create.c @@ -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; |