summaryrefslogtreecommitdiff
path: root/private.c
diff options
context:
space:
mode:
authorrpj <rpj>2000-12-28 05:32:07 +0000
committerrpj <rpj>2000-12-28 05:32:07 +0000
commitc94735ecdde19c4de652efd144faeec1a729b1e0 (patch)
tree1780c2bfe14e0b41931d85f6a5ed2f5e2695b6b2 /private.c
parent548fc29a8cc3fd016eba997facc9566af8fd2d75 (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.c157
1 files changed, 115 insertions, 42 deletions
diff --git a/private.c b/private.c
index 0e94d5f..977eb67 100644
--- a/private.c
+++ b/private.c
@@ -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 */