From a86e3e5891c72314c8c5d64b56f12474c72c0563 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Mon, 26 Nov 2001 12:59:16 +0000 Subject: (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. --- linuxthreads/manager.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'linuxthreads/manager.c') diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c index 41f53f38ef..c8808197c1 100644 --- a/linuxthreads/manager.c +++ b/linuxthreads/manager.c @@ -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; -- cgit v1.2.3