aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog14
-rw-r--r--linuxthreads/descr.h1
-rw-r--r--linuxthreads/internals.h27
-rw-r--r--linuxthreads/sighandler.c6
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)) {