diff options
Diffstat (limited to 'pthreads/ptw32_threadStart.c')
-rw-r--r-- | pthreads/ptw32_threadStart.c | 169 |
1 files changed, 71 insertions, 98 deletions
diff --git a/pthreads/ptw32_threadStart.c b/pthreads/ptw32_threadStart.c index cb08403b1..ffa0eb602 100644 --- a/pthreads/ptw32_threadStart.c +++ b/pthreads/ptw32_threadStart.c @@ -9,10 +9,11 @@ * * Pthreads-win32 - POSIX Threads Library for Win32 * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * + * Copyright(C) 1999,2012 Pthreads-win32 contributors + * + * Homepage1: http://sourceware.org/pthreads-win32/ + * Homepage2: http://sourceforge.net/projects/pthreads4w/ + * * The current list of contributors is contained * in the file CONTRIBUTORS included with the source * code distribution. The list can also be seen at the @@ -35,6 +36,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include "pthread.h" #include "implement.h" #include <stdio.h> @@ -59,7 +64,7 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) for (param = 0; param < numParams; param++) { - ei[param] = ep->ExceptionRecord->ExceptionInformation[param]; + ei[param] = (DWORD) ep->ExceptionRecord->ExceptionInformation[param]; } return EXCEPTION_EXECUTE_HANDLER; @@ -89,38 +94,32 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) #elif defined(__WATCOMC__) # include <eh.h> # include <exceptio.h> -typedef terminate_handler - terminate_function; #else # if defined(__GNUC__) && __GNUC__ < 3 # include <new.h> # else # include <new> using - std::terminate_handler; -using std::terminate; using std::set_terminate; # endif -typedef terminate_handler - terminate_function; #endif -static terminate_function - ptw32_oldTerminate; - -void -ptw32_terminate () -{ - set_terminate (ptw32_oldTerminate); - (void) pthread_win32_thread_detach_np (); - terminate (); -} +#endif /* __CLEANUP_CXX */ +/* + * MSVC6 does not optimize ptw32_threadStart() safely + * (i.e. tests/context1.c fails with "abnormal program + * termination" in some configurations), and there's no + * point to optimizing this routine anyway + */ +#ifdef _MSC_VER +# pragma optimize("g", off) +# pragma warning( disable : 4748 ) #endif -#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || (defined (__MSVCRT__) && ! defined (__DMC__)) +#if ! defined (PTW32_CONFIG_MINGW) || (defined (__MSVCRT__) && ! defined (__DMC__)) unsigned __stdcall #else @@ -131,7 +130,7 @@ ptw32_threadStart (void *vthreadParms) ThreadParms * threadParms = (ThreadParms *) vthreadParms; pthread_t self; ptw32_thread_t * sp; - void *(*start) (void *); + void * (PTW32_CDECL *start) (void *); void * arg; #if defined(__CLEANUP_SEH) @@ -153,7 +152,7 @@ ptw32_threadStart (void *vthreadParms) free (threadParms); -#if (defined(__MINGW64__) || defined(__MINGW32__)) && ! defined (__MSVCRT__) +#if defined (PTW32_CONFIG_MINGW) && ! defined (__MSVCRT__) /* * beginthread does not return the thread id and is running * before it returns us the thread handle, and so we do it here. @@ -194,19 +193,19 @@ ptw32_threadStart (void *vthreadParms) { switch (ei[0]) { - case PTW32_EPS_CANCEL: - status = sp->exitStatus = PTHREAD_CANCELED; + case PTW32_EPS_CANCEL: + status = sp->exitStatus = PTHREAD_CANCELED; #if defined(_UWIN) - if (--pthread_count <= 0) - exit (0); + if (--pthread_count <= 0) + exit (0); #endif - break; - case PTW32_EPS_EXIT: - status = sp->exitStatus; - break; - default: - status = sp->exitStatus = PTHREAD_CANCELED; - break; + break; + case PTW32_EPS_EXIT: + status = sp->exitStatus; + break; + default: + status = sp->exitStatus = PTHREAD_CANCELED; + break; } } @@ -218,7 +217,6 @@ ptw32_threadStart (void *vthreadParms) if (0 == setjmp_rc) { - /* * Run the caller's routine; */ @@ -228,64 +226,27 @@ ptw32_threadStart (void *vthreadParms) else { switch (setjmp_rc) - { - case PTW32_EPS_CANCEL: - status = sp->exitStatus = PTHREAD_CANCELED; - break; - case PTW32_EPS_EXIT: - status = sp->exitStatus; - break; - default: - status = sp->exitStatus = PTHREAD_CANCELED; - break; - } + { + case PTW32_EPS_CANCEL: + status = sp->exitStatus = PTHREAD_CANCELED; + break; + case PTW32_EPS_EXIT: + status = sp->exitStatus; + break; + default: + status = sp->exitStatus = PTHREAD_CANCELED; + break; + } } #else /* __CLEANUP_C */ #if defined(__CLEANUP_CXX) - ptw32_oldTerminate = set_terminate (&ptw32_terminate); - try { - /* - * 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. - */ - try - { - status = sp->exitStatus = (*start) (arg); - sp->state = PThreadStateExiting; - } - 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. - */ - terminate_function - term_func = set_terminate (0); - set_terminate (term_func); - - if (term_func != 0) - { - term_func (); - } - throw; - } + status = sp->exitStatus = (*start) (arg); + sp->state = PThreadStateExiting; } catch (ptw32_exception_cancel &) { @@ -304,16 +265,13 @@ ptw32_threadStart (void *vthreadParms) catch (...) { /* - * A system unexpected exception has occurred running the user's - * terminate routine. We get control back within this block - * and exit with a substitute status. If the thread was not - * cancelled then this indicates the unhandled exception. + * Some other exception occurred. Clean up while we have + * the opportunity, and call the terminate handler. */ - status = sp->exitStatus = PTHREAD_CANCELED; + (void) pthread_win32_thread_detach_np (); + terminate (); } - (void) set_terminate (ptw32_oldTerminate); - #else #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. @@ -326,7 +284,7 @@ ptw32_threadStart (void *vthreadParms) /* * We need to cleanup the pthread now if we have * been statically linked, in which case the cleanup - * in dllMain won't get done. Joinable threads will + * in DllMain won't get done. Joinable threads will * only be partially cleaned up and must be fully cleaned * up by pthread_join() or pthread_detach(). * @@ -334,13 +292,13 @@ ptw32_threadStart (void *vthreadParms) * implicitly created pthreads (those created * for Win32 threads which have called pthreads routines) * must be cleaned up explicitly by the application - * (by calling pthread_win32_thread_detach_np()). - * For the dll, dllMain will do the cleanup automatically. + * by calling pthread_exit(). + * For the dll, DllMain will do the cleanup automatically. */ (void) pthread_win32_thread_detach_np (); #endif -#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) +#if ! defined (PTW32_CONFIG_MINGW) || defined (__MSVCRT__) || defined (__DMC__) _endthreadex ((unsigned)(size_t) status); #else _endthread (); @@ -350,8 +308,23 @@ ptw32_threadStart (void *vthreadParms) * Never reached. */ -#if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__) +#if ! defined (PTW32_CONFIG_MINGW) || defined (__MSVCRT__) || defined (__DMC__) return (unsigned)(size_t) status; #endif } /* ptw32_threadStart */ + +/* + * Reset optimization + */ +#ifdef _MSC_VER +# pragma optimize("", on) +#endif + +#if defined (PTW32_USES_SEPARATE_CRT) && defined (__cplusplus) +ptw32_terminate_handler +pthread_win32_set_terminate_np(ptw32_terminate_handler termFunction) +{ + return set_terminate(termFunction); +} +#endif |