mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 13:00:06 +00:00
(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:
parent
dd09c3dcc9
commit
a86e3e5891
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user