From 6237335fec273ac2b00c32609a8eef91c6ec7473 Mon Sep 17 00:00:00 2001 From: rpj Date: Sat, 23 Jan 1999 06:58:47 +0000 Subject: Fixing problems building with GNU compilers: Sun Jan 24 01:34:52 1999 Ross Johnson * semaphore.c (sem_wait): Remove second arg to pthreadCancelableWait() call. Fri Jan 22 14:31:59 1999 Ross Johnson * Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed with egcs. Add -g for debugging. * create.c (pthread_create): Replace __stdcall with PT_STDCALL macro. This is a hack and must be fixed. * misc.c (CancelableWait): Remove redundant statement. * mutex.c (pthread_mutexattr_init): Cast calloc return value. * misc.c (CancelableWait): Add cast. (pthread_self): Add cast. * exit.c (pthread_exit): Add cast. * condvar.c (pthread_condattr_init): Cast calloc return value. * cleanup.c: Reorganise conditional compilation. * attr.c (pthread_attr_init): Remove unused 'result'. Cast malloc return value. * private.c (_pthread_callUserDestroyRoutines): Redo conditional compilation. * misc.c (CancelableWait): C++ version uses 'throw'. * cancel.c (pthread_testcancel): Ditto. * implement.h (class pthread_exception): Define for C++. * pthread.h: Fix C, C++, and Win32 SEH condition compilation mayhem around pthread_cleanup_* defines. C++ version now uses John Bossom's cleanup handlers. (pthread_attr_t): Make 'valid' unsigned. Define '_timeb' as 'timeb' for Ming32. Define PT_STDCALL as nothing for Mingw32. May be temporary. * cancel.c (pthread_testcancel): Cast return value. --- ChangeLog | 49 ++++++++++++++++++++ Makefile.in | 6 ++- attr.c | 3 +- cancel.c | 17 ++++++- cleanup.c | 20 ++++---- condvar.c | 2 +- create.c | 2 +- dll.c | 4 +- exit.c | 2 +- global.c | 6 +++ implement.h | 16 +++++++ misc.c | 23 +++++++-- mutex.c | 2 +- private.c | 62 ++++++++++++++++++++----- pthread.def | 17 +++++-- pthread.h | 152 +++++++++++++++++++++++++++++++++++++++++++----------------- semaphore.c | 2 +- tsd.c | 2 +- 18 files changed, 304 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index f20c90f..b12ecd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,59 @@ +Sun Jan 24 01:34:52 1999 Ross Johnson + + * semaphore.c (sem_wait): Remove second arg to + pthreadCancelableWait() call. + Sat Jan 23 17:36:40 1999 Ross Johnson + * pthread.def: Add new functions to export list. + * pthread.h (PTHREAD_MUTEX_AUTO_CS_NP): New. (PTHREAD_MUTEX_FORCE_CS_NP): New. * README: Updated. +Fri Jan 22 14:31:59 1999 Ross Johnson + + * Makefile.in (CFLAGS): Remove -fhandle-exceptions. Not needed + with egcs. Add -g for debugging. + + * create.c (pthread_create): Replace __stdcall with PT_STDCALL + macro. This is a hack and must be fixed. + + * misc.c (CancelableWait): Remove redundant statement. + + * mutex.c (pthread_mutexattr_init): Cast calloc return value. + + * misc.c (CancelableWait): Add cast. + (pthread_self): Add cast. + + * exit.c (pthread_exit): Add cast. + + * condvar.c (pthread_condattr_init): Cast calloc return value. + + * cleanup.c: Reorganise conditional compilation. + + * attr.c (pthread_attr_init): Remove unused 'result'. + Cast malloc return value. + + * private.c (_pthread_callUserDestroyRoutines): Redo conditional + compilation. + + * misc.c (CancelableWait): C++ version uses 'throw'. + + * cancel.c (pthread_testcancel): Ditto. + + * implement.h (class pthread_exception): Define for C++. + + * pthread.h: Fix C, C++, and Win32 SEH condition compilation + mayhem around pthread_cleanup_* defines. C++ version now uses John + Bossom's cleanup handlers. + (pthread_attr_t): Make 'valid' unsigned. + Define '_timeb' as 'timeb' for Ming32. + Define PT_STDCALL as nothing for Mingw32. May be temporary. + + * cancel.c (pthread_testcancel): Cast return value. + Wed Jan 20 09:31:28 1999 Ross Johnson * pthread.h (pthread_mutexattr_t): Changed to a pointer. diff --git a/Makefile.in b/Makefile.in index 89c72fe..a5dea55 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,6 +1,10 @@ CC = g++ -CFLAGS = -fhandle-exceptions -I. -DHAVE_CONFIG_H -Wall +# Mingw32 +CFLAGS = -g -I. -DHAVE_CONFIG_H -Wall + +# Cygwin G++ +#CFLAGS = -fhandle-exceptions -I. -DHAVE_CONFIG_H -Wall OBJS = attr.o cancel.o cleanup.o condvar.o create.o dll.o \ exit.o fork.o global.o misc.o mutex.o private.o sched.o \ diff --git a/attr.c b/attr.c index 3ec1d12..e0778ac 100644 --- a/attr.c +++ b/attr.c @@ -292,7 +292,6 @@ pthread_attr_init(pthread_attr_t *attr) */ { pthread_attr_t attr_result; - int result = 0; if (attr == NULL) { @@ -300,7 +299,7 @@ pthread_attr_init(pthread_attr_t *attr) return EINVAL; } - attr_result = malloc (sizeof (*attr_result)); + attr_result = (pthread_attr_t) malloc (sizeof (*attr_result)); if (attr_result == NULL) { diff --git a/cancel.c b/cancel.c index 93d6e07..5b7ff1a 100644 --- a/cancel.c +++ b/cancel.c @@ -163,7 +163,8 @@ pthread_testcancel (void) { pthread_t self; - if ((self = pthread_getspecific (_pthread_selfThreadKey)) != NULL) + if ((self = (pthread_t) pthread_getspecific (_pthread_selfThreadKey)) + != NULL) { if (self->cancelState == PTHREAD_CANCEL_ENABLE) @@ -175,6 +176,9 @@ pthread_testcancel (void) /* * Canceling! */ + +#ifdef _MSC_VER + DWORD exceptionInformation[3]; exceptionInformation[0] = (DWORD) (0); @@ -185,6 +189,17 @@ pthread_testcancel (void) 0, 3, exceptionInformation); + +#else /* _MSC_VER */ + +#ifdef __cplusplus + + throw pthread_exception; + +#endif /* __cplusplus */ + +#endif /* _MSC_VER */ + } } } diff --git a/cleanup.c b/cleanup.c index 199101b..3a1613c 100644 --- a/cleanup.c +++ b/cleanup.c @@ -44,14 +44,14 @@ _pthread_pop_cleanup (int execute) { _pthread_cleanup_t *cleanup; - cleanup = pthread_getspecific (_pthread_cleanupKey); + cleanup = (_pthread_cleanup_t *) pthread_getspecific (_pthread_cleanupKey); if (cleanup != NULL) { if (execute && (cleanup->routine != NULL)) { -#ifdef _WIN32 +#ifdef _MSC_VER __try { @@ -69,7 +69,7 @@ _pthread_pop_cleanup (int execute) */ } -#else /* _WIN32 */ +#else /* _MSC_VER */ #ifdef __cplusplus @@ -91,7 +91,7 @@ _pthread_pop_cleanup (int execute) #else /* __cplusplus */ -#if defined(__CYGWIN__) || defined(__CYGWIN32__) +#if defined(__GNUC__) #warning Compile __FILE__ as C++ or thread cancellation will not work properly. #endif @@ -102,15 +102,16 @@ _pthread_pop_cleanup (int execute) #endif /* __cplusplus */ -#endif /* _WIN32 */ +#endif /* _MSC_VER */ } -#if !defined(_WIN32) && !defined(__cplusplus) +#if !defined(_MSC_VER) && !defined(__cplusplus) - pthread_setspecific (_pthread_cleanupKey, cleanup->prev); + pthread_setspecific (_pthread_cleanupKey, (void *) cleanup->prev); #endif + } return (cleanup); @@ -165,9 +166,9 @@ _pthread_push_cleanup (_pthread_cleanup_t * cleanup, cleanup->routine = routine; cleanup->arg = arg; -#if !defined(_WIN32) && !defined(__cplusplus) +#if !defined(_MSC_VER) && !defined(__cplusplus) - cleanup->prev = pthread_getspecific (_pthread_cleanupKey); + cleanup->prev = (_pthread_cleanup_t *) pthread_getspecific (_pthread_cleanupKey); #endif @@ -177,4 +178,3 @@ _pthread_push_cleanup (_pthread_cleanup_t * cleanup, /* */ - diff --git a/condvar.c b/condvar.c index f55fefa..37d92e6 100644 --- a/condvar.c +++ b/condvar.c @@ -48,7 +48,7 @@ pthread_condattr_init (pthread_condattr_t * attr) pthread_condattr_t attr_result; int result = 0; - attr_result = calloc (1, sizeof (*attr_result)); + attr_result = (pthread_condattr_t) calloc (1, sizeof (*attr_result)); if (attr_result == NULL) { diff --git a/create.c b/create.c index 37e1c61..c017b61 100644 --- a/create.c +++ b/create.c @@ -108,7 +108,7 @@ pthread_create (pthread_t * tid, _beginthreadex ( (void *) NULL, /* No security info */ (unsigned) stackSize, /* default stack size */ - (unsigned (__stdcall *) (void *)) _pthread_threadStart, + (unsigned (PT_STDCALL *) (void *)) _pthread_threadStart, parms, (unsigned) run ? 0 : CREATE_SUSPENDED, (unsigned *) &(thread->thread)); diff --git a/dll.c b/dll.c index f2b3505..7ebfd5e 100644 --- a/dll.c +++ b/dll.c @@ -50,8 +50,8 @@ DllMain ( /* Load KERNEL32 and try to get address of TryEnterCriticalSection */ _pthread_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); _pthread_try_enter_critical_section = - (void *) GetProcAddress(_pthread_h_kernel32, - "TryEnterCriticalSection"); + GetProcAddress(_pthread_h_kernel32, + (LPCSTR) "TryEnterCriticalSection"); break; case DLL_THREAD_ATTACH: diff --git a/exit.c b/exit.c index 5177e88..2d0cddd 100644 --- a/exit.c +++ b/exit.c @@ -37,7 +37,7 @@ pthread_exit (void *value_ptr) * ------------------------------------------------------ */ { - _pthread_callUserDestroyRoutines(pthread_getspecific(_pthread_selfThreadKey)); + _pthread_callUserDestroyRoutines((pthread_t) pthread_getspecific(_pthread_selfThreadKey)); _endthreadex ((unsigned) value_ptr); diff --git a/global.c b/global.c index a8bd69a..abaea7c 100644 --- a/global.c +++ b/global.c @@ -14,6 +14,12 @@ int _pthread_processInitialized = FALSE; pthread_key_t _pthread_selfThreadKey = NULL; pthread_key_t _pthread_cleanupKey = NULL; +#if !defined(_MSC_VER) && defined(__cplusplus) + +Pthread_exception pthread_exception; + +#endif + /* * Global lock for testing internal state of PTHREAD_MUTEX_INITIALIZER * created mutexes. diff --git a/implement.h b/implement.h index f897033..75ca6f6 100644 --- a/implement.h +++ b/implement.h @@ -84,6 +84,7 @@ struct ThreadKeyAssoc { }; +#ifdef _MSC_VER /* * -------------------------------------------------------------- * MAKE_SOFTWARE_EXCEPTION @@ -127,6 +128,21 @@ struct ThreadKeyAssoc { #define PTHREAD_SERVICES_FACILITY 0xBAD #define PTHREAD_SERVICES_ERROR 0xDEED +#else + +#ifdef __cplusplus + +class Pthread_exception {}; + +extern Pthread_exception pthread_exception; + +#else /* __cplusplus */ + +#warning File __FILE__, Line __LINE__: Cancellation not supported under C. + +#endif /* __cplusplus */ + +#endif /* _MSC_VER */ /* Function pointer to TryEnterCriticalSection if it exists; otherwise NULL */ extern BOOL (WINAPI *_pthread_try_enter_critical_section)(LPCRITICAL_SECTION); diff --git a/misc.c b/misc.c index 49a71dd..f57d738 100644 --- a/misc.c +++ b/misc.c @@ -71,7 +71,8 @@ pthread_self (void) * need to ensure there always is a self */ - if ((self = pthread_getspecific (_pthread_selfThreadKey)) == NULL) + if ((self = (pthread_t) pthread_getspecific (_pthread_selfThreadKey)) + == NULL) { /* * Need to create an implicit 'self' for the currently @@ -153,7 +154,8 @@ CancelableWait (HANDLE waitHandle, DWORD timeout) handles[0] = waitHandle; - if ((self = pthread_getspecific (_pthread_selfThreadKey)) != NULL) + if ((self = (pthread_t) pthread_getspecific (_pthread_selfThreadKey)) + != NULL) { /* * Get cancelEvent handle @@ -219,6 +221,9 @@ CancelableWait (HANDLE waitHandle, DWORD timeout) /* * Thread started with pthread_create */ + +#ifdef _MSC_VER + DWORD exceptionInformation[3]; exceptionInformation[0] = (DWORD) (0); @@ -229,10 +234,20 @@ CancelableWait (HANDLE waitHandle, DWORD timeout) 0, 3, exceptionInformation); - } +#else /* _MSC_VER */ + +#ifdef __cplusplus + + throw pthread_exception; + +#endif /* __cplusplus */ + +#endif /* _MSC_VER */ + } - ((void *) -1); + /* Should never get to here. */ + result = EINVAL; break; default: diff --git a/mutex.c b/mutex.c index b800512..1a037f0 100644 --- a/mutex.c +++ b/mutex.c @@ -223,7 +223,7 @@ pthread_mutexattr_init (pthread_mutexattr_t * attr) pthread_mutexattr_t attr_result; int result = 0; - attr_result = calloc (1, sizeof (*attr_result)); + attr_result = (pthread_mutexattr_t) calloc (1, sizeof (*attr_result)); result = (attr_result == NULL) ? ENOMEM diff --git a/private.c b/private.c index dd32ccd..615271d 100644 --- a/private.c +++ b/private.c @@ -6,11 +6,11 @@ * the implementation and may be used throughout it. */ +#include + #include "pthread.h" #include "implement.h" -#include - /* * Code contributed by John E. Bossom . */ @@ -133,7 +133,7 @@ _pthread_threadStart (ThreadParms * threadParms) pthread_setspecific (_pthread_selfThreadKey, tid); -#ifdef _WIN32 +#ifdef _MSC_VER __try { @@ -152,7 +152,7 @@ _pthread_threadStart (ThreadParms * threadParms) status = -1; } -#else /* _WIN32 */ +#else /* _MSC_VER */ #ifdef __cplusplus @@ -164,19 +164,26 @@ _pthread_threadStart (ThreadParms * threadParms) (*start) (arg); status = 0; } + catch (Pthread_exception) + { + /* + * Thread was cancelled. + */ + status = -1; + } catch (...) - { - /* - * A system unexpected exception had occurred running the user's - * routine. We get control back within this block. - */ - status = -1; - } + { + /* + * A system unexpected exception had occurred running the user's + * routine. We get control back within this block. + */ + status = -1; + } #else /* __cplusplus */ #if defined(__CYGWIN__) || defined(__CYGWIN32__) -#warning Compile __FILE__ as C++ or thread cancellation will not work properly. +#warning File __FILE__, Line __LINE__: Cancelation not supported under C. #endif /* @@ -407,6 +414,8 @@ _pthread_callUserDestroyRoutines (pthread_t thread) if (value != NULL && k->destructor != NULL) { +#ifdef _MSC_VER + __try { /* @@ -422,6 +431,35 @@ _pthread_callUserDestroyRoutines (pthread_t thread) * We get control back within this block. */ } + +#else /* _MSC_VER */ +#ifdef __cplusplus + + try + { + /* + * Run the caller's cleanup routine. + */ + (*(k->destructor)) (value); + } + catch (...) + { + /* + * A system unexpected exception had occurred + * running the user's destructor. + * We get control back within this block. + */ + } + +#else /* __cplusplus */ + + /* + * Run the caller's cleanup routine. + */ + (*(k->destructor)) (value); + +#endif /* __cplusplus */ +#endif /* _MSC_VER */ } } diff --git a/pthread.def b/pthread.def index 3f68e5c..d8f950f 100644 --- a/pthread.def +++ b/pthread.def @@ -1,5 +1,5 @@ ; pthread.def -; Last updated: $Date: 1999/01/12 14:48:59 $ +; Last updated: $Date: 1999/01/23 06:59:02 $ ; Currently unimplemented functions are commented out. @@ -49,11 +49,11 @@ pthread_key_delete pthread_mutexattr_destroy ;pthread_mutexattr_getprioceiling ;pthread_mutexattr_getprotocol -;phtread_mutexattr_getpshared +pthread_mutexattr_getpshared pthread_mutexattr_init ;pthread_mutexattr_setprioceiling ;pthread_mutexattr_setprotocol -;pthread_mutexattr_setpshared +pthread_mutexattr_setpshared pthread_mutexattr_destroy pthread_mutex_init pthread_mutex_destroy @@ -68,3 +68,14 @@ pthread_setschedparam pthread_setspecific ;pthread_sigmask pthread_testcancel +; +; Non-portable but useful +; +pthread_mutexattr_setforcecs_np +pthreadCancelableWait +pthreadCancelableTimedWait +; +; Needed if !defined(_MSC_VER) && !defined(__cplusplus) +; +_pthread_push_cleanup +_pthread_pop_cleanup diff --git a/pthread.h b/pthread.h index 8426411..d090e43 100644 --- a/pthread.h +++ b/pthread.h @@ -205,6 +205,8 @@ #include #endif /* HAVE_SIGNAL_H */ +#include + #ifndef HAVE_STRUCT_TIMESPEC struct timespec { int tv_sec; @@ -248,8 +250,22 @@ struct timespec { #include -/* #include /**/ +/* #include */ + +#ifdef __MINGW32__ +#define PT_STDCALL +#else +#define PT_STDCALL __stdcall +#endif +/* + * This should perhaps be in autoconf or + * possibly fixed in Mingw32 to + * correspond to the Windows headers. + */ +#ifdef __MINGW32__ +#define _timeb timeb +#endif #ifdef __cplusplus extern "C" @@ -562,7 +578,7 @@ struct pthread_t_ { #define _PTHREAD_ATTR_VALID 0xC4C0FFEE struct pthread_attr_t_ { - long valid; + unsigned long valid; void *stackaddr; size_t stacksize; int detachstate; @@ -647,27 +663,24 @@ struct pthread_once_t_ { /* There are three implementations of cancel cleanup. * + * WIN32 SEH * C - * C++ (as per Cygwin32 or Mingw32) - * WIN32 SEH or C++ + * C++ */ - typedef struct _pthread_cleanup_t _pthread_cleanup_t; - - struct _pthread_cleanup_t - { - void (*routine) (void *); - void *arg; -#if !defined(_WIN32) && !defined(__cplusplus) - _pthread_cleanup_t *prev; -#endif - }; - -#ifdef _WIN32 +#ifdef _MSC_VER /* * WIN32 SEH version of cancel cleanup. */ + typedef struct _pthread_cleanup_t _pthread_cleanup_t; + + struct _pthread_cleanup_t + { + void (*routine) (void *); + void *arg; + }; + #define pthread_cleanup_push( _rout, _arg ) \ { \ _pthread_cleanup_t _cleanup; \ @@ -688,7 +701,7 @@ struct pthread_once_t_ { } \ } -#else /* _WIN32 */ +#else /* _MSC_VER */ #ifndef __cplusplus @@ -696,6 +709,15 @@ struct pthread_once_t_ { * C implementation of PThreads cancel cleanup */ + typedef struct _pthread_cleanup_t _pthread_cleanup_t; + + struct _pthread_cleanup_t + { + void (*routine) (void *); + void *arg; + _pthread_cleanup_t *prev; + }; + #define pthread_cleanup_push( _rout, _arg ) \ { \ _pthread_cleanup_t _cleanup; \ @@ -709,39 +731,85 @@ struct pthread_once_t_ { #else /* !__cplusplus */ /* - * C++ (ie. Cygwin32 or Mingw32) version of cancel cleanup. + * C++ version of cancel cleanup. + * - John E. Bossom. * * Emulate try-finally behaviour. */ + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + void (*cleanUpRout)( void * ); + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( NULL ), + obj( NULL ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + void (*routine)( void * ), + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && cleanUpRout != NULL ) + { + (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ #define pthread_cleanup_push( _rout, _arg ) \ - { \ - _pthread_cleanup_t _cleanup; \ - \ - _cleanup.routine = (_rout); \ - _cleanup.arg = (_arg); \ - try \ - { \ + { \ + PThreadCleanup cleanup((void (PT_STDCALL *)(void *))(_rout), \ + (void *) (_arg) ); #define pthread_cleanup_pop( _execute ) \ - } \ - catch(...) \ - { \ - (*(_cleanup.routine))( _cleanup.arg ); \ - \ - throw; \ - } \ - \ - if (_execute) \ - { \ - (*(_cleanup.routine))( _cleanup.arg ); \ - } \ - } - -#endif /* _WIN32 */ + cleanup.execute( _execute ); \ + } #endif /* !__cplusplus */ +#endif /* _MSC_VER */ + /* * =============== * =============== @@ -797,7 +865,7 @@ pthread_t pthread_self (void); int pthread_cancel (pthread_t thread); -#if !defined(__cplusplus) && !defined(_WIN32) +#if !defined(__cplusplus) && !defined(_MSC_VER) _pthread_cleanup_t *_pthread_pop_cleanup (int execute); @@ -805,7 +873,7 @@ void _pthread_push_cleanup (_pthread_cleanup_t * cleanup, void (*routine) (void *), void *arg); -#endif /* !__cplusplus && ! _WIN32 */ +#endif /* !__cplusplus && ! _MSC_VER */ int pthread_setcancelstate (int state, int *oldstate); diff --git a/semaphore.c b/semaphore.c index 9200cdd..9645379 100644 --- a/semaphore.c +++ b/semaphore.c @@ -212,7 +212,7 @@ sem_wait (sem_t * sem) return ((sem == NULL) ? EINVAL - : pthreadCancelableWait (*sem, INFINITE) + : pthreadCancelableWait (*sem) ); } /* sem_wait */ diff --git a/tsd.c b/tsd.c index 72a03ea..b43f4c9 100644 --- a/tsd.c +++ b/tsd.c @@ -215,7 +215,7 @@ pthread_setspecific (pthread_key_t key, const void *value) * Resolve catch-22 of registering thread with threadSelf * key */ - self = pthread_getspecific (_pthread_selfThreadKey); + self = (pthread_t) pthread_getspecific (_pthread_selfThreadKey); if (self == NULL) { self = (pthread_t) value; -- cgit v1.2.3