summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog49
-rw-r--r--Makefile.in6
-rw-r--r--attr.c3
-rw-r--r--cancel.c17
-rw-r--r--cleanup.c20
-rw-r--r--condvar.c2
-rw-r--r--create.c2
-rw-r--r--dll.c4
-rw-r--r--exit.c2
-rw-r--r--global.c6
-rw-r--r--implement.h16
-rw-r--r--misc.c23
-rw-r--r--mutex.c2
-rw-r--r--private.c62
-rw-r--r--pthread.def17
-rw-r--r--pthread.h152
-rw-r--r--semaphore.c2
-rw-r--r--tsd.c2
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 <rpj@ixobrychus.canberra.edu.au>
+
+ * semaphore.c (sem_wait): Remove second arg to
+ pthreadCancelableWait() call.
+
Sat Jan 23 17:36:40 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+ * 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 <rpj@swan.canberra.edu.au>
+
+ * 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 <rpj@ixobrychus.canberra.edu.au>
* 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,
/* </JEB> */
-
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 <sys/timeb.h>
+
#include "pthread.h"
#include "implement.h"
-#include <sys/timeb.h>
-
/*
* Code contributed by John E. Bossom <JEB>.
*/
@@ -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 <signal.h>
#endif /* HAVE_SIGNAL_H */
+#include <malloc.h>
+
#ifndef HAVE_STRUCT_TIMESPEC
struct timespec {
int tv_sec;
@@ -248,8 +250,22 @@ struct timespec {
#include <semaphore.h>
-/* #include <sched.h> /**/
+/* #include <sched.h> */
+
+#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;