From f92b4771baf8faccc197ae06922690d1cef74dad Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 12 Aug 1999 00:53:52 +0000 Subject: 1999-08-12 Ross Johnson * exit.c (pthread_exit): Check for implicitly created threads to avoid raising an unhandled exception. 1999-07-12 Ross Johnson * 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 1999-07-09 Ross Johnson The following changes fix a bug identified by Lorin Hochstein and solved by John Bossom . 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(). --- exit.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'exit.c') 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); } -- cgit v1.2.3