diff options
-rw-r--r-- | linuxthreads/ChangeLog | 12 | ||||
-rw-r--r-- | linuxthreads/manager.c | 13 | ||||
-rw-r--r-- | linuxthreads/pthread.c | 39 |
3 files changed, 47 insertions, 17 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index e9be46bd1e..438fd1a193 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,13 @@ +2001-11-30 Andreas Schwab <schwab@suse.de> + + * pthread.c (pthread_handle_sigcancel) [THREAD_SELF]: Double check + that self is the manager thread, and initialize the thread + register if not. + (thread_self_stack) [THREAD_SELF]: New function to find self via + stack pointer. + * manager.c (pthread_handle_create): Don't block cancel signal any + more. + 2001-11-29 Andreas Jaeger <aj@suse.de> * sysdeps/x86_64/pt-machine.h: Use %gs as thread specific @@ -5,7 +15,7 @@ (THREAD_SELF): New. (INIT_THREAD_SELF): New. (THREAD_GETMEM): New. - (THREAD_GETMEM_NC): + (THREAD_GETMEM_NC): (THREAD_SETMEM): New. (THREAD_SETMEM_NC): New. (FLOATING_STACKS): Define. diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c index b1a4542d69..9e4fcacb48 100644 --- a/linuxthreads/manager.c +++ b/linuxthreads/manager.c @@ -534,7 +534,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, 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 @@ -620,11 +619,6 @@ 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); @@ -653,7 +647,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, __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 @@ -679,11 +672,6 @@ 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, @@ -700,7 +688,6 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, __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) { diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c index 81261416e2..1a2888f3c6 100644 --- a/linuxthreads/pthread.c +++ b/linuxthreads/pthread.c @@ -709,7 +709,7 @@ int pthread_equal(pthread_t thread1, pthread_t thread2) #ifndef THREAD_SELF -pthread_descr __pthread_find_self() +pthread_descr __pthread_find_self(void) { char * sp = CURRENT_STACK_FRAME; pthread_handle h; @@ -721,6 +721,21 @@ pthread_descr __pthread_find_self() return h->h_descr; } +#else + +static pthread_descr thread_self_stack(void) +{ + char *sp = CURRENT_STACK_FRAME; + pthread_handle h; + + if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos) + return &__pthread_manager_thread; + h = __pthread_handles + 2; + while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) + h++; + return h->h_descr; +} + #endif /* Thread scheduling */ @@ -769,7 +784,7 @@ int pthread_getschedparam(pthread_t thread, int *policy, return 0; } -int __pthread_yield () +int __pthread_yield (void) { /* For now this is equivalent with the POSIX call. */ return sched_yield (); @@ -841,8 +856,26 @@ static void pthread_handle_sigcancel(int sig) if (self == &__pthread_manager_thread) { +#ifdef THREAD_SELF + /* A new thread might get a cancel signal before it is fully + initialized, so that the thread register might still point to the + manager thread. Double check that this is really the manager + thread. */ + pthread_descr real_self = thread_self_stack(); + if (real_self == &__pthread_manager_thread) + { + __pthread_manager_sighandler(sig); + return; + } + /* Oops, thread_self() isn't working yet.. */ + self = real_self; +# ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(self, self->p_nr); +# endif +#else __pthread_manager_sighandler(sig); return; +#endif } if (__builtin_expect (__pthread_exit_requested, 0)) { /* Main thread should accumulate times for thread manager and its @@ -884,7 +917,7 @@ static void pthread_handle_sigdebug(int sig) Notice that we can't free the stack segments, as the forked thread may hold pointers into them. */ -void __pthread_reset_main_thread() +void __pthread_reset_main_thread(void) { pthread_descr self = thread_self(); struct rlimit limit; |