(pthread_handle_create): Start the child thread with the cancel signal blocked, so that it does not handle it before the thread register is set up. Save errno from failed clone call.

This commit is contained in:
Andreas Schwab 2001-11-26 12:59:16 +00:00
parent dd09c3dcc9
commit a86e3e5891

View File

@ -526,6 +526,8 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
char *guardaddr = NULL;
size_t guardsize = 0;
int pagesize = __getpagesize();
int saved_errno;
sigset_t newmask, oldmask;
/* First check whether we have to change the policy and if yes, whether
we can do this. Normally this should be done by examining the
@ -611,6 +613,11 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
if ((mask & (__pthread_threads_events.event_bits[idx]
| event_maskp->event_bits[idx])) != 0)
{
/* Block cancel signal in the child until it is fully
initialized. */
sigemptyset(&newmask);
sigaddset(&newmask, __pthread_sig_cancel);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
/* Lock the mutex the child will use now so that it will stop. */
__pthread_lock(new_thread->p_lock, NULL);
@ -638,6 +645,8 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
__pthread_sig_cancel, new_thread);
#endif
saved_errno = errno;
sigprocmask(SIG_SETMASK, &oldmask, NULL);
if (pid != -1)
{
/* Now fill in the information about the new thread in
@ -663,6 +672,11 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
}
if (pid == 0)
{
/* Block cancel signal in the child until it is fully
initialized. */
sigemptyset(&newmask);
sigaddset(&newmask, __pthread_sig_cancel);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
#ifdef NEED_SEPARATE_REGISTER_STACK
pid = __clone2(pthread_start_thread,
(void **)new_thread_bottom,
@ -678,6 +692,8 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
__pthread_sig_cancel, new_thread);
#endif /* !NEED_SEPARATE_REGISTER_STACK */
saved_errno = errno;
sigprocmask(SIG_SETMASK, &oldmask, NULL);
}
/* Check if cloning succeeded */
if (pid == -1) {
@ -700,7 +716,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
__pthread_handles[sseg].h_descr = NULL;
__pthread_handles[sseg].h_bottom = NULL;
__pthread_handles_num--;
return errno;
return saved_errno;
}
/* Insert new thread in doubly linked list of active threads */
new_thread->p_prevlive = __pthread_main_thread;