summaryrefslogtreecommitdiff
path: root/exit.c
diff options
context:
space:
mode:
authorrpj <rpj>1999-08-12 00:53:52 +0000
committerrpj <rpj>1999-08-12 00:53:52 +0000
commitf92b4771baf8faccc197ae06922690d1cef74dad (patch)
tree8b06f29abbaf8d1cc027bab0731a9fe79db69413 /exit.c
parent77d0a6ff70ef2bb480c927e563340fc501ec0930 (diff)
1999-08-12 Ross Johnson <rpj@ixobrychus.canberra.edu.au>snap-1999-05-30-patches
* exit.c (pthread_exit): Check for implicitly created threads to avoid raising an unhandled exception. 1999-07-12 Ross Johnson <rpj@ixobrychus.canberra.edu.au> * condvar.c (pthread_cond_destroy): Add critical section. (cond_timedwait): Add critical section; check for timeout waiting on semaphore. (pthread_cond_broadcast): Add critical section. - Peter Slacik <Peter.Slacik@tatramed.sk> 1999-07-09 Ross Johnson <rpj@ixobrychus.canberra.edu.au> The following changes fix a bug identified by Lorin Hochstein <lmh@xiphos.ca> and solved by John Bossom <John.Bossom@Cognos.COM>. The problem was that cleanup handlers were not executed when pthread_exit() was called. * implement.h (pthread_t_): Add exceptionInformation element for C++ per-thread exception information. (general): Define and rename exceptions. * misc.c (CancelableWait): _PTHREAD_EPS_CANCEL (SEH) and Pthread_exception_cancel (C++) used to identify the exception. * cancel.c (pthread_testcancel): _PTHREAD_EPS_CANCEL (SEH) and Pthread_exception_cancel (C++) used to identify the exception. * exit.c (pthread_exit): throw/raise an exception to return to _pthread_threadStart() to exit the thread. _PTHREAD_EPS_EXIT (SEH) and Pthread_exception_exit (C++) used to identify the exception. * private.c (_pthread_threadStart): Add pthread_exit exception trap; clean up and exit the thread directly rather than via pthread_exit().
Diffstat (limited to 'exit.c')
-rw-r--r--exit.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/exit.c b/exit.c
index 46c2b3f..5035718 100644
--- a/exit.c
+++ b/exit.c
@@ -51,7 +51,60 @@ pthread_exit (void *value_ptr)
* ------------------------------------------------------
*/
{
- _pthread_callUserDestroyRoutines((pthread_t) pthread_getspecific(_pthread_selfThreadKey));
+ pthread_t self = pthread_self();
+
+ /* If the current thread is implicit it was not started through
+ pthread_create(), therefore we cleanup and end the thread
+ here. Otherwise we raise an exception to unwind the exception
+ stack. The exception will be caught by _pthread_threadStart(),
+ which will cleanup and end the thread for us.
+ */
+
+ if (self->implicit)
+ {
+ _pthread_callUserDestroyRoutines(self);
+
+ _endthreadex ((unsigned) value_ptr);
+
+ /* Never reached */
+ }
+ else
+ {
+#ifdef _MSC_VER
+
+ DWORD exceptionInformation[3];
+
+ exceptionInformation[0] = (DWORD) (_PTHREAD_EPS_EXIT);
+ exceptionInformation[1] = (DWORD) (value_ptr);
+ exceptionInformation[2] = (DWORD) (0);
+
+ RaiseException (
+ EXCEPTION_PTHREAD_SERVICES,
+ 0,
+ 3,
+ exceptionInformation);
+
+#else /* ! _MSC_VER */
+
+#ifdef __cplusplus
+
+ self->exceptionInformation = value_ptr;
+ throw Pthread_exception_exit();
+
+#else /* ! __cplusplus */
+
+ (void) pthread_pop_cleanup( 1 );
+
+ _pthread_callUserDestroyRoutines(self);
+
+ _endthreadex ((unsigned) value_ptr);
+
+#endif /* __cplusplus */
+
+#endif /* _MSC_VER */
+
+ }
+
+ /* Never reached. */
- _endthreadex ((unsigned) value_ptr);
}