From 11eb4dfd2d42417327fc205c649ea32ee623cf92 Mon Sep 17 00:00:00 2001
From: rpj <rpj>
Date: Fri, 18 Aug 2000 08:02:29 +0000
Subject: 2000-08-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>

        * Several: Fix typos from scripted edit session
        yesterday.

        * nonportable.c (pthread_mutexattr_setforcecs_np):
        Moved this function from mutex.c.
        (pthread_getw32threadhandle_np): New function to
        return the win32 thread handle that the POSIX
        thread is using.
        * mutex.c (pthread_mutexattr_setforcecs_np):
        Moved to new file "nonportable.c".

        * pthread.h (PTW32_BUILD): Only redefine __except
        and catch compiler keywords if we aren't building
        the library (ie. PTW32_BUILD is not defined) -
        this is safer than defining and then undefining
        if not building the library.
        * implement.h: Remove __except and catch undefines.
        * Makefile (CFLAGS): Define PTW32_BUILD.
        * GNUmakefile (CFLAGS): Define PTW32_BUILD.

        * All appropriate: Change Pthread_exception* to
        ptw32_exception* to be consistent with internal
        identifier naming.

        * private.c (ptw32_throw): New function to provide
        a generic exception throw for all internal
        exceptions and EH schemes.
        (ptw32_threadStart): pthread_exit() value is now
        returned via the thread structure exitStatus
        element.
        * exit.c (pthread_exit): pthread_exit() value is now
        returned via the thread structure exitStatus
        element.
        * cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
        (pthread_setcancelstate): Ditto.
        (pthread_setcanceltype): Ditto.
        (pthread_testcancel): Ditto.
        (pthread_cancel): Ditto.
        * misc.c (CancelableWait): Ditto.
        * exit.c (pthread_exit): Ditto.
        * All applicable: Change PTW32_ prefix to
        PTW32_ prefix to remove leading underscores
        from private library identifiers.
---
 ANNOUNCE    |  32 ++++++++++--------
 ChangeLog   | 110 ++++++++++++++++++++++++++++++++++++++++++------------------
 GNUmakefile |   8 ++---
 Makefile    |   3 +-
 README      |  42 +++++++++++++++++++++--
 attr.c      |   4 +--
 cancel.c    |  58 ++++----------------------------
 cleanup.c   |   4 +--
 condvar.c   |  14 ++++----
 dll.c       |   2 +-
 exit.c      |  42 ++---------------------
 global.c    |   2 +-
 implement.h |  50 +++++++++------------------
 misc.c      |  27 ++-------------
 mutex.c     |  30 ++++-------------
 private.c   |  69 ++++++++++++++++++++++++++++++++------
 pthread.def |   3 +-
 pthread.h   |  55 ++++++++++++++++++++----------
 rwlock.c    |  18 +++++-----
 sched.c     |   2 +-
 tsd.c       |   2 +-
 21 files changed, 294 insertions(+), 283 deletions(-)

diff --git a/ANNOUNCE b/ANNOUNCE
index a7e61c3..9607dd4 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -26,19 +26,14 @@ Change Summary (since the last snapshot)
 (See the ChangeLog file for details.)
 
 New:
--	Renamed DLL and LIB files:
-		pthreadVSE.dll	(MS VC++/Structured EH)
-		pthreadVSE.lib
-		pthreadVCE.dll	(MS VC++/C++ EH)
-		pthreadVCE.lib
-		pthreadGCE.dll	(GNU G++/C++ EH)
-		libpthreadw32.a
-
-	Both your application and the pthread dll should use the
-	same exception handling scheme.
+-	New non-portable function (see the README file):
+		pthread_getw32threadhandle_np
 
 Bugs fixed:
--	MSVC++ C++ exception handling.
+-	TSD key creation race condition;
+-	Other potential race conditions
+	associated with initialising various
+	pthreads objects.
 
 Some new tests have been added.
 
@@ -46,15 +41,18 @@ Some new tests have been added.
 Known bugs in this snapshot
 ---------------------------
 
-1. Running the test "join1.c" with the library built with Mingw32
+1. Asynchronous cancelation only works on Intel X86 machines.
+
+2. Running the test "join1.c" with the library built with Mingw32
 and the GNUmakefile included, the test fails with a segmentation (invalid
 page access) exception. The fault appears to be in the assembler code
 emmitted by the compiler [to handle exception contexts] at the
 end of the try block in ptw32_threadStart().
 
-2. There are problems using the libpthreadw32.a stub archive derived
+3. There are problems using the libpthreadw32.a stub archive derived
 from either of pthreadVSE.dll or pthreadVCE.dll. The cleanup1.c test
-fails.
+fails. This is now an expected result of having different EH and cleanup
+handler schemes in the library and application.
 
 
 Caveats
@@ -207,6 +205,12 @@ The following functions are implemented:
       ---------------------------
       pthread_sigmask
 
+      ---------------------------
+      Non-portable routines (see the README file for usage)
+      ---------------------------
+      pthread_mutexattr_setforcecs_np
+      pthread_getw32threadhandle_np
+
       ---------------------------
       Static Initializers (macros)
       ---------------------------
diff --git a/ChangeLog b/ChangeLog
index 22393ab..433a835 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2000-08-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
+
+	* Several: Fix typos from scripted edit session
+	yesterday.
+
+	* nonportable.c (pthread_mutexattr_setforcecs_np):
+	Moved this function from mutex.c.
+	(pthread_getw32threadhandle_np): New function to
+	return the win32 thread handle that the POSIX
+	thread is using.
+	* mutex.c (pthread_mutexattr_setforcecs_np):
+	Moved to new file "nonportable.c".
+
+	* pthread.h (PTW32_BUILD): Only	redefine __except
+	and catch compiler keywords if we aren't building
+	the library (ie. PTW32_BUILD is not defined) - 
+	this is safer than defining and then undefining
+	if not building the library.
+	* implement.h: Remove __except and catch undefines.
+	* Makefile (CFLAGS): Define PTW32_BUILD.
+	* GNUmakefile (CFLAGS): Define PTW32_BUILD.
+
+	* All appropriate: Change Pthread_exception* to
+	ptw32_exception* to be consistent with internal
+	identifier naming.
+
+	* private.c (ptw32_throw): New function to provide
+	a generic exception throw for all internal
+	exceptions and EH schemes.
+	(ptw32_threadStart): pthread_exit() value is now
+	returned via the thread structure exitStatus
+	element.
+	* exit.c (pthread_exit): pthread_exit() value is now
+	returned via the thread structure exitStatus
+	element.
+	* cancel.c (ptw32_cancel_self): Now uses ptw32_throw.
+	(pthread_setcancelstate): Ditto.
+	(pthread_setcanceltype): Ditto.
+	(pthread_testcancel): Ditto.
+	(pthread_cancel): Ditto.
+	* misc.c (CancelableWait): Ditto.
+	* exit.c (pthread_exit): Ditto.
+	* All applicable: Change PTW32_ prefix to
+	PTW32_ prefix to remove leading underscores
+	from private library identifiers.
+
 2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 
 	* All applicable: Change _pthread_ prefix to
@@ -116,7 +162,7 @@
 
 2000-08-03  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 
-	* pthread.h: Add a base class Pthread_exception for
+	* pthread.h: Add a base class ptw32_exception for
 	library internal exceptions and change the "catch"
 	re-define macro to use it.
 
@@ -254,13 +300,13 @@
 2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 
 	* private.c (ptw32_get_exception_services_code): New; returns
-	value of EXCEPTION_PTHREAD_SERVICES.
+	value of EXCEPTION_PTW32_SERVICES.
 	(ptw32_processInitialize): Remove initialisation of
 	ptw32_exception_services which is no longer needed.
 
 	* pthread.h (ptw32_exception_services): Remove extern.
 	(ptw32_get_exception_services_code): Add function prototype;
-	use this to return EXCEPTION_PTHREAD_SERVICES value instead of
+	use this to return EXCEPTION_PTW32_SERVICES value instead of
 	using the ptw32_exception_services variable which I had
 	trouble exporting through pthread.def.
 
@@ -524,15 +570,15 @@ Tue Aug 17 20:00:08 1999  Mumit Khan  <khan@xraylith.wisc.edu>
 	(general): Define and rename exceptions.
 
 
-	* misc.c (CancelableWait):  _PTHREAD_EPS_CANCEL (SEH) and
-	Pthread_exception_cancel (C++) used to identify the exception.
+	* misc.c (CancelableWait):  PTW32_EPS_CANCEL (SEH) and
+	ptw32_exception_cancel (C++) used to identify the exception.
 
-	* cancel.c (pthread_testcancel): _PTHREAD_EPS_CANCEL (SEH) and
-	Pthread_exception_cancel (C++) used to identify the exception.
+	* cancel.c (pthread_testcancel): PTW32_EPS_CANCEL (SEH) and
+	ptw32_exception_cancel (C++) used to identify the exception.
 
 	* exit.c (pthread_exit): throw/raise an exception to return to
-	ptw32_threadStart() to exit the thread. _PTHREAD_EPS_EXIT (SEH)
-	and Pthread_exception_exit (C++) used to identify the exception.
+	ptw32_threadStart() to exit the thread. PTW32_EPS_EXIT (SEH)
+	and ptw32_exception_exit (C++) used to identify the exception.
 
 	* private.c (ptw32_threadStart): Add pthread_exit exception trap;
 	clean up and exit the thread directly rather than via pthread_exit().
@@ -822,7 +868,7 @@ Fri Feb  5 13:42:30 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 
 Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
-	* global.c: Remove Pthread_exception instantiation.
+	* global.c: Remove ptw32_exception instantiation.
 
 	* cancel.c (pthread_testcancel): Change C++ exception throw.
 
@@ -858,7 +904,7 @@ Tue Feb  2 18:07:43 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 	Reverse LHS/RHS bitwise assignments.
 
 	* pthread.h: Remove #include <semaphore.h>.
-	(_PTHREAD_ATTR_VALID): Add cast.
+	(PTW32_ATTR_VALID): Add cast.
 	(struct pthread_t_): Add sigmask element.
 
 	* dll.c: Add "extern C" for DLLMain.
@@ -950,7 +996,7 @@ Fri Jan 22 14:31:59 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 
 	* cancel.c (pthread_testcancel): Ditto.
 
-	* implement.h (class pthread_exception): Define for C++.
+	* implement.h (class ptw32_exception): Define for C++.
 
 	* pthread.h: Fix C, C++, and Win32 SEH condition compilation
 	mayhem around pthread_cleanup_* defines. C++ version now uses John
@@ -1400,7 +1446,7 @@ Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
 Fri Oct 23 00:08:09 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
-	* implement.h (_PTHREAD_TSD_KEY_REUSE): Add enum.
+	* implement.h (PTW32_TSD_KEY_REUSE): Add enum.
 
 	* private.c (ptw32_delete_thread): Add call to
 	ptw32_destructor_run_all() to clean up the threads keys.
@@ -1486,8 +1532,8 @@ Mon Oct 12 00:00:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 	* implement.h (ptw32_destructor_push): Remove.
 	(ptw32_destructor_pop): Remove.
 	(ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
-	(_PTHREAD_TSD_KEY_DELETED): Add enum.
-	(_PTHREAD_TSD_KEY_INUSE): Add enum.
+	(PTW32_TSD_KEY_DELETED): Add enum.
+	(PTW32_TSD_KEY_INUSE): Add enum.
 
 	* cleanup.c (ptw32_destructor_push): Remove.
 	(ptw32_destructor_pop): Remove.
@@ -1693,7 +1739,7 @@ Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 	* private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
 	(ptw32_delete_thread): Ditto.
 
-	* implement.h: (_PTHREAD_MAX_THREADS): Add define. This keeps
+	* implement.h: (PTW32_MAX_THREADS): Add define. This keeps
 	changing in an attempt to make thread administration data types
 	opaque and cleanup DLL startup.
 
@@ -1704,7 +1750,7 @@ Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 	(ptw32_threads_mutex_table): Ditto.
 
 	* global.c (_POSIX_THREAD_THREADS_MAX): Initialise with 
-	_PTHREAD_MAX_THREADS.
+	PTW32_MAX_THREADS.
 	(ptw32_virgins): Ditto.
 	(ptw32_reuse): Ditto.
 	(ptw32_win32handle_map): Ditto.
@@ -1839,9 +1885,9 @@ Mon Aug  3 21:19:57 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 	member initialisation - cancelstate, canceltype, cancel_pending.
 	(is_attr): Make arg "attr" a const.
 
-	* implement.h (_PTHREAD_HANDLER_POP_LIFO): Remove definition.
-	(_PTHREAD_HANDLER_POP_FIFO): Ditto.
-	(_PTHREAD_VALID): Add missing newline escape (\).
+	* implement.h (PTW32_HANDLER_POP_LIFO): Remove definition.
+	(PTW32_HANDLER_POP_FIFO): Ditto.
+	(PTW32_VALID): Add missing newline escape (\).
 	(ptw32_handler_node): Make element "next" a pointer.
 
 1998-08-02  Ben Elliston  <bje@cygnus.com>
@@ -1903,8 +1949,8 @@ Fri Jul 31 00:05:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
 	* condvar.c (windows.h): Add include.
 
-	* implement.h (_PTHREAD_THIS): Remove - no longer required.
-	(_PTHREAD_STACK): Use pthread_self() instead of _PTHREAD_THIS.
+	* implement.h (PTW32_THIS): Remove - no longer required.
+	(PTW32_STACK): Use pthread_self() instead of PTW32_THIS.
 
 Thu Jul 30 23:12:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
@@ -1921,7 +1967,7 @@ Thu Jul 30 23:12:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 	local storage.
 
 	* implement.h: Add ptw32_threadID_TlsIndex.
-	Add ()s around _PTHREAD_VALID expression.
+	Add ()s around PTW32_VALID expression.
 
 	* misc.c (pthread_self): Re-implement using Win32 TLS to store
 	the threads own ID.
@@ -1940,7 +1986,7 @@ Wed Jul 29 11:39:03 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
 Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 
-	* implement.h: Add _PTHREAD_VALID macro.
+	* implement.h: Add PTW32_VALID macro.
 
 	* sync.c (pthread_join): Modify to use the new thread
 	type and ptw32_delete_thread(). Rename "target" to "thread".
@@ -1956,14 +2002,14 @@ Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 
 	* private.c (ptw32_find_thread): Fix return type and arg.
 
-	* implement.h: Remove _PTHREAD_YES and _PTHREAD_NO.
+	* implement.h: Remove PTW32_YES and PTW32_NO.
 	(ptw32_new_thread): Add prototype.
 	(ptw32_find_thread): Ditto.
 	(ptw32_delete_thread): Ditto.
 	(ptw32_new_thread_entry): Remove prototype.
 	(ptw32_find_thread_entry): Ditto.
 	(ptw32_delete_thread_entry): Ditto.
-	(  _PTHREAD_NEW, _PTHREAD_INUSE, _PTHREAD_EXITED, _PTHREAD_REUSE):
+	(  PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
 	Add.
 
 
@@ -2146,7 +2192,7 @@ Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
 	* exit.c (pthread_exit): Fix indirection mistake.
 
-	* implement.h (_PTHREAD_THREADS_TABLE_INDEX): Add.
+	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
 
 	* exit.c (ptw32_vacuum): Fix incorrect args to
 	ptw32_handler_pop_all() calls.
@@ -2154,7 +2200,7 @@ Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 
 	* sync.c (pthread_join): Add multiple join and async detach handling.
 
-	* implement.h (_PTHREAD_THREADS_TABLE_INDEX): Add.
+	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
 
 	* global.c (ptw32_threads_mutex_table): Add.
 
@@ -2192,8 +2238,8 @@ Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 	* exit.c (pthread_exit): Add comment explaining the longjmp().
 
 	* implement.h (ptw32_threads_thread_t): New member cancelthread.
-	(_PTHREAD_YES): Define.
-	(_PTHREAD_NO): Define.
+	(PTW32_YES): Define.
+	(PTW32_NO): Define.
 	(RND_SIZEOF): Remove.
 
 	* create.c (pthread_create): Rename cancelability to cancelstate.
@@ -2309,7 +2355,7 @@ Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 	(pthread_attr_getdetachstate): Implement.
 	(pthread_attr_setdetachstate): Likewise.
 
-	* implement.h (_PTHREAD_CANCEL_DEFAULTS): Remove.  Bit fields
+	* implement.h (PTW32_CANCEL_DEFAULTS): Remove.  Bit fields
 	proved to be too cumbersome.  Set the defaults in attr.c using the
 	public PTHREAD_CANCEL_* constants.
 
@@ -2495,7 +2541,7 @@ Mon Jul 20 02:31:05 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 	non-sharable static data within the pthread DLL.
 
 	* implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
-	and _PTHREAD_HASH_INDEX.
+	and PTW32_HASH_INDEX.
 
 	* exit.c (pthread_exit): Begin work on cleanup and de-allocate
 	thread-private storage.
diff --git a/GNUmakefile b/GNUmakefile
index c91a782..85dd95b 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -33,14 +33,14 @@ LD	= gcc -mdll
 OPT	= -g -O0 -x $(GLANG)
 
 ## Mingw32
-CFLAGS	= $(OPT) -I. -mthreads -DHAVE_CONFIG_H -Wall
+CFLAGS	= $(OPT) -I. -mthreads -DHAVE_CONFIG_H -DPTW32_BUILD -Wall
 
 ## Cygwin G++
-#CFLAGS	= $(OPT) -fhandle-exceptions -I. -DHAVE_CONFIG_H -Wall
+#CFLAGS	= $(OPT) -fhandle-exceptions -I. -DHAVE_CONFIG_H -DPTW32_BUILD -Wall
 
 OBJS	= attr.o cancel.o cleanup.o condvar.o create.o dll.o errno.o \
-	  exit.o fork.o global.o misc.o mutex.o private.o rwlock.o \
-	  sched.o semaphore.o signal.o sync.o tsd.o
+	  exit.o fork.o global.o misc.o mutex.o nonportable.o \
+	  private.o rwlock.o sched.o semaphore.o signal.o sync.o tsd.o
 
 INCL	= implement.h semaphore.h pthread.h windows.h
 
diff --git a/Makefile b/Makefile
index f8d0b00..976d9f2 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn
 #Structured Exceptions
 VSEFLAGS	= 
 
-CFLAGS	= /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400
+CFLAGS	= /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DPTW32_BUILD
 
 OBJ=attr.obj \
 	cancel.obj \
@@ -32,6 +32,7 @@ OBJ=attr.obj \
 	global.obj \
 	misc.obj \
 	mutex.obj \
+	nonportable.obj \
 	private.obj \
 	rwlock.obj \
 	sched.obj \
diff --git a/README b/README
index 794ba7d..3ad70f9 100644
--- a/README
+++ b/README
@@ -52,15 +52,18 @@ The GNU library archive file name has changed to:
 Known bugs in this snapshot
 ---------------------------
 
-1. Running the test "join1.c" with the library built with Mingw32
+1. Asynchronous cancelation only works on Intel X86 machines.
+
+2. Running the test "join1.c" with the library built with Mingw32
 and the GNUmakefile included, the test fails with a segmentation (invalid
 page access) exception. The fault appears to be in the assembler code
 emmitted by the compiler [to handle exception contexts] at the
 end of the try block in ptw32_threadStart().
 
-2. There are problems using the libpthreadw32.a stub archive derived
+3. There are problems using the libpthreadw32.a stub archive derived
 from either of pthreadVSE.dll or pthreadVCE.dll. The cleanup1.c test
-fails.
+fails. This is now an expected result of having different EH and cleanup
+handler schemes in the library and application.
 
 
 Caveats
@@ -85,6 +88,39 @@ Otherwise neither pthreads cancelation nor pthread_exit() will work
 reliably.
 
 
+Non-portable functions included in the library
+----------------------------------------------
+
+void
+pthread_mutexattr_setforcecs_np(pthread_mutexattr_t *attr,
+				int forcecs);
+
+	Allows an application to force the library to use
+	critical sections rather than win32 mutexes as
+	the basis for any mutex that uses "attr".
+	Critical sections are significantly faster than
+	mutexes.
+
+	Values for "forcecs" are:
+	PTHREAD_MUTEX_AUTO_CS_NP
+		- allow the library to decide based on
+		  availability of tryEnterCriticalSection()
+	PTHREAD_MUTEX_FORCE_CS_NP
+		- force use of critical sections, but you'd
+		  better not try to use pthread_mutex_trylock()
+		  on that mutex if you want your application
+		  to work on all versions of Windows.
+
+HANDLE
+pthread_getw32threadhandle_np(pthread_t thread);
+
+	Returns the win32 thread handle that the POSIX
+	thread "thread" is running as.
+
+	Applications can use the win32 handle to set
+	win32 specific attributes of the thread.
+
+
 Building under VC++ using either C++ EH or Structured EH
 --------------------------------------------------------
 
diff --git a/attr.c b/attr.c
index 84c35a5..9489e70 100644
--- a/attr.c
+++ b/attr.c
@@ -35,7 +35,7 @@ is_attr(const pthread_attr_t *attr)
 
   return (attr == NULL || 
 	  *attr == NULL || 
-	  (*attr)->valid != _PTHREAD_ATTR_VALID);
+	  (*attr)->valid != PTW32_ATTR_VALID);
 }
 
 
@@ -346,7 +346,7 @@ pthread_attr_init(pthread_attr_t *attr)
   /* Priority uses Win32 priority values. */
   attr_result->priority = THREAD_PRIORITY_NORMAL;
 
-  attr_result->valid = _PTHREAD_ATTR_VALID;
+  attr_result->valid = PTW32_ATTR_VALID;
 
   *attr = attr_result;
 
diff --git a/cancel.c b/cancel.c
index 3273299..9e5b789 100644
--- a/cancel.c
+++ b/cancel.c
@@ -30,29 +30,7 @@
 static void 
 ptw32_cancel_self(void)
 {
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-  DWORD exceptionInformation[3];
-
-  exceptionInformation[0] = (DWORD) (_PTHREAD_EPS_CANCEL);
-  exceptionInformation[1] = (DWORD) (0);
-  exceptionInformation[2] = (DWORD) (0);
-
-  RaiseException (
-		  EXCEPTION_PTHREAD_SERVICES,
-		  0,
-		  3,
-		  exceptionInformation);
-
-#else /* _MSC_VER && ! __cplusplus */
-
-# ifdef __cplusplus
-
-  throw Pthread_exception_cancel();
-
-# endif /* __cplusplus */
-
-#endif /* _MSC_VER && ! __cplusplus */
+  ptw32_throw(PTW32_EPS_CANCEL);
 
   /* Never reached */
 }
@@ -62,7 +40,7 @@ ptw32_cancel_self(void)
  * ptw32_cancel_thread implements asynchronous cancellation.
  */
 static void 
-ptw32_ancel_thread(pthread_t thread)
+ptw32_cancel_thread(pthread_t thread)
 {
   HANDLE threadH = thread->threadH;
 
@@ -158,7 +136,7 @@ pthread_setcancelstate (int state, int *oldstate)
     {
       ResetEvent(self->cancelEvent);
       (void) pthread_mutex_unlock(&self->cancelLock);
-      ptw32_cancel_self();
+      ptw32_throw(PTW32_EPS_CANCEL);
 
       /* Never reached */
     }
@@ -242,7 +220,7 @@ pthread_setcanceltype (int type, int *oldtype)
     {
       ResetEvent(self->cancelEvent);
       (void) pthread_mutex_unlock(&self->cancelLock);
-      ptw32_cancel_self();
+      ptw32_throw(PTW32_EPS_CANCEL);
 
       /* Never reached */
     }
@@ -293,31 +271,7 @@ pthread_testcancel (void)
       /*
        * Canceling!
        */
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-      DWORD exceptionInformation[3];
-
-      exceptionInformation[0] = (DWORD) (_PTHREAD_EPS_CANCEL);
-      exceptionInformation[1] = (DWORD) (0);
-      exceptionInformation[2] = (DWORD) (0);
-
-      RaiseException (
-		      EXCEPTION_PTHREAD_SERVICES,
-		      0,
-		      3,
-		      exceptionInformation);
-
-#else /* _MSC_VER && ! __cplusplus */
-
-#ifdef __cplusplus
-
-      throw Pthread_exception_cancel();
-
-#endif /* __cplusplus */
-
-#endif /* _MSC_VER && ! __cplusplus */
-
+      ptw32_throw(PTW32_EPS_CANCEL);
     }
 }				/* pthread_testcancel */
 
@@ -384,7 +338,7 @@ pthread_cancel (pthread_t thread)
       if (cancel_self)
 	{
 	  (void) pthread_mutex_unlock(&self->cancelLock);
-	  ptw32_cancel_self();
+	  ptw32_throw(PTW32_EPS_CANCEL);
 
 	  /* Never reached */
 	}
diff --git a/cleanup.c b/cleanup.c
index 971828f..3ba4193 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -69,7 +69,7 @@ pthread_pop_cleanup (int execute)
 {
   ptw32_cleanup_t *cleanup = NULL;
   
-  cleanup = (ptw32_leanup_t *) pthread_getspecific (ptw32_leanupKey);
+  cleanup = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey);
 
   if (cleanup != NULL)
     {
@@ -105,7 +105,7 @@ pthread_pop_cleanup (int execute)
 	       */
 	      (*cleanup->routine) (cleanup->arg);
 	    }
-      catch(...)
+	  catch(...)
 	    {
 	      /*
 	       * A system unexpected exception had occurred
diff --git a/condvar.c b/condvar.c
index 0f74c9f..87e62d8 100644
--- a/condvar.c
+++ b/condvar.c
@@ -61,7 +61,7 @@ _cond_check_need_init(pthread_cond_t *cond)
    * re-initialise it only by calling pthread_cond_init()
    * explicitly.
    */
-  if (*cond == (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
     {
       result = pthread_cond_init(cond, NULL);
     }
@@ -464,7 +464,7 @@ pthread_cond_destroy (pthread_cond_t * cond)
       return EINVAL;
     }
 
-  if (*cond != (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*cond != (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
     {
       cv = *cond;
 
@@ -492,12 +492,12 @@ pthread_cond_destroy (pthread_cond_t * cond)
       /*
        * See notes in _cond_check_need_init() above also.
        */
-      EnterCriticalSection(&ptw32_ond_test_init_lock);
+      EnterCriticalSection(&ptw32_cond_test_init_lock);
 
       /*
        * Check again.
        */
-      if (*cond == (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT)
+      if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
         {
           /*
            * This is all we need to do to destroy a statically
@@ -604,7 +604,7 @@ cond_timedwait (pthread_cond_t * cond,
    * again inside the guarded section of _cond_check_need_init()
    * to avoid race conditions.
    */
-  if (*cond == (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*cond == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
     {
       result = _cond_check_need_init(cond);
     }
@@ -855,7 +855,7 @@ pthread_cond_signal (pthread_cond_t * cond)
    * No-op if the CV is static and hasn't been initialised yet.
    * Assuming that race conditions are harmless.
    */
-  if (cv == (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (cv == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
     {
       return 0;
     }
@@ -926,7 +926,7 @@ pthread_cond_broadcast (pthread_cond_t * cond)
    * No-op if the CV is static and hasn't been initialised yet.
    * Assuming that any race condition is harmless.
    */
-  if (cv == (pthread_cond_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (cv == (pthread_cond_t) PTW32_OBJECT_AUTO_INIT)
     {
       return 0;
     }
diff --git a/dll.c b/dll.c
index 7b0253f..15c1bda 100644
--- a/dll.c
+++ b/dll.c
@@ -82,7 +82,7 @@ DllMain (
       /*
        * The DLL is being mapped into the process's address space
        */
-      result = ptw32_rocessInitialize ();
+      result = ptw32_processInitialize ();
 
       /* Load KERNEL32 and try to get address of TryEnterCriticalSection */
       ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL"));
diff --git a/exit.c b/exit.c
index 146bf7a..2e55e7a 100644
--- a/exit.c
+++ b/exit.c
@@ -53,12 +53,6 @@ pthread_exit (void *value_ptr)
 {
   pthread_t self;
 
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-  DWORD exceptionInformation[3];
-
-#endif
-
   /* If the current thread is implicit it was not started through
      pthread_create(), therefore we cleanup and end the thread
      here. Otherwise we raise an exception to unwind the exception
@@ -70,7 +64,7 @@ pthread_exit (void *value_ptr)
 
   if (self == NULL || self->implicit)
     {
-      ptw32_allUserDestroyRoutines(self);
+      ptw32_callUserDestroyRoutines(self);
 
 #if ! defined (__MINGW32__) || defined (__MSVCRT__)
       _endthreadex ((unsigned) value_ptr);
@@ -83,39 +77,7 @@ pthread_exit (void *value_ptr)
 
   self->exitStatus = value_ptr;
 
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-  exceptionInformation[0] = (DWORD) (_PTHREAD_EPS_EXIT);
-  exceptionInformation[1] = (DWORD) (value_ptr);
-  exceptionInformation[2] = (DWORD) (0);
-
-  RaiseException (
-		  EXCEPTION_PTHREAD_SERVICES,
-		  0,
-		  3,
-		  exceptionInformation);
-
-#else /* ! _MSC_VER */
-
-#ifdef __cplusplus
-
-  throw Pthread_exception_exit();
-
-#else /* ! __cplusplus */
-
-  (void) pthread_pop_cleanup( 1 );
-
-  ptw32_callUserDestroyRoutines(self);
-
-#if ! defined (__MINGW32__) || defined (__MSVCRT__)
-  _endthreadex ((unsigned) value_ptr);
-#else
-  _endthread ();
-#endif
-
-#endif /* __cplusplus */
-
-#endif /* _MSC_VER */
+  ptw32_throw(PTW32_EPS_EXIT);
 
   /* Never reached. */
 
diff --git a/global.c b/global.c
index e55fc5b..a094459 100644
--- a/global.c
+++ b/global.c
@@ -30,7 +30,7 @@
 
 int ptw32_processInitialized = FALSE;
 pthread_key_t ptw32_selfThreadKey = NULL;
-pthread_key_t ptw32_leanupKey = NULL;
+pthread_key_t ptw32_cleanupKey = NULL;
 
 /*
  * Global lock for testing internal state of PTHREAD_MUTEX_INITIALIZER
diff --git a/implement.h b/implement.h
index 6cfcc75..4172618 100644
--- a/implement.h
+++ b/implement.h
@@ -96,7 +96,7 @@ struct pthread_t_ {
 /* 
  * Special value to mark attribute objects as valid.
  */
-#define _PTHREAD_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
+#define PTW32_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
 
 struct pthread_attr_t_ {
   unsigned long valid;
@@ -118,8 +118,8 @@ struct pthread_attr_t_ {
  * ====================
  */
 
-#define _PTHREAD_OBJECT_AUTO_INIT ((void *) -1)
-#define _PTHREAD_OBJECT_INVALID   NULL
+#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
+#define PTW32_OBJECT_INVALID   NULL
 
 struct pthread_mutex_t_ {
   HANDLE mutex;
@@ -282,51 +282,29 @@ struct ThreadKeyAssoc {
  * We store our actual component and error code within
  * the optional information array.
  */
-#define EXCEPTION_PTHREAD_SERVICES	\
+#define EXCEPTION_PTW32_SERVICES	\
      MAKE_SOFTWARE_EXCEPTION( SE_ERROR, \
-			      _PTHREAD_SERVICES_FACILITY, \
-			      _PTHREAD_SERVICES_ERROR )
+			      PTW32_SERVICES_FACILITY, \
+			      PTW32_SERVICES_ERROR )
 
-#define _PTHREAD_SERVICES_FACILITY		0xBAD
-#define _PTHREAD_SERVICES_ERROR			0xDEED
+#define PTW32_SERVICES_FACILITY		0xBAD
+#define PTW32_SERVICES_ERROR	       	0xDEED
 
 /*
- * Services available through EXCEPTION_PTHREAD_SERVICES
+ * Services available through EXCEPTION_PTW32_SERVICES
  */
-#define _PTHREAD_EPS_CANCEL       0
-#define _PTHREAD_EPS_EXIT         1
-
-/*
- * '__except' was redefined in pthread.h. We use the real one internally.
- */
-#ifdef __except
-#undef __except
-#endif
-
-#else
-
-#ifdef __cplusplus
-/*
- * 'catch' was redefined in pthread.h. We use the real one internally.
- */
-#ifdef catch
-#undef catch
-#endif
-
-#else /* __cplusplus */
-
-#warning File __FILE__, Line __LINE__: Cancellation not supported if library compiled as C.
-
-#endif /* __cplusplus */
+#define PTW32_EPS_CANCEL       0
+#define PTW32_EPS_EXIT         1
 
 #endif /* _MSC_VER */
 
+
 /* Function pointer to TryEnterCriticalSection if it exists; otherwise NULL */
 extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION);
 
 /* Declared in global.c */
 extern int ptw32_processInitialized;
-extern pthread_key_t ptw32_elfThreadKey;
+extern pthread_key_t ptw32_selfThreadKey;
 extern pthread_key_t ptw32_cleanupKey;
 extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
 extern CRITICAL_SECTION ptw32_cond_test_init_lock;
@@ -338,6 +316,8 @@ extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
 void *ptw32_calloc(size_t n, size_t s);
 #endif
 
+/* Declared in private.c */
+void ptw32_throw(DWORD exception);
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/misc.c b/misc.c
index ea38845..08de967 100644
--- a/misc.c
+++ b/misc.c
@@ -195,7 +195,7 @@ pthread_self (void)
 #endif
 	}
 
-      pthread_setspecific (ptw32_elfThreadKey, self);
+      pthread_setspecific (ptw32_selfThreadKey, self);
     }
 
   return (self);
@@ -327,30 +327,7 @@ CancelableWait (HANDLE waitHandle, DWORD timeout)
               /*
                * Thread started with pthread_create
                */
-
-#if defined(_MSC_VER) && !defined(__cplusplus)
-
-              DWORD exceptionInformation[3];
-
-              exceptionInformation[0] = (DWORD) (_PTHREAD_EPS_CANCEL);
-              exceptionInformation[1] = (DWORD) (0);
-              exceptionInformation[2] = (DWORD) (0);
-
-              RaiseException (
-                               EXCEPTION_PTHREAD_SERVICES,
-                               0,
-                               3,
-                               exceptionInformation);
-
-#else /* _MSC_VER */
-
-#ifdef __cplusplus
-
-	      throw Pthread_exception_cancel();
-
-#endif /* __cplusplus */
-
-#endif /* _MSC_VER */
+	      ptw32_throw(PTW32_EPS_CANCEL);
             }
 
          /* Should never get to here. */
diff --git a/mutex.c b/mutex.c
index 1ea7aab..3e0e484 100644
--- a/mutex.c
+++ b/mutex.c
@@ -66,7 +66,7 @@ _mutex_check_need_init(pthread_mutex_t *mutex)
    * re-initialise it only by calling pthread_mutex_init()
    * explicitly.
    */
-  if (*mutex == (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*mutex == (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
     {
       result = pthread_mutex_init(mutex, NULL);
     }
@@ -140,7 +140,7 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
     }
   else
     {
-      if (ptw32_ry_enter_critical_section != NULL
+      if (ptw32_try_enter_critical_section != NULL
 	  || (attr != NULL
 	      && *attr != NULL
 	      && (*attr)->forcecs == 1)
@@ -209,7 +209,7 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
   /*
    * Check to see if we have something to delete.
    */
-  if (*mutex != (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*mutex != (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
     {
       mx = *mutex;
 
@@ -239,7 +239,7 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
       /*
        * Check again.
        */
-      if (*mutex == (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)
+      if (*mutex == (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
         {
           /*
            * This is all we need to do to destroy a statically
@@ -354,22 +354,6 @@ pthread_mutexattr_destroy (pthread_mutexattr_t * attr)
 }                               /* pthread_mutexattr_destroy */
 
 
-int
-pthread_mutexattr_setforcecs_np(pthread_mutexattr_t *attr,
-				int forcecs)
-{
-  if (attr == NULL || *attr == NULL)
-    {
-      /* This is disallowed. */
-      return EINVAL;
-    }
-
-  (*attr)->forcecs = forcecs;
-
-  return 0;
-}
-
-
 int
 pthread_mutexattr_getpshared (const pthread_mutexattr_t * attr,
 			      int *pshared)
@@ -528,7 +512,7 @@ pthread_mutex_lock(pthread_mutex_t *mutex)
    * again inside the guarded section of _mutex_check_need_init()
    * to avoid race conditions.
    */
-  if (*mutex == (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*mutex == (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
     {
       result = _mutex_check_need_init(mutex);
     }
@@ -571,7 +555,7 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
    * race condition. If another thread holds the
    * lock then we shouldn't be in here.
    */
-  if (mx != (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (mx != (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
     {
       if (mx->mutex == 0)
 	{
@@ -607,7 +591,7 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
    * again inside the guarded section of _mutex_check_need_init()
    * to avoid race conditions.
    */
-  if (*mutex == (pthread_mutex_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*mutex == (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
     {
       result = _mutex_check_need_init(mutex);
     }
diff --git a/private.c b/private.c
index 2cdccac..0f8a175 100644
--- a/private.c
+++ b/private.c
@@ -62,7 +62,7 @@ ptw32_processInitialize (void)
       * ------------------------------------------------------
       */
 {
-	if (ptw32_rocessInitialized) {
+	if (ptw32_processInitialized) {
 		/* 
 		 * ignore if already initialized. this is useful for 
 		 * programs that uses a non-dll pthread
@@ -184,6 +184,7 @@ ptw32_threadStart (ThreadParms * threadParms)
   pthread_t self;
   void *(*start) (void *);
   void *arg;
+
 #ifdef _MSC_VER
   DWORD ei[] = {0,0,0};
 #endif
@@ -221,21 +222,21 @@ ptw32_threadStart (ThreadParms * threadParms)
     /*
      * Run the caller's routine;
      */
-    status = (*start) (arg);
+    status = self->exitStatus = (*start) (arg);
   }
   __except (ExceptionFilter(GetExceptionInformation(), ei))
   {
     DWORD ec = GetExceptionCode();
 
-    if (ec == EXCEPTION_PTHREAD_SERVICES)
+    if (ec == EXCEPTION_PTW32_SERVICES)
       {
 	switch (ei[0])
 	  {
-	  case _PTHREAD_EPS_CANCEL:
+	  case PTW32_EPS_CANCEL:
 	    status = PTHREAD_CANCELED;
 	    break;
-	  case _PTHREAD_EPS_EXIT:
-	    status = (void *) ei[1];
+	  case PTW32_EPS_EXIT:
+	    status = self->exitStatus;
 	    break;
 	  default:
 	    status = PTHREAD_CANCELED;
@@ -247,7 +248,7 @@ ptw32_threadStart (ThreadParms * threadParms)
 	/*
 	 * A system unexpected exception had occurred running the user's
 	 * routine. We get control back within this block because
-         * we can't allow the exception out of thread scope.
+         * we can't allow the exception to pass out of thread scope.
 	 */
 	status = PTHREAD_CANCELED;
       }
@@ -264,14 +265,14 @@ ptw32_threadStart (ThreadParms * threadParms)
      */
     status = self->exitStatus = (*start) (arg);
   }
-  catch (Pthread_exception_cancel)
+  catch (ptw32_exception_cancel)
     {
       /*
        * Thread was cancelled.
        */
       status = self->exitStatus = PTHREAD_CANCELED;
     }
-  catch (Pthread_exception_exit)
+  catch (ptw32_exception_exit)
     {
       /*
        * Thread was exited via pthread_exit().
@@ -294,7 +295,7 @@ ptw32_threadStart (ThreadParms * threadParms)
    * Run the caller's routine; no cancelation or other exceptions will
    * be honoured.
    */
-  status = (*start) (arg);
+  status = self->exitStatus = (*start) (arg);
 
 #endif /* __cplusplus */
 
@@ -800,7 +801,7 @@ ptw32_get_exception_services_code(void)
 {
 #if defined(_MSC_VER) && !defined(__cplusplus)
 
-  return EXCEPTION_PTHREAD_SERVICES;
+  return EXCEPTION_PTW32_SERVICES;
 
 #else
 
@@ -808,3 +809,49 @@ ptw32_get_exception_services_code(void)
 
 #endif
 }
+
+
+void
+ptw32_throw(DWORD exception)
+{
+  if (exception != PTW32_EPS_CANCEL ||
+      exception != PTW32_EPS_EXIT)
+    {
+      /* Should never enter here */
+      exit(1);
+    }
+
+#if defined(_MSC_VER) && !defined(__cplusplus)
+
+  DWORD exceptionInformation[3];
+
+  exceptionInformation[0] = (DWORD) (exception);
+  exceptionInformation[1] = (DWORD) (0);
+  exceptionInformation[2] = (DWORD) (0);
+
+  RaiseException (
+		  EXCEPTION_PTW32_SERVICES,
+		  0,
+		  3,
+		  exceptionInformation);
+
+#else /* _MSC_VER && ! __cplusplus */
+
+# ifdef __cplusplus
+
+  switch (exception)
+    {
+    case PTW32_EPS_CANCEL:
+      throw ptw32_exception_cancel();
+      break;
+    case PTW32_EPS_EXIT:
+      throw ptw32_exception_exit();
+      break;
+    }
+
+# endif /* __cplusplus */
+
+#endif /* _MSC_VER && ! __cplusplus */
+
+  /* Never reached */
+}
diff --git a/pthread.def b/pthread.def
index 9ddf1a5..395f156 100644
--- a/pthread.def
+++ b/pthread.def
@@ -1,5 +1,5 @@
 ; pthread.def
-; Last updated: $Date: 2000/08/17 10:18:36 $
+; Last updated: $Date: 2000/08/18 08:02:29 $
 
 ; Currently unimplemented functions are commented out.
 
@@ -102,6 +102,7 @@ pthread_rwlock_unlock
 ; Non-portable but useful
 ;
 pthread_mutexattr_setforcecs_np
+pthread_getw32threadhandle_np
 pthreadCancelableWait
 pthreadCancelableTimedWait
 ;
diff --git a/pthread.h b/pthread.h
index a853191..ead9424 100644
--- a/pthread.h
+++ b/pthread.h
@@ -821,9 +821,6 @@ int pthread_mutexattr_getpshared (const pthread_mutexattr_t
 int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
 				  int pshared);
 
-int pthread_mutexattr_setforcecs_np(pthread_mutexattr_t *attr,
-				    int forcecs);
-
 /*
  * Mutex Functions
  */
@@ -873,7 +870,6 @@ int pthread_cond_broadcast (pthread_cond_t * cond);
 /*
  * Scheduling
  */
-
 int pthread_setschedparam (pthread_t thread,
 			   int policy,
 			   const struct sched_param *param);
@@ -891,7 +887,6 @@ int pthread_attr_setschedparam (pthread_attr_t *attr,
 /*
  * Read-Write Lock Functions
  */
-
 int pthread_rwlock_init(pthread_rwlock_t *lock,
                                const pthread_rwlockattr_t *attr);
 
@@ -907,6 +902,15 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *lock);
 
 int pthread_rwlock_unlock(pthread_rwlock_t *lock);
 
+/*
+ * Non-portable functions
+ */
+int pthread_mutexattr_setforcecs_np(pthread_mutexattr_t *attr,
+				    int forcecs);
+
+HANDLE pthread_getw32threadhandle_np(pthread_t thread);
+
+
 /*
  * Protected Methods
  *
@@ -966,8 +970,21 @@ int * _errno( void );
 	rand()
 
 
-/* FIXME: This is only required if the library was built using SEH */
+#ifdef __cplusplus
+
 /*
+ * Internal exceptions
+ */
+class ptw32_exception {};
+class ptw32_exception_cancel : public ptw32_exception {};
+class ptw32_exception_exit   : public ptw32_exception {};
+
+#endif
+
+#ifndef PTW32_BUILD
+
+/* FIXME: This is only required if the library was built using SEH */
+ *
  * Get internal SEH tag
  */
 DWORD ptw32_get_exception_services_code(void);
@@ -986,13 +1003,6 @@ DWORD ptw32_get_exception_services_code(void);
 
 #ifdef __cplusplus
 
-/*
- * Internal exceptions
- */
-class Pthread_exception {};
-class Pthread_exception_cancel : public Pthread_exception {};
-class Pthread_exception_exit   : public Pthread_exception {};
-
 /*
  * Redefine the C++ catch keyword to ensure that applications
  * propagate our internal exceptions up to the library's internal handlers.
@@ -1002,21 +1012,30 @@ class Pthread_exception_exit   : public Pthread_exception {};
          * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
          * if you want Pthread-Win32 cancelation and pthread_exit to work.
          */
+
 #ifndef PtW32NoCatchWarn
+
 #pragma message("When compiling applications with MSVC++ and C++ exception handling:")
 #pragma message("  Replace any 'catch( ... )' with 'PtW32CatchAll' in POSIX threads")
 #pragma message("  if you want POSIX thread cancelation and pthread_exit to work.")
+
 #endif
+
 #define PtW32CatchAll \
-        catch( Pthread_exception & ) { throw; } \
+        catch( ptw32_exception & ) { throw; } \
         catch( ... )
-#else
+
+#else /* _MSC_VER */
+
 #define catch( E ) \
-        catch( Pthread_exception & ) { throw; } \
+        catch( ptw32_exception & ) { throw; } \
         catch( E )
-#endif
 
-#endif
+#endif /* _MSC_VER */
+
+#endif /* __cplusplus */
+
+#endif /* ! PTW32_BUILD */
 
 #ifdef __cplusplus
 }				/* End of extern "C" */
diff --git a/rwlock.c b/rwlock.c
index f476b8a..d02461c 100644
--- a/rwlock.c
+++ b/rwlock.c
@@ -64,7 +64,7 @@ _rwlock_check_need_init(pthread_rwlock_t *rwlock)
    * re-initialise it only by calling pthread_rwlock_init()
    * explicitly.
    */
-  if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+  if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
     {
       result = pthread_rwlock_init(rwlock, NULL);
     }
@@ -158,7 +158,7 @@ pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
         return(EINVAL);
       }
 
-    if (*rwlock != (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+    if (*rwlock != (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
       {
         rw = *rwlock;
 
@@ -197,12 +197,12 @@ pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
         /*
          * See notes in _rwlock_check_need_init() above also.
          */
-        EnterCriticalSection(&ptw32_wlock_test_init_lock);
+        EnterCriticalSection(&ptw32_rwlock_test_init_lock);
 
         /*
          * Check again.
          */
-        if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+        if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
           {
             /*
              * This is all we need to do to destroy a statically
@@ -254,7 +254,7 @@ pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
      * again inside the guarded section of _rwlock_check_need_init()
      * to avoid race conditions.
      */
-    if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+    if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
       {
         result = _rwlock_check_need_init(rwlock);
 
@@ -332,7 +332,7 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock)
      * again inside the guarded section of _rwlock_check_need_init()
      * to avoid race conditions.
      */
-    if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+    if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
       {
         result = _rwlock_check_need_init(rwlock);
 
@@ -389,7 +389,7 @@ pthread_rwlock_unlock(pthread_rwlock_t * rwlock)
         return(EINVAL);
       }
 
-    if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+    if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
       {
         /*
          * Assume any race condition here is harmless.
@@ -463,7 +463,7 @@ pthread_rwlock_tryrdlock(pthread_rwlock_t * rwlock)
      * again inside the guarded section of _rwlock_check_need_init()
      * to avoid race conditions.
      */
-    if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+    if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
       {
         result = _rwlock_check_need_init(rwlock);
 
@@ -518,7 +518,7 @@ pthread_rwlock_trywrlock(pthread_rwlock_t * rwlock)
      * again inside the guarded section of _rwlock_check_need_init()
      * to avoid race conditions.
      */
-    if (*rwlock == (pthread_rwlock_t) _PTHREAD_OBJECT_AUTO_INIT)
+    if (*rwlock == (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)
       {
         result = _rwlock_check_need_init(rwlock);
 
diff --git a/sched.c b/sched.c
index a4451ce..0f83a43 100644
--- a/sched.c
+++ b/sched.c
@@ -34,7 +34,7 @@ is_attr(const pthread_attr_t *attr)
 {
   return (attr == NULL || 
 	  *attr == NULL || 
-	  (*attr)->valid != _PTHREAD_ATTR_VALID) ? 1 : 0;
+	  (*attr)->valid != PTW32_ATTR_VALID) ? 1 : 0;
 }
 
 int
diff --git a/tsd.c b/tsd.c
index 3c06782..491769f 100644
--- a/tsd.c
+++ b/tsd.c
@@ -233,7 +233,7 @@ pthread_setspecific (pthread_key_t key, const void *value)
        * Resolve catch-22 of registering thread with threadSelf
        * key
        */
-      self = (pthread_t) pthread_getspecific (ptw32_elfThreadKey);
+      self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey);
       if (self == NULL)
         {
           self = (pthread_t) value;
-- 
cgit v1.2.3