X-Git-Url: http://git.csclub.uwaterloo.ca/?p=kopensolaris-gnu%2Fglibc.git;a=blobdiff_plain;f=nptl%2Fsysdeps%2Funix%2Fsysv%2Fsolaris2%2Fkopensolaris-gnu%2Fcreatethread.c;h=19171522bab01318a4ebed2b0d8e5e11c38c7a41;hp=7ddaf9c79923bba3cac7d732e58789a051adc10a;hb=ad8bb4d13593dcf41d13a59163245ac2468583ce;hpb=e544d0289c66840848318ed7cdb53dbb0d11ccf7 diff --git a/nptl/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/createthread.c b/nptl/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/createthread.c index 7ddaf9c799..19171522ba 100644 --- a/nptl/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/createthread.c +++ b/nptl/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/createthread.c @@ -22,13 +22,12 @@ #include #include -#include #include #include #include -#include +#include #include -#include +#include #include DECLARE_INLINE_SYSCALL (int, lwp_create, ucontext_t *ucp, int flags, @@ -55,6 +54,9 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, if (errval != 0) return errval; + /* Threads inherit the parent's sigmask. */ + pthread_sigmask (SIG_SETMASK, NULL, &ctx.uc_sigmask); + /* One more thread. We cannot have the thread do this itself, since it might exist but not have been scheduled yet by the time we've returned and need to check the value to behave correctly. We must do it before @@ -68,10 +70,10 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, /* We set the thread to be initially suspended so that we can set scheduling magic. */ int lwp_flags = - ((attr->flags & ATTR_FLAG_DAEMON) ? THR_DAEMON : 0) | - ((attr->flags & ATTR_FLAG_DETACHSTATE) ? THR_DETACHED : 0); - if (attr->flags & ATTR_FLAG_THR_CREATE == 0) - lwp_flags |= THR_SUSPENDED; + ((attr->flags & ATTR_FLAG_DAEMON) ? LWP_DAEMON : 0) | + ((attr->flags & ATTR_FLAG_DETACHSTATE) ? LWP_DETACHED : 0); + if ((attr->flags & ATTR_FLAG_THR_CREATE) == 0) + lwp_flags |= LWP_SUSPENDED; errval = INLINE_SYSCALL (lwp_create, 3, &ctx, lwp_flags, &pd->tid); if (errval == 0 && (attr->flags & ATTR_FLAG_THR_CREATE) == 0) { @@ -96,28 +98,36 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, errval = EPERM; } - /* Resume thread if requested. */ - if (errval == 0) + if (errval == 0 && !(attr->flags & ATTR_FLAG_SUSPENDED)) { - if (!(attr->flags & ATTR_FLAG_SUSPENDED)) - errval = INLINE_SYSCALL (lwp_continue, 1, pd->tid); + errval = INLINE_SYSCALL (lwp_continue, 1, pd->tid); } + else if (errval != 0) + { + pd->flags |= ATTR_FLAG_CREATE_FAILED; + INLINE_SYSCALL (lwp_continue, 1, pd->tid); + + if (!IS_DETACHED (pd)) + { + int result; + lll_wait_tid (pd->tid); + } - /* Kill the thread if we didn't succeed above. */ - if (errval != 0) - INLINE_SYSCALL (lwp_kill, 2, pd->tid, SIGKILL); + /* Note: if the thread is detached, start_thread will free pd; + otherwise the caller of create_thread will free pd. */ + } } - if (errval != 0) + if (errval == 0) + { + /* We now have for sure more than one thread. The main thread might + not yet have the flag set. No need to set the global variable + again if this is what we use. */ + THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); + } + else { atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */ - - /* Failed. If the thread is detached, remove the TCB here since - the caller cannot do this. The caller remembered the thread - as detached and cannot reverify that it is not since it must - not access the thread descriptor again. */ - if (IS_DETACHED (pd)) - __deallocate_stack (pd); } return errval;