about summary refs log tree commit diff
path: root/linuxthreads/pthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/pthread.c')
-rw-r--r--linuxthreads/pthread.c39
1 files changed, 36 insertions, 3 deletions
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;