about summary refs log tree commit diff
path: root/nptl/pthreadP.h
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-12-13 10:59:14 +0000
committerUlrich Drepper <drepper@redhat.com>2002-12-13 10:59:14 +0000
commit9ae0909b35bc7ed04897536cbf224f7e134b5184 (patch)
treeaa669fa5f77206d19f065a05859b8c52032019ad /nptl/pthreadP.h
parentb9633fccd30c9cb390295ca0c43477f2bef986af (diff)
downloadglibc-9ae0909b35bc7ed04897536cbf224f7e134b5184.tar.gz
glibc-9ae0909b35bc7ed04897536cbf224f7e134b5184.tar.xz
glibc-9ae0909b35bc7ed04897536cbf224f7e134b5184.zip
Update.
2002-12-13  Ulrich Drepper  <drepper@redhat.com>

	* misc/syslog.c (log_cleanup): Don't use parameter in
	__libc_lock_unlock call, use syslog_lock directly.  Adjust callers to
	pass NULL instead of a pointer to syslog_lock.
Diffstat (limited to 'nptl/pthreadP.h')
-rw-r--r--nptl/pthreadP.h48
1 files changed, 43 insertions, 5 deletions
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 1813a04583..94f169c564 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -74,7 +74,7 @@ extern int __pthread_debug attribute_hidden;
     if (CANCEL_ENABLED_AND_CANCELED (cancelhandling))			      \
       {									      \
 	THREAD_SETMEM (self, result, PTHREAD_CANCELED);			      \
-	__do_cancel (CURRENT_STACK_FRAME);				      \
+	__do_cancel ();							      \
       }									      \
   } while (0)
 
@@ -85,9 +85,41 @@ extern int __pthread_debug attribute_hidden;
 #define CANCEL_RESET(oldtype) \
   __pthread_disable_asynccancel (oldtype)
 
-/* Function performing the cancellation.  */
-extern void __do_cancel (char *currentframe)
-     __attribute ((visibility ("hidden"), noreturn, regparm (1)));
+/* Same as CANCEL_ASYNC, but for use in libc.so.  */
+#define LIBC_CANCEL_ASYNC() \
+  __libc_enable_asynccancel ()
+/* Same as CANCEL_RESET, but for use in libc.so.  */
+#define LIBC_CANCEL_RESET(oldtype) \
+  __libc_disable_asynccancel (oldtype)
+
+
+/* This function is responsible for calling all registered cleanup
+   handlers and then terminate the thread.  This includes dellocating
+   the thread-specific data.  The implementation is complicated by the
+   fact that we have to handle to cancellation handler registration
+   methods: exceptions using try/finally and setjmp.
+
+   The setjmp method is always available.  The user might compile some
+   code which uses this method because no modern compiler is
+   available.  So we have to handle these first since we cannot call
+   the cleanup handlers if the stack frames are gone.  At the same
+   time this opens a hole for the register exception handler blocks
+   since now they might be in danger of using an overwritten stack
+   frame.  The advise is to only use new or only old style cancellation
+   handling.  */
+static inline void
+__do_cancel (void)
+{
+  struct pthread *self = THREAD_SELF;
+
+  /* Throw an exception.  */
+  // XXX TBI
+
+  /* If throwing an exception didn't work try the longjmp.  */
+  __libc_longjmp (self->cancelbuf, 1);
+
+  /* NOTREACHED */
+}
 
 
 /* Test whether stackframe is still active.  */
@@ -186,7 +218,13 @@ extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
 extern int __pthread_kill (pthread_t threadid, int signo);
 extern int __pthread_setcanceltype (int type, int *oldtype);
 extern int __pthread_enable_asynccancel (void) attribute_hidden;
-extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
+extern void __pthread_disable_asynccancel (int oldtype)
+     internal_function attribute_hidden;
+
+/* The two functions are in libc.so and not exported.  */
+extern int __libc_enable_asynccancel (void) attribute_hidden;
+extern void __libc_disable_asynccancel (int oldtype)
+     internal_function attribute_hidden;
 
 #ifdef IS_IN_libpthread
 /* Special versions which use non-exported functions.  */