diff options
-rw-r--r-- | linuxthreads/ChangeLog | 14 | ||||
-rw-r--r-- | linuxthreads/descr.h | 1 | ||||
-rw-r--r-- | linuxthreads/internals.h | 27 | ||||
-rw-r--r-- | linuxthreads/sighandler.c | 6 |
4 files changed, 46 insertions, 2 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 62d4df0f62..3385353bd4 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,17 @@ +2003-09-17 Jakub Jelinek <jakub@redhat.com> + + * pthread.c (manager_thread): Remove static, add attribute_hidden. + (thread_self_stack): Rename to... + (__pthread_self_stack): ... this. Remove static. + (pthread_handle_sigcancel): Use check_thread_self (). + (pthread_handle_sigrestart): Likewise. + * sighandler.c (__pthread_sighandler, __pthread_sighandler_rt): + Likewise. + * descr.h (manager_thread): Declare. + * internals.h (__pthread_self_stack): New prototype. + (__manager_thread): Define. + (check_thread_self): New function. + 2003-09-15 Jakub Jelinek <jakub@redhat.com> * Makefile (CFLAGS-mutex.c): Add $(uses-callbacks). diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h index f00278cb51..0b9efd220d 100644 --- a/linuxthreads/descr.h +++ b/linuxthreads/descr.h @@ -217,6 +217,7 @@ extern char *__pthread_manager_thread_tos; /* Descriptor of the manager thread */ extern struct _pthread_descr_struct __pthread_manager_thread; +extern pthread_descr manager_thread attribute_hidden; /* Indicate whether at least one thread has a user-defined stack (if 1), or all threads have stacks supplied by LinuxThreads (if 0). */ diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h index a5ec8b9284..90649335bb 100644 --- a/linuxthreads/internals.h +++ b/linuxthreads/internals.h @@ -363,6 +363,7 @@ extern int __pthread_condattr_init (pthread_condattr_t *attr); extern int __pthread_condattr_destroy (pthread_condattr_t *attr); extern pthread_t __pthread_self (void); extern pthread_descr __pthread_thread_self (void); +extern pthread_descr __pthread_self_stack (void) attribute_hidden; extern int __pthread_equal (pthread_t thread1, pthread_t thread2); extern void __pthread_exit (void *retval); extern int __pthread_getschedparam (pthread_t thread, int *policy, @@ -522,4 +523,30 @@ weak_extern (__pthread_thread_self) # endif #endif +#ifndef USE_TLS +# define __manager_thread (&__pthread_manager_thread) +#else +# define __manager_thread manager_thread +#endif + +extern inline __attribute__((always_inline)) pthread_descr +check_thread_self (void) +{ + pthread_descr self = thread_self (); +#if defined THREAD_SELF && defined INIT_THREAD_SELF + if (self == __manager_thread) + { + /* 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. */ + self = __pthread_self_stack(); + if (self != __manager_thread) + /* Oops, thread_self() isn't working yet.. */ + INIT_THREAD_SELF(self, self->p_nr); + } +#endif + return self; +} + #endif /* internals.h */ diff --git a/linuxthreads/sighandler.c b/linuxthreads/sighandler.c index ab8b38e539..9dd3e228f6 100644 --- a/linuxthreads/sighandler.c +++ b/linuxthreads/sighandler.c @@ -22,7 +22,8 @@ void __pthread_sighandler(int signo, SIGCONTEXT ctx) { pthread_descr self; char * in_sighandler; - self = thread_self(); + self = check_thread_self(); + /* If we're in a sigwait operation, just record the signal received and return without calling the user's handler */ if (THREAD_GETMEM(self, p_sigwaiting)) { @@ -46,7 +47,8 @@ void __pthread_sighandler_rt(int signo, struct siginfo *si, { pthread_descr self; char * in_sighandler; - self = thread_self(); + self = check_thread_self(); + /* If we're in a sigwait operation, just record the signal received and return without calling the user's handler */ if (THREAD_GETMEM(self, p_sigwaiting)) { |