diff options
author | rpj <rpj> | 2001-05-31 02:01:47 +0000 |
---|---|---|
committer | rpj <rpj> | 2001-05-31 02:01:47 +0000 |
commit | e121b938c9f012958196a3141f04a3fd4f58bdb9 (patch) | |
tree | d1cb950413e3a350606f2a4d9bea687b6680570d /private.c | |
parent | 6bf07e836550f9ffe11e0f38ff1323be731eb250 (diff) |
2001-05-30 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
* pthread.h (rand_r): Fake using _seed argument to quell
compiler warning (compiler should optimise this away later).
* GNUmakefile (OPT): Leave symbolic information out of the library
and increase optimisation level - for smaller faster prebuilt
dlls.
2001-05-29 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
Contributed by - Milan Gardian <Milan.Gardian@LEIBINGER.com>
* Makefile: fix typo.
* pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
remove the need for PT_STDCALL everywhere; remove warning supression.
* (errno): Fix the longstanding "inconsistent dll linkage" problem
with errno; now also works with /MD debugging libs -
warnings emerged when compiling pthreads library with /MD (or /MDd)
compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
using Multithreaded DLL CRT instead of Multithreaded statically linked
CRT).
* create.c (pthread_create): Likewise; fix typo.
* private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
throw exceptions.
* Remove unnecessary #includes from a number of modules -
[I had to #include malloc.h in implement.h for gcc - rpj].
2001-05-29 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
Contributed by - Thomas Pfaff <tpfaff@gmx.net>
* pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
PTHREAD_MUTEX_DEFAULT_NP.
* (PTHREAD_MUTEX_NORMAL): Similarly.
* (PTHREAD_MUTEX_ERRORCHECK): Similarly.
* (PTHREAD_MUTEX_RECURSIVE): Similarly.
* (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
for pthread_mutexattr_settype.
* (pthread_mutexattr_getkind_np): New; Linux compatibility stub
for pthread_mutexattr_gettype.
* mutex.c (pthread_mutexattr_settype): New; allow
the following types of mutex:
PTHREAD_MUTEX_DEFAULT_NP
PTHREAD_MUTEX_NORMAL_NP
PTHREAD_MUTEX_ERRORCHECK_NP
PTHREAD_MUTEX_RECURSIVE_NP
* Note that PTHREAD_MUTEX_DEFAULT is equivalent to
PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
be recursive by default, and a thread will deadlock if it
tries to relock a mutex it already owns. This is inline with
other pthreads implementations.
* (pthread_mutex_lock): Process the lock request
according to the mutex type.
* (pthread_mutex_init): Eliminate use of Win32 mutexes as the
basis of POSIX mutexes - instead, a combination of one critical section
and one semaphore are used in conjunction with Win32 Interlocked* routines.
* (pthread_mutex_destroy): Likewise.
* (pthread_mutex_lock): Likewise.
* (pthread_mutex_trylock): Likewise.
* (pthread_mutex_unlock): Likewise.
* Use longjmp/setjmp to implement cancelation when building the library
using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
that gcc -x c++ uses exceptions).
* Also fixed some of the same typos and eliminated PT_STDCALL as
Milan Gardian's patches above.
2001-02-07 Ross Johnson <rpj@special.ise.canberra.edu.au>
Contributed by - Alexander Terekhov <TEREKHOV@de.ibm.com>
* rwlock.c: Revamped.
* implement.h (pthread_rwlock_t_): Redefined.
This implementation does not have reader/writer starvation problem.
Rwlock attempts to behave more like a normal mutex with
races and scheduling policy determining who is more important;
It also supports recursive locking,
has less synchronization overhead (no broadcasts at all,
readers are not blocked on any condition variable) and seem to
be faster than the current implementation [W98 appears to be
approximately 15 percent faster at least - on top of speed increase
from Thomas Pfaff's changes to mutex.c - rpj].
Diffstat (limited to 'private.c')
-rw-r--r-- | private.c | 151 |
1 files changed, 106 insertions, 45 deletions
@@ -24,12 +24,7 @@ * MA 02111-1307, USA */ -#if !defined(_MSC_VER) && !defined(__cplusplus) && defined(__GNUC__) - -#warning Compile __FILE__ as C++ or thread cancellation will not work properly. - -#endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ - +#include <process.h> #ifndef NEED_FTIME #include <sys/timeb.h> #endif @@ -154,7 +149,7 @@ ptw32_processTerminate (void) } /* processTerminate */ -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH static DWORD ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) @@ -194,7 +189,7 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) } } -#elif defined(__cplusplus) +#elif defined(__CLEANUP_CXX) #if defined(_MSC_VER) #include <eh.h> @@ -230,20 +225,25 @@ ptw32_terminate () #endif /* _MSC_VER */ #if ! defined (__MINGW32__) || defined (__MSVCRT__) -unsigned PT_STDCALL +unsigned __stdcall #else void #endif -ptw32_threadStart (ThreadParms * threadParms) +ptw32_threadStart (void * vthreadParms) { + ThreadParms *threadParms = (ThreadParms *) vthreadParms; pthread_t self; void *(*start) (void *); void *arg; -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH DWORD ei[] = {0,0,0}; #endif +#ifdef __CLEANUP_C + int setjmp_rc; +#endif + void * status = (void *) 0; self = threadParms->tid; @@ -270,7 +270,7 @@ ptw32_threadStart (ThreadParms * threadParms) pthread_setspecific (ptw32_selfThreadKey, self); -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH __try { @@ -295,9 +295,39 @@ ptw32_threadStart (ThreadParms * threadParms) } } -#else /* _MSC_VER && !__cplusplus */ +#else /* __CLEANUP_SEH */ -#ifdef __cplusplus +#ifdef __CLEANUP_C + + setjmp_rc = setjmp( self->start_mark ); + + if( 0 == setjmp_rc ) { + + /* + * Run the caller's routine; + */ + status = self->exitStatus = (*start) (arg); + } + + else { + + switch (setjmp_rc) + { + case PTW32_EPS_CANCEL: + status = PTHREAD_CANCELED; + break; + case PTW32_EPS_EXIT: + status = self->exitStatus; + break; + default: + status = PTHREAD_CANCELED; + break; + } + } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX ptw32_oldTerminate = set_terminate(&ptw32_terminate); @@ -328,7 +358,30 @@ ptw32_threadStart (ThreadParms * threadParms) * * ptw32_terminate() will be called if there is no user supplied function. */ - (void) terminate(); + + //Original invocation: + //(void) terminate(); + + + //New invocation: + // a) get pointer to the termination function +#if defined(_MSC_VER) + terminate_function term_func = set_terminate(0); +#else + terminate_handler term_func = set_terminate(0); +#endif + + set_terminate(term_func); + + // b) call the termination function (if any) + if (term_func != 0) { + term_func(); + } + + // c) if there was no termination function or the termination function did + // not exit thread/process, (we got this far), propagate the exception on! + // (should be caught by the second level try/catch block below) + throw; } } catch (ptw32_exception_cancel &) @@ -365,17 +418,14 @@ ptw32_threadStart (ThreadParms * threadParms) (void) set_terminate(ptw32_oldTerminate); -#else /* __cplusplus */ +#else - /* - * Run the caller's routine; no cancelation or other exceptions will - * be honoured. - */ - status = self->exitStatus = (*start) (arg); +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. -#endif /* __cplusplus */ +#endif /* __CLEANUP_CXX */ +#endif /* __CLEANUP_C */ +#endif /* __CLEANUP_SEH */ -#endif /* _MSC_VER */ (void) pthread_mutex_destroy(&self->cancelLock); @@ -637,19 +687,6 @@ ptw32_callUserDestroyRoutines (pthread_t thread) if (value != NULL && k->destructor != NULL) { -#if defined(_MSC_VER) && !defined(__cplusplus) - - /* - * Run the caller's cleanup routine. - * - * If an exception occurs we let the system handle it - * as an unhandled exception. Since we are leaving the - * thread we should not get any internal pthreads - * exceptions. - */ - (*(k->destructor)) (value); - -#else /* _MSC_VER && !__cplusplus */ #ifdef __cplusplus try @@ -681,7 +718,6 @@ ptw32_callUserDestroyRoutines (pthread_t thread) (*(k->destructor)) (value); #endif /* __cplusplus */ -#endif /* _MSC_VER */ } } @@ -895,7 +931,7 @@ ptw32_sem_timedwait (sem_t * sem, const struct timespec * abstime) DWORD ptw32_get_exception_services_code(void) { -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH return EXCEPTION_PTW32_SERVICES; @@ -910,10 +946,13 @@ ptw32_get_exception_services_code(void) void ptw32_throw(DWORD exception) { -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_C + pthread_t self = pthread_self(); +#endif - DWORD exceptionInformation[3]; +#ifdef __CLEANUP_SEH + DWORD exceptionInformation[3]; #endif if (exception != PTW32_EPS_CANCEL && @@ -923,7 +962,8 @@ ptw32_throw(DWORD exception) exit(1); } -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH + exceptionInformation[0] = (DWORD) (exception); exceptionInformation[1] = (DWORD) (0); @@ -935,9 +975,17 @@ ptw32_throw(DWORD exception) 3, exceptionInformation); -#else /* _MSC_VER && ! __cplusplus */ +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C -# ifdef __cplusplus + ptw32_pop_cleanup_all( 1 ); + + longjmp( self->start_mark, exception ); + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX switch (exception) { @@ -949,9 +997,22 @@ ptw32_throw(DWORD exception) break; } -# endif /* __cplusplus */ +#else -#endif /* _MSC_VER && ! __cplusplus */ +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ /* Never reached */ } + +void +ptw32_pop_cleanup_all(int execute) +{ + while( NULL != ptw32_pop_cleanup(execute) ) { + } +} |