diff options
author | rpj <rpj> | 2000-12-28 05:32:07 +0000 |
---|---|---|
committer | rpj <rpj> | 2000-12-28 05:32:07 +0000 |
commit | c94735ecdde19c4de652efd144faeec1a729b1e0 (patch) | |
tree | 1780c2bfe14e0b41931d85f6a5ed2f5e2695b6b2 /private.c | |
parent | 548fc29a8cc3fd016eba997facc9566af8fd2d75 (diff) |
./ChangeLog:
2000-12-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
* private.c (ptw32_threadStart): Unhandled exceptions are
now passed through to the system to deal with. This is consistent
with normal Windows behaviour. C++ applications may use
set_terminate() to override the default behaviour which is
to call ptw32_terminate(). Ptw32_terminate() cleans up some
POSIX thread stuff before calling the system default function
which calls abort(). The users termination function should conform
to standard C++ semantics which is to not return. It should
exit the thread (call pthread_exit()) or exit the application.
* private.c (ptw32_terminate): Added as the default set_terminate()
function. It calls the system default function after cleaning up
some POSIX thread stuff.
* implement.h (ptw32_try_enter_critical_section): Move
declaration.
* global.c (ptw32_try_enter_critical_section): Moved
from dll.c.
* dll.c: Move process and thread attach/detach code into
functions in nonportable.c.
* nonportable.c (pthread_win32_process_attach_np): Process
attach code from dll.c is now available to static linked
applications.
* nonportable.c (pthread_win32_process_detach_np): Likewise.
* nonportable.c (pthread_win32_thread_attach_np): Likewise.
* nonportable.c (pthread_win32_thread_detach_np): Likewise.
* pthread.h: Add new non-portable prototypes for static
linked applications.
* GNUmakefile (OPT): Increase optimisation flag and remove
debug info flag.
* pthread.def: Add new non-portable exports for static
linked applications.
2000-12-11 Ross Johnson <rpj@special.ise.canberra.edu.au>
* FAQ: Update Answer 6 re getting a fully working
Mingw32 built library.
2000-09-09 Ross Johnson <rpj@special.ise.canberra.edu.au>
* pthread.h (ctime_r): Fix arg.
./tests/ChangeLog:
2000-12-28 Ross Johnson <rpj@special.ise.canberra.edu.au>
* eyal1.c: Increase thread work loads.
* exception2.c: New test.
* exception3.c: New test.
* Makefile: Add new tests exception2.c and exception3.c.
* GNUmakefile: Likewise.
2000-12-11 Ross Johnson <rpj@special.ise.canberra.edu.au>
* cleanup3.c: Remove unused variable.
* cleanup2.c: Likewise.
* exception1.c: Throw an exception rather than use
a deliberate zero divide so that catch(...) will
handle it under Mingw32. Mingw32 now builds the
library correctly to pass all tests - see Thomas
Pfaff's detailed instructions re needed changes
to Mingw32 in the Pthreads-Win32 FAQ.
Diffstat (limited to 'private.c')
-rw-r--r-- | private.c | 157 |
1 files changed, 115 insertions, 42 deletions
@@ -154,22 +154,77 @@ ptw32_processTerminate (void) } /* processTerminate */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__cplusplus) static DWORD ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) { - DWORD param; - DWORD numParams = ep->ExceptionRecord->NumberParameters; - - numParams = (numParams > 3) ? 3 : numParams; - - for (param = 0; param < numParams; param++) + switch (ep->ExceptionRecord->ExceptionCode) { - ei[param] = ep->ExceptionRecord->ExceptionInformation[param]; + case EXCEPTION_PTW32_SERVICES: + { + DWORD param; + DWORD numParams = ep->ExceptionRecord->NumberParameters; + + numParams = (numParams > 3) ? 3 : numParams; + + for (param = 0; param < numParams; param++) + { + ei[param] = ep->ExceptionRecord->ExceptionInformation[param]; + } + + return EXCEPTION_EXECUTE_HANDLER; + break; + } + default: + { + /* + * A system unexpected exception has occurred running the user's + * routine. We need to cleanup before letting the exception + * out of thread scope. + */ + pthread_t self = pthread_self(); + + (void) pthread_mutex_destroy(&self->cancelLock); + ptw32_callUserDestroyRoutines(self); + + return EXCEPTION_CONTINUE_SEARCH; + break; + } } +} + +#elif defined(__cplusplus) + +#if defined(_MSC_VER) +#include <eh.h> +static terminate_function ptw32_oldTerminate; +#else +#include <new.h> +static terminate_handler ptw32_oldTerminate; +#endif - return EXCEPTION_EXECUTE_HANDLER; +#if 0 +#include <stdio.h> +static pthread_mutex_t termLock = PTHREAD_MUTEX_INITIALIZER; +#endif + +void +ptw32_terminate () +{ + pthread_t self = pthread_self(); +#if 0 + FILE * fp; + pthread_mutex_lock(&termLock); + fp = fopen("pthread.log", "a"); + fprintf(fp, "Terminate\n"); + fclose(fp); + pthread_mutex_unlock(&termLock); +#endif + set_terminate(ptw32_oldTerminate); + (void) pthread_mutex_destroy(&self->cancelLock); + ptw32_callUserDestroyRoutines(self); + terminate(); } #endif /* _MSC_VER */ @@ -189,7 +244,7 @@ ptw32_threadStart (ThreadParms * threadParms) DWORD ei[] = {0,0,0}; #endif - void * status; + void * status = (void *) 0; self = threadParms->tid; start = threadParms->start; @@ -226,53 +281,64 @@ ptw32_threadStart (ThreadParms * threadParms) } __except (ExceptionFilter(GetExceptionInformation(), ei)) { - DWORD ec = GetExceptionCode(); - - if (ec == EXCEPTION_PTW32_SERVICES) - { - switch (ei[0]) - { - case PTW32_EPS_CANCEL: - status = PTHREAD_CANCELED; - break; - case PTW32_EPS_EXIT: - status = self->exitStatus; - break; - default: - status = PTHREAD_CANCELED; + switch (ei[0]) + { + case PTW32_EPS_CANCEL: + status = PTHREAD_CANCELED; break; - } - } - else - { - /* - * A system unexpected exception had occurred running the user's - * routine. We get control back within this block because - * we can't allow the exception to pass out of thread scope. - */ - status = PTHREAD_CANCELED; - } + case PTW32_EPS_EXIT: + status = self->exitStatus; + break; + default: + status = PTHREAD_CANCELED; + break; + } } #else /* _MSC_VER && !__cplusplus */ #ifdef __cplusplus + ptw32_oldTerminate = set_terminate(&ptw32_terminate); + try { /* - * Run the caller's routine; + * Run the caller's routine in a nested try block so that we + * can run the user's terminate function, which may call + * pthread_exit() or be canceled. */ - status = self->exitStatus = (*start) (arg); + try + { + status = self->exitStatus = (*start) (arg); + } + catch (ptw32_exception &) + { + /* + * Pass these through to the outer block. + */ + throw; + } + catch(...) + { + /* + * We want to run the user's terminate function if supplied. + * That function may call pthread_exit() or be canceled, which will + * be handled by the outer try block. + * + * ptw32_terminate() will be called if there is no user supplied function. + */ + (void) terminate(); + } } - catch (ptw32_exception_cancel) + catch (ptw32_exception_cancel &) { /* * Thread was cancelled. */ status = self->exitStatus = PTHREAD_CANCELED; } - catch (ptw32_exception_exit) + catch (ptw32_exception_exit &) { /* * Thread was exited via pthread_exit(). @@ -282,11 +348,18 @@ ptw32_threadStart (ThreadParms * threadParms) catch (...) { /* - * A system unexpected exception had occurred running the user's - * routine. We get control back within this block because - * we can't allow the exception out of thread scope. + * A system unexpected exception has occurred running the user's + * terminate routine. We get control back within this block - cleanup + * and release the exception out of thread scope. */ status = self->exitStatus = PTHREAD_CANCELED; + (void) pthread_mutex_destroy(&self->cancelLock); + ptw32_callUserDestroyRoutines(self); + throw; + + /* + * Never reached. + */ } #else /* __cplusplus */ |