summaryrefslogtreecommitdiff
path: root/lib/libthr/thread/thr_create.c
diff options
context:
space:
mode:
authorDavid Xu <davidxu@FreeBSD.org>2008-04-11 01:42:20 +0000
committerDavid Xu <davidxu@FreeBSD.org>2008-04-11 01:42:20 +0000
commitee61152b4f34bd637266ddb54c3bbec9b00bbf97 (patch)
treedf8c653e8f83c8138cb1e01e291f26064b379008 /lib/libthr/thread/thr_create.c
parent04175b15f17815682c1edb9d60a4e1140405aab1 (diff)
Notes
Diffstat (limited to 'lib/libthr/thread/thr_create.c')
-rw-r--r--lib/libthr/thread/thr_create.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c
index abab2123a06d..ad0f14017ecb 100644
--- a/lib/libthr/thread/thr_create.c
+++ b/lib/libthr/thread/thr_create.c
@@ -119,6 +119,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);
@@ -213,26 +218,40 @@ create_stack(struct pthread_attr *pattr)
static void
thread_start(struct pthread *curthread)
{
- if (curthread->attr.suspend == THR_CREATE_SUSPENDED) {
- sigset_t set = curthread->sigmask;
+ sigset_t set;
+
+ if (curthread->attr.suspend == THR_CREATE_SUSPENDED)
+ set = curthread->sigmask;
+
+ /*
+ * This is used as a serialization point to allow parent
+ * to report 'new thread' event to debugger or tweak new thread's
+ * attributes before the new thread does real-world work.
+ */
+ THR_LOCK(curthread);
+ THR_UNLOCK(curthread);
+ if (curthread->unblock_sigcancel) {
+ sigset_t set1;
+
+ SIGEMPTYSET(set1);
+ SIGADDSET(set1, SIGCANCEL);
+ __sys_sigprocmask(SIG_UNBLOCK, &set1, NULL);
+ }
+
+ if (curthread->attr.suspend == THR_CREATE_SUSPENDED) {
+#if 0
+ /* Done in THR_UNLOCK() */
_thr_ast(curthread);
+#endif
/*
* Parent thread have stored signal mask for us,
* we should restore it now.
*/
- sigprocmask(SIG_SETMASK, &set, NULL);
+ __sys_sigprocmask(SIG_SETMASK, &set, NULL);
}
- /*
- * This is used as a serialization point to allow parent
- * to report 'new thread' event to debugger before the thread
- * does real work.
- */
- THR_LOCK(curthread);
- THR_UNLOCK(curthread);
-
/* Run the current thread's start routine with argument: */
_pthread_exit(curthread->start_routine(curthread->arg));