summaryrefslogtreecommitdiff
path: root/pthread.h
diff options
context:
space:
mode:
authorrpj <rpj>2002-01-31 06:56:03 +0000
committerrpj <rpj>2002-01-31 06:56:03 +0000
commit75f8ad67d45d48b9cdde5a298083881790c76c73 (patch)
tree0d793e00b40a3292f1fee2b302eb6eccdf15d113 /pthread.h
parent30a1e9738593302fa26e0a668f517bc7f5800190 (diff)
2002-01-27 Ross Johnson <rpj@special.ise.canberra.edu.au>
* mutex.c (pthread_mutex_timedlock): New function suggested by Alexander Terekhov. The logic required to implement this properly came from Alexander, with some collaboration with Thomas Pfaff. (pthread_mutex_unlock): Wrap the waiters check and sema post in a critical section to prevent a race with pthread_mutex_timedlock. (ptw32_timed_semwait): New function; returns a special result if the absolute timeout parameter represents a time already passed when called; used by pthread_mutex_timedwait(). Have deliberately not reused the name "ptw32_sem_timedwait" because they are not the same routine. * condvar.c (ptw32_cond_timedwait): Use the new sem_timedwait() instead of ptw32_sem_timedwait(), which now has a different function. See previous. * implement.h: Remove prototype for ptw32_sem_timedwait. See next. (pthread_mutex_t_): Add critical section element for access to lock_idx during mutex post-timeout processing. * semaphore.h (sem_timedwait): See next. * semaphore.c (sem_timedwait): See next. * private.c (ptw32_sem_timedwait): Move to semaphore.c and rename as sem_timedwait(). 2002-01-18 Ross Johnson <rpj@special.ise.canberra.edu.au> * sync.c (pthread_join): Was getting the exit code from the calling thread rather than the joined thread if defined(__MINGW32__) && !defined(__MSVCRT__). 2002-01-15 Ross Johnson <rpj@special.ise.canberra.edu.au> * pthread.h: Unless the build explicitly defines __CLEANUP_SEH, __CLEANUP_CXX, or __CLEANUP_C, then the build defaults to __CLEANUP_C style cleanup. This style uses setjmp/longjmp in the cancelation and thread exit implementations and therefore won't do stack unwinding if linked to applications that have it (e.g. C++ apps). This is currently consistent with most/all commercial Unix POSIX threads implementations. * spin.c (pthread_spin_init): Edit renamed function call. * nonportable.c (pthread_num_processors_np): New. (pthread_getprocessors_np): Renamed to ptw32_getprocessors and moved to private.c. * private.c (pthread_getprocessors): Moved here from nonportable.c. * pthread.def (pthread_getprocessors_np): Removed from export list. * rwlock.c (pthread_rwlockattr_init): New. (pthread_rwlockattr_destroy): New. (pthread_rwlockattr_getpshared): New. (pthread_rwlockattr_setpshared): New.
Diffstat (limited to 'pthread.h')
-rw-r--r--pthread.h369
1 files changed, 209 insertions, 160 deletions
diff --git a/pthread.h b/pthread.h
index de97dc9..8ecb7d7 100644
--- a/pthread.h
+++ b/pthread.h
@@ -27,7 +27,7 @@
#ifdef _UWIN
# define HAVE_STRUCT_TIMESPEC 1
-# define HAVE_SIGNAL_H 1
+# define HAVE_SIGNAL_H 1
# undef HAVE_CONFIG_H
# pragma comment(lib, "pthread")
#endif
@@ -39,16 +39,20 @@
* Module: pthread.h
*
* Purpose:
- * Provides an implementation of PThreads based upon the
- * standard:
+ * Provides an implementation of PThreads based upon the
+ * standard:
*
- * POSIX 1003.1c-1995 (POSIX.1c)
+ * POSIX 1003.1c-1995 (POSIX.1c)
*
* Parts of the implementation also comply with the
* Open Group Unix 98 specification in order to enhance
* code portability between Windows, various commercial
* Unix implementations, and Linux.
*
+ * See the ANNOUNCE file for a full list of conforming
+ * routines and defined constants, and a list of missing
+ * routines and constants not defined in this implementation.
+ *
* Authors:
* There have been many contributors to this library.
* The initial implementation was contributed by
@@ -63,7 +67,7 @@
* in the ChangeLog file in the source code distribution
* where their changes are noted in detail.
*
- * Contributors are listed in the MAINTAINERS file.
+ * Contributors are listed in the CONTRIBUTORS file.
*
* As usual, all bouquets go to the contributors, and all
* brickbats go to the project maintainer.
@@ -99,6 +103,24 @@
* -------------------------------------------------------------
*/
+/* Try to avoid including windows.h */
+#if defined(__MINGW32__) && defined(__cplusplus)
+/*
+ * FIXME: The pthreadGCE.dll build gets linker unresolved errors
+ * on pthread_key_create() unless windows.h is included here.
+ * It appears to have something to do with an argument type mismatch.
+ * Looking at tsd.o with 'nm' shows this line:
+ * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
+ * instead of
+ * 00000000 T _pthread_key_create
+ */
+#define PTW32_INCLUDE_WINDOWS_H
+#endif
+
+#ifdef PTW32_INCLUDE_WINDOWS_H
+#include <windows.h>
+#endif
+
/*
* -----------------
* autoconf switches
@@ -109,8 +131,6 @@
#include "config.h"
#endif /* HAVE_CONFIG_H */
-#include <windows.h>
-
#ifndef NEED_FTIME
#include <time.h>
#else /* NEED_FTIME */
@@ -142,11 +162,6 @@ struct timespec {
#define SIG_SETMASK 2
#endif /* SIG_SETMASK */
-/*
- * note: ETIMEDOUT is correctly defined in winsock.h
- */
-#include <winsock.h>
-
#ifdef NEED_ERRNO
# include "need_errno.h"
#else
@@ -156,18 +171,31 @@ struct timespec {
#include <sched.h>
/*
- * In case ETIMEDOUT hasn't been defined above somehow.
+ * Several systems don't define ENOTSUP. If not, we use
+ * the same value as Solaris.
*/
+#ifndef ENOTSUP
+# define ENOTSUP 48
+#endif
+
#ifndef ETIMEDOUT
# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
#endif
/*
- * Several systems don't define ENOTSUP. If not, we use
- * the same value as Solaris.
+ * To avoid including windows.h we define only those things that we
+ * actually need from it. I don't like the potential incompatibility that
+ * this creates with future versions of windows.
*/
-#ifndef ENOTSUP
-# define ENOTSUP 48
+#ifndef PTW32_INCLUDE_WINDOWS_H
+#ifndef HANDLE
+# define __HANDLE_DEF
+# define HANDLE void *
+#endif
+#ifndef DWORD
+# define __DWORD_DEF
+# define DWORD unsigned long
+#endif
#endif
#ifdef __cplusplus
@@ -182,104 +210,104 @@ extern "C"
* ===========================
*
* _POSIX_THREADS (set)
- * If set, you can use threads
+ * If set, you can use threads
*
* _POSIX_THREAD_ATTR_STACKSIZE (set)
- * If set, you can control the size of a thread's
- * stack
- * pthread_attr_getstacksize
- * pthread_attr_setstacksize
+ * If set, you can control the size of a thread's
+ * stack
+ * pthread_attr_getstacksize
+ * pthread_attr_setstacksize
*
* _POSIX_THREAD_ATTR_STACKADDR (not set)
- * If set, you can allocate and control a thread's
- * stack. If not supported, the following functions
- * will return ENOSYS, indicating they are not
- * supported:
- * pthread_attr_getstackaddr
- * pthread_attr_setstackaddr
+ * If set, you can allocate and control a thread's
+ * stack. If not supported, the following functions
+ * will return ENOSYS, indicating they are not
+ * supported:
+ * pthread_attr_getstackaddr
+ * pthread_attr_setstackaddr
*
* _POSIX_THREAD_PRIORITY_SCHEDULING (set)
- * If set, you can use realtime scheduling.
- * Indicates the availability of:
- * pthread_attr_getinheritsched
- * pthread_attr_getschedparam
- * pthread_attr_getschedpolicy
- * pthread_attr_getscope
- * pthread_attr_setinheritsched
- * pthread_attr_setschedparam
- * pthread_attr_setschedpolicy
- * pthread_attr_setscope
- * pthread_getschedparam
- * pthread_setschedparam
- * sched_get_priority_max
- * sched_get_priority_min
- * sched_rr_set_interval
+ * If set, you can use realtime scheduling.
+ * Indicates the availability of:
+ * pthread_attr_getinheritsched
+ * pthread_attr_getschedparam
+ * pthread_attr_getschedpolicy
+ * pthread_attr_getscope
+ * pthread_attr_setinheritsched
+ * pthread_attr_setschedparam
+ * pthread_attr_setschedpolicy
+ * pthread_attr_setscope
+ * pthread_getschedparam
+ * pthread_setschedparam
+ * sched_get_priority_max
+ * sched_get_priority_min
+ * sched_rr_set_interval
*
* _POSIX_THREAD_PRIO_INHERIT (not set)
- * If set, you can create priority inheritance
- * mutexes.
- * pthread_mutexattr_getprotocol +
- * pthread_mutexattr_setprotocol +
+ * If set, you can create priority inheritance
+ * mutexes.
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprotocol +
*
* _POSIX_THREAD_PRIO_PROTECT (not set)
- * If set, you can create priority ceiling mutexes
- * Indicates the availability of:
- * pthread_mutex_getprioceiling
- * pthread_mutex_setprioceiling
- * pthread_mutexattr_getprioceiling
- * pthread_mutexattr_getprotocol +
- * pthread_mutexattr_setprioceiling
- * pthread_mutexattr_setprotocol +
+ * If set, you can create priority ceiling mutexes
+ * Indicates the availability of:
+ * pthread_mutex_getprioceiling
+ * pthread_mutex_setprioceiling
+ * pthread_mutexattr_getprioceiling
+ * pthread_mutexattr_getprotocol +
+ * pthread_mutexattr_setprioceiling
+ * pthread_mutexattr_setprotocol +
*
* _POSIX_THREAD_PROCESS_SHARED (not set)
- * If set, you can create mutexes and condition
- * variables that can be shared with another
- * process.If set, indicates the availability
- * of:
- * pthread_mutexattr_getpshared
- * pthread_mutexattr_setpshared
- * pthread_condattr_getpshared
- * pthread_condattr_setpshared
+ * If set, you can create mutexes and condition
+ * variables that can be shared with another
+ * process.If set, indicates the availability
+ * of:
+ * pthread_mutexattr_getpshared
+ * pthread_mutexattr_setpshared
+ * pthread_condattr_getpshared
+ * pthread_condattr_setpshared
*
* _POSIX_THREAD_SAFE_FUNCTIONS (set)
- * If set you can use the special *_r library
- * functions that provide thread-safe behaviour
+ * If set you can use the special *_r library
+ * functions that provide thread-safe behaviour
*
- * + These functions provide both 'inherit' and/or
- * 'protect' protocol, based upon these macro
- * settings.
+ * + These functions provide both 'inherit' and/or
+ * 'protect' protocol, based upon these macro
+ * settings.
*
* POSIX 1003.1c-1995 Limits
* ===========================
*
* PTHREAD_DESTRUCTOR_ITERATIONS
- * Maximum number of attempts to destroy
- * a thread's thread-specific data on
- * termination (must be at least 4)
+ * Maximum number of attempts to destroy
+ * a thread's thread-specific data on
+ * termination (must be at least 4)
*
* PTHREAD_KEYS_MAX
- * Maximum number of thread-specific data keys
- * available per process (must be at least 128)
+ * Maximum number of thread-specific data keys
+ * available per process (must be at least 128)
*
* PTHREAD_STACK_MIN
- * Minimum supported stack size for a thread
+ * Minimum supported stack size for a thread
*
* PTHREAD_THREADS_MAX
- * Maximum number of threads supported per
- * process (must be at least 64).
+ * Maximum number of threads supported per
+ * process (must be at least 64).
*
*
* POSIX 1003.1j/D10-1999 Options
* ==============================
*
* _POSIX_READER_WRITER_LOCKS (set)
- * If set, you can use read/write locks
+ * If set, you can use read/write locks
*
* _POSIX_SPIN_LOCKS (set)
- * If set, you can use spin locks
+ * If set, you can use spin locks
*
* _POSIX_BARRIERS (set)
- * If set, you can use barriers
+ * If set, you can use barriers
*
* -------------------------------------------------------------
*/
@@ -321,30 +349,33 @@ extern "C"
/*
* POSIX Limits
*
- * PTHREAD_DESTRUCTOR_ITERATIONS
- * Standard states this must be at least
- * 4.
+ * PTHREAD_DESTRUCTOR_ITERATIONS
+ * Standard states this must be at least
+ * 4.
*
- * PTHREAD_KEYS_MAX
- * WIN32 permits only 64 TLS keys per process.
- * This limitation could be worked around by
- * simply simulating keys.
+ * PTHREAD_KEYS_MAX
+ * WIN32 permits only 64 TLS keys per process.
+ * This limitation could be worked around by
+ * simply simulating keys.
*
- * PTHREADS_STACK_MIN
- * POSIX specifies 0 which is also the value WIN32
- * interprets as allowing the system to
- * set the size to that of the main thread. The
- * maximum stack size in Win32 is 1Meg. WIN32
- * allocates more stack as required up to the 1Meg
- * limit.
+ * PTHREADS_STACK_MIN
+ * POSIX specifies 0 which is also the value WIN32
+ * interprets as allowing the system to
+ * set the size to that of the main thread. The
+ * maximum stack size in Win32 is 1Meg. WIN32
+ * allocates more stack as required up to the 1Meg
+ * limit.
*
- * PTHREAD_THREADS_MAX
- * Not documented by WIN32. Wrote a test program
- * that kept creating threads until it failed
- * revealed this approximate number.
+ * PTHREAD_THREADS_MAX
+ * Not documented by WIN32. Wrote a test program
+ * that kept creating threads until it failed
+ * revealed this approximate number (Windows NT).
+ * This number is somewhat less for Windows 9x
+ * and is effectively less than 64. Perhaps this
+ * constant should be set at DLL load time.
*
*/
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
#define PTHREAD_KEYS_MAX 64
#define PTHREAD_STACK_MIN 0
#define PTHREAD_THREADS_MAX 2019
@@ -386,19 +417,19 @@ enum {
/*
* pthread_attr_{get,set}inheritsched
*/
- PTHREAD_INHERIT_SCHED = 0,
+ PTHREAD_INHERIT_SCHED = 0,
PTHREAD_EXPLICIT_SCHED = 1, /* Default */
/*
* pthread_{get,set}scope
*/
- PTHREAD_SCOPE_PROCESS = 0,
+ PTHREAD_SCOPE_PROCESS = 0,
PTHREAD_SCOPE_SYSTEM = 1, /* Default */
/*
* pthread_setcancelstate paramters
*/
- PTHREAD_CANCEL_ENABLE = 0, /* Default */
+ PTHREAD_CANCEL_ENABLE = 0, /* Default */
PTHREAD_CANCEL_DISABLE = 1,
/*
@@ -437,13 +468,13 @@ enum {
* ====================
* ====================
*/
-#define PTHREAD_ONCE_INIT { FALSE, -1 }
+#define PTHREAD_ONCE_INIT { FALSE, -1 }
struct pthread_once_t_
{
- int done; /* indicates if user function executed */
- long started; /* First thread to increment this value */
- /* to zero executes the user function */
+ int done; /* indicates if user function executed */
+ long started; /* First thread to increment this value */
+ /* to zero executes the user function */
};
@@ -495,19 +526,17 @@ enum
* C++ and C built versions will not.
*/
-/*
- * define defaults for cleanup code
+/*
+ * Define defaults for cleanup code.
+ * Note: Unless the build explicitly defines one of the following, then
+ * we default to standard C style cleanup. This style uses setjmp/longjmp
+ * in the cancelation and thread exit implementations and therefore won't
+ * do stack unwinding if linked to applications that have it (e.g.
+ * C++ apps). This is currently consistent with most/all commercial Unix
+ * POSIX threads implementations.
*/
#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
-
-#if defined(_MSC_VER)
-#define __CLEANUP_SEH
-#elif defined(__cplusplus)
-#define __CLEANUP_CXX
-#else
-#define __CLEANUP_C
-#endif
-
+# define __CLEANUP_C
#endif
#if defined( __CLEANUP_SEH ) && defined(__GNUC__)
@@ -533,7 +562,7 @@ struct ptw32_cleanup_t
{ \
ptw32_cleanup_t _cleanup; \
\
- _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
+ _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
_cleanup.arg = (_arg); \
__try \
{ \
@@ -560,7 +589,7 @@ struct ptw32_cleanup_t
#define pthread_cleanup_push( _rout, _arg ) \
{ \
ptw32_cleanup_t _cleanup; \
- \
+ \
ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
#define pthread_cleanup_pop( _execute ) \
@@ -581,22 +610,22 @@ struct ptw32_cleanup_t
* 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)
+ * 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)
*/
ptw32_cleanup_callback_t cleanUpRout;
- void * obj;
- int executeIt;
+ void * obj;
+ int executeIt;
public:
PThreadCleanup() :
- cleanUpRout( NULL ),
- obj( NULL ),
+ cleanUpRout( 0 ),
+ obj( 0 ),
executeIt( 0 )
/*
* No cleanup performed
@@ -605,22 +634,22 @@ struct ptw32_cleanup_t
}
PThreadCleanup(
- ptw32_cleanup_callback_t routine,
- void * arg ) :
+ ptw32_cleanup_callback_t routine,
+ void * arg ) :
cleanUpRout( routine ),
obj( arg ),
executeIt( 1 )
/*
- * Registers a cleanup routine for 'arg'
- */
+ * Registers a cleanup routine for 'arg'
+ */
{
}
~PThreadCleanup()
{
- if ( executeIt && ((void *) cleanUpRout != NULL) )
+ if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
{
- (void) (*cleanUpRout)( obj );
+ (void) (*cleanUpRout)( obj );
}
}
@@ -637,7 +666,7 @@ struct ptw32_cleanup_t
* cleanup routine if we exit our scope weirdly
*/
#define pthread_cleanup_push( _rout, _arg ) \
- { \
+ { \
PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \
(void *) (_arg) );
@@ -689,28 +718,28 @@ int pthread_attr_setstacksize (pthread_attr_t * attr,
size_t stacksize);
int pthread_attr_getschedparam (const pthread_attr_t *attr,
- struct sched_param *param);
+ struct sched_param *param);
int pthread_attr_setschedparam (pthread_attr_t *attr,
- const struct sched_param *param);
+ const struct sched_param *param);
int pthread_attr_setschedpolicy (pthread_attr_t *,
- int);
+ int);
int pthread_attr_getschedpolicy (pthread_attr_t *,
- int *);
+ int *);
int pthread_attr_setinheritsched(pthread_attr_t * attr,
- int inheritsched);
+ int inheritsched);
int pthread_attr_getinheritsched(pthread_attr_t * attr,
- int * inheritsched);
+ int * inheritsched);
int pthread_attr_setscope (pthread_attr_t *,
- int);
+ int);
int pthread_attr_getscope (const pthread_attr_t *,
- int *);
+ int *);
/*
* PThread Functions
@@ -806,6 +835,9 @@ int pthread_mutex_destroy (pthread_mutex_t * mutex);
int pthread_mutex_lock (pthread_mutex_t * mutex);
+int pthread_mutex_timedlock(pthread_mutex_t *mutex,
+ const struct timespec *abstime);
+
int pthread_mutex_trylock (pthread_mutex_t * mutex);
int pthread_mutex_unlock (pthread_mutex_t * mutex);
@@ -828,7 +860,7 @@ int pthread_spin_unlock (pthread_spinlock_t * lock);
*/
int pthread_barrier_init (pthread_barrier_t * barrier,
const pthread_barrierattr_t * attr,
- unsigned int count);
+ unsigned int count);
int pthread_barrier_destroy (pthread_barrier_t * barrier);
@@ -885,7 +917,7 @@ int pthread_getconcurrency (void);
* Read-Write Lock Functions
*/
int pthread_rwlock_init(pthread_rwlock_t *lock,
- const pthread_rwlockattr_t *attr);
+ const pthread_rwlockattr_t *attr);
int pthread_rwlock_destroy(pthread_rwlock_t *lock);
@@ -899,6 +931,15 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *lock);
int pthread_rwlock_unlock(pthread_rwlock_t *lock);
+int pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
+
+int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
+
+int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
+ int *pshared);
+
+int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
+ int pshared);
/*
* Non-portable functions
@@ -924,6 +965,7 @@ HANDLE pthread_getw32threadhandle_np(pthread_t thread);
* Returns the number of CPUs available to the process.
*/
int pthread_getprocessors_np(int * count);
+int pthread_num_processors_np(void);
/*
* Useful if an application wants to statically link
@@ -943,7 +985,7 @@ int pthread_win32_thread_detach_np(void);
* This function allows the caller to hook into the
* PThreads cancel mechanism. It is implemented using
*
- * WaitForMultipleObjects
+ * WaitForMultipleObjects
*
* on 'waitHandle' and a manually reset WIN32 Event
* used to implement pthread_cancel. The 'timeout'
@@ -991,8 +1033,8 @@ int * _errno( void );
(_buf) )
#define ctime_r( _clock, _buf ) \
- ( strcpy( (_buf), ctime( (_clock) ) ), \
- (_buf) )
+ ( strcpy( (_buf), ctime( (_clock) ) ), \
+ (_buf) )
#define gmtime_r( _clock, _result ) \
( *(_result) = *gmtime( (_clock) ), \
@@ -1032,22 +1074,22 @@ DWORD ptw32_get_exception_services_code(void);
* propagate our internal exceptions up to the library's internal handlers.
*/
#define __except( E ) \
- __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
+ __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
? EXCEPTION_CONTINUE_SEARCH : ( E ) )
#endif /* __CLEANUP_SEH */
-#ifdef __cplusplus
+#ifdef __CLEANUP_CXX
/*
* Redefine the C++ catch keyword to ensure that applications
* propagate our internal exceptions up to the library's internal handlers.
*/
#ifdef _MSC_VER
- /*
- * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
- * if you want Pthread-Win32 cancelation and pthread_exit to work.
- */
+ /*
+ * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
+ * if you want Pthread-Win32 cancelation and pthread_exit to work.
+ */
#ifndef PtW32NoCatchWarn
@@ -1058,18 +1100,18 @@ DWORD ptw32_get_exception_services_code(void);
#endif
#define PtW32CatchAll \
- catch( ptw32_exception & ) { throw; } \
- catch( ... )
+ catch( ptw32_exception & ) { throw; } \
+ catch( ... )
#else /* _MSC_VER */
#define catch( E ) \
- catch( ptw32_exception & ) { throw; } \
- catch( E )
+ catch( ptw32_exception & ) { throw; } \
+ catch( E )
#endif /* _MSC_VER */
-#endif /* __cplusplus */
+#endif /* __CLEANUP_CXX */
#endif /* ! PTW32_BUILD */
@@ -1077,4 +1119,11 @@ DWORD ptw32_get_exception_services_code(void);
} /* End of extern "C" */
#endif /* __cplusplus */
+#ifdef __HANDLE_DEF
+# undef HANDLE
+#endif
+#ifdef __DWORD_DEF
+# undef DWORD
+#endif
+
#endif /* PTHREAD_H */