diff options
| -rw-r--r-- | ANNOUNCE | 177 | ||||
| -rw-r--r-- | CONTRIBUTORS | 7 | ||||
| -rw-r--r-- | ChangeLog | 5997 | ||||
| -rw-r--r-- | GNUmakefile | 71 | ||||
| -rw-r--r-- | Makefile | 23 | ||||
| -rw-r--r-- | attr.c | 33 | ||||
| -rw-r--r-- | cancel.c | 25 | ||||
| -rw-r--r-- | cleanup.c | 74 | ||||
| -rw-r--r-- | create.c | 5 | ||||
| -rw-r--r-- | dll.c | 8 | ||||
| -rw-r--r-- | errno.c | 2 | ||||
| -rw-r--r-- | exit.c | 1 | ||||
| -rw-r--r-- | global.c | 7 | ||||
| -rw-r--r-- | implement.h | 65 | ||||
| -rw-r--r-- | misc.c | 51 | ||||
| -rw-r--r-- | mutex.c | 331 | ||||
| -rw-r--r-- | nonportable.c | 149 | ||||
| -rw-r--r-- | private.c | 151 | ||||
| -rw-r--r-- | pthread.def | 17 | ||||
| -rw-r--r-- | pthread.h | 368 | ||||
| -rw-r--r-- | rwlock.c | 436 | ||||
| -rw-r--r-- | sched.h | 25 | ||||
| -rw-r--r-- | semaphore.c | 8 | ||||
| -rw-r--r-- | tests/ChangeLog | 951 | ||||
| -rw-r--r-- | tests/GNUmakefile | 119 | ||||
| -rw-r--r-- | tests/Makefile | 102 | ||||
| -rw-r--r-- | tests/condvar7.c | 6 | ||||
| -rw-r--r-- | tests/exception1.c | 2 | ||||
| -rw-r--r-- | tests/exception2.c | 8 | ||||
| -rw-r--r-- | tests/exception3.c | 2 | ||||
| -rw-r--r-- | tests/eyal1.c | 2 | ||||
| -rw-r--r-- | tests/mutex1.c | 4 | ||||
| -rw-r--r-- | tests/rwlock6.c | 34 | ||||
| -rw-r--r-- | tsd.c | 8 | 
34 files changed, 4802 insertions, 4467 deletions
@@ -1,5 +1,5 @@ -                 PTHREADS-WIN32 SNAPSHOT 2000-12-29
 +                 PTHREADS-WIN32 SNAPSHOT ????-??-??
                   ----------------------------------
         Web Site: http://sources.redhat.com/pthreads-win32/
        FTP Site: ftp://sources.redhat.com/pub/pthreads-win32
 @@ -13,6 +13,10 @@ Win32 environment. Some functions from POSIX 1003.1b are also  supported including semaphores. Other related functions include
  the set of read-write lock functions.
 +Parts of the implementation also comply with the Open Group's
 +Unix 98 specification for compatibility with major Unix
 +implementations and Linux.
 +
  Pthreads-win32 is free software, distributed under the GNU Library
  General Public License (LGPL).
 @@ -26,57 +30,114 @@ Change Summary (since the last snapshot)  (See the ChangeLog file for details.)
  New:
 --	New non-portable functions for use when statically linking the library
 -	(see the README file):
 -		pthread_delay_np
 -		pthread_win32_process_attach_np
 -		pthread_win32_process_detach_np
 -		pthread_win32_thread_attach_np
 -		pthread_win32_thread_detach_np
 -	Also, the start of support within the library for statically
 -	linked applications, but this has not been tested by statically
 -	linking yet.
 --	A fully working MinGW32 g++ compiled version of the library
 -	is now supplied. To use with g++ compiled applications
 -	please see the FAQ "How do I generate pthreadGCE.dll and
 -	libpthreadw32.a for use with Mingw32", which you need to do
 -	before compiling and linking applications as well.
 --	Unhandled exceptions, whether SEH or C++, are no longer
 -	silently caught and ignored but are passed out of threads for
 -	the system to deal with. C++ applications can override
 -	the default termination handler via set_terminate().
 -	set_terminate() works fine for MinGW32 g++ but not yet with MS VC++
 -	(see known bugs (2)) even though it's the same code. See
 -	tests/exception3.c for an example of using set_terminate().
 +-	Async cancellation should now work for Windows running
 +	on the following processors: IX86, MIPS, ALPHA, PPC.
 +	- contributors name misplaced (please contact me if it's you)
 + 
 +-       New functions (no-ops) for source code compatibility:
 +                pthread_getconcurrency()
 +                        Returns the value previously set by
 +			pthread_setconcurrency() or 0 (zero)
 +			if no value was previously set.
 +			The implementation does not currently use
 +			this value.
 +                pthread_setconcurrency()
 +                        Accepts any value >= 0 but does not
 +                        have any effect; returns '0' or
 +                        EINVAL if the value is < 0
 +                pthread_attr_getscope()
 +                pthread_attr_setscope()
 +                        Currently only return ENOSYS
 +
 +-       The following mutex types and related functions are now
 +        supported:
 +
 +                pthread_mutexattr_gettype()
 +                pthread_mutexattr_settype()
 +                PTHREAD_MUTEX_DEFAULT
 +                PTHREAD_MUTEX_NORMAL or PTHREAD_MUTEX_FAST_NP
 +                PTHREAD_MUTEX_ERRORCHECK or PTHREAD_MUTEX_ERRORCHECK_NP
 +                PTHREAD_MUTEX_RECURSIVE or PTHREAD_MUTEX_RECURSIVE_NP
 +
 +	The *_NP versions are for Linux portability.
 +
 +        In this implementation PTHREAD_MUTEX_DEFAULT is
 +        mapped to PTHREAD_MUTEX_NORMAL for compatibility
 +	with major Unix vendors. This is also the default
 +	if no type is specified.
 +
 +	Please note that the default behaviour in previous
 +	versions of the library was equivalent to
 +	PTHREAD_MUTEX_RECURSIVE. This will be a problem
 +	for some applications unless they are updated to
 +	explicitly set the type of any mutexes that are, or
 +	could be, locked recursively.
 +
 +        PTHREAD_MUTEX_NORMAL will cause thread deadlock
 +        if the owner of a mutex tries to relock it without
 +        first unlocking it. It has slightly less overhead
 +	that other types.
 +
 +-       Pthreads-win32 mutexes are now based on Win32
 +        critical sections for all Windows versions. The
 +	implementation no longer depends on
 +	TryEnterCriticalSection.
 +        - Thomas Pfaff <tpfaff@gmx.net>
  Bugs fixed:
 --	Pthread_mutex_unlock() now returns EPERM if the unlocking
 -	thread does not currently hold the thread.
 --	Args in the ctime_r macro in pthread.h are fixed.
 --	Made semaphore.h independent of config.h when building
 -	applications. Don't know how this went unnoticed for so long
 -	- the default defines must have been correct for my test
 -	environment.
 -
 -Some new tests have been added.
 +-       Pthread_mutex_trylock() now properly returns EBUSY
 +        even when the current thread owns the mutex.
 +        Consequently, pthread_mutex_destroy() will no longer
 +        destroy a locked mutex (it will return EBUSY).
 +        - Thomas Pfaff <tpfaff@gmx.net>
 +-	Errno warnings and building with /MD;
 +	calling conventions (stdcall v cdecl);
 +	thread termination problems;
 +	- Milan Gardian <Milan.Gardian@LEIBINGER.com>
  Known bugs in this snapshot
  ---------------------------
 -1. Asynchronous cancelation only works on Intel X86 machines.
 -
 -2. Under MS VC++ (only tested with version 6.0), a term_func
 +1. Under MS VC++ (only tested with version 6.0), a term_func
     set via the standard C++ set_terminate() function is not called
     for some reason. The code - in private.c:ptw32_threadStart() -
     makes an explicit call to terminate() which works as expected
     under MinGW32 g++ doesn't appear to run the term_func under
     MC VC++ 6.0.
 -3. This is an interim snapshot as there are still some additional
 -   patches to go in, eg. to fix problems with errno support under
 -   some circumstances. Some people are seeing compile warnings
 -   to do with _errno.
 +2. Cancellation problems in optimised code
 +   - Milan Gardian
 +
 +   The cancellation (actually, cleanup-after-cancel) tests fail when using VC
 +   (professional) optimisation switches (/O1 or /O2) in pthreads library. I
 +   have not investigated which concrete optimisation technique causes this
 +   problem (/Og, /Oi, /Ot, /Oy, /Ob1, /Gs, /Gf, /Gy, etc.), but here is a
 +   summary of builds and corresponding failures:
 +
 +     * pthreads VSE (optimised tests): OK
 +     * pthreads VCE (optimised tests): Failed "cleanup1" test (runtime)
 +   
 +     * pthreads VSE (DLL in CRT, optimised tests): OK
 +     * pthreads VCE (DLL in CRT, optimised tests): Failed "cleanup1" test
 +   (runtime)
 +
 +   Please note that while in VSE version of the pthreads library the
 +   optimisation does not really have any impact on the tests (they pass OK), in
 +   VCE version addition of optimisation (/O2 in this case) causes the tests to
 +   fail uniformly - either in "cleanup0" or "cleanup1" test cases.
 +   
 +   Please note that all the tests above use default pthreads DLL (no
 +   optimisations, linked with either static or DLL CRT, based on test type).
 +   Therefore the problem lies not within the pthreads DLL but within the
 +   compiled client code (the application using pthreads -> involvement of
 +   "pthread.h").
 +
 +   I think the message of this section is that usage of VCE version of pthreads
 +   in applications relying on cancellation/cleanup AND using optimisations for
 +   creation of production code is highly unreliable for the current version of
 +   the pthreads library.
 +
  Caveats
  -------
 @@ -166,7 +227,11 @@ The following functions are implemented:        pthread_mutexattr_destroy
        pthread_mutexattr_getpshared
        pthread_mutexattr_setpshared
 -
 +      pthread_mutexattr_gettype
 +      pthread_mutexattr_settype (types: PTHREAD_MUTEX_DEFAULT
 +                                        PTHREAD_MUTEX_NORMAL
 +                                        PTHREAD_MUTEX_ERRORCHECK
 +                                        PTHREAD_MUTEX_RECURSIVE  )
        pthread_mutex_init
        pthread_mutex_destroy
        pthread_mutex_lock
 @@ -219,6 +284,10 @@ The following functions are implemented:        pthread_attr_setschedparam  
        pthread_getschedparam
        pthread_setschedparam
 +      pthread_getconcurrency (always returns '0' indicating system default)
 +      pthread_setconcurrency (accepts any value >= 0 but is ignored)
 +      pthread_attr_getscope  (returns an error ENOSYS)
 +      pthread_attr_setscope  (returns an error ENOSYS)
        sched_get_priority_max (POSIX 1b)
        sched_get_priority_min (POSIX 1b)
        sched_yield            (POSIX 1b)
 @@ -229,15 +298,15 @@ The following functions are implemented:        pthread_sigmask
        ---------------------------
 -      Non-portable routines (see the README file for usage)
 +      Non-portable routines (see the README.NONPORTABLE file for usage)
        ---------------------------
 -      pthread_mutexattr_setforcecs_np
        pthread_getw32threadhandle_np
 -	pthread_delay_np
 -	pthread_win32_process_attach_np
 -	pthread_win32_process_detach_np
 -	pthread_win32_thread_attach_np
 -	pthread_win32_thread_detach_np
 +      pthread_delay_np
 +      pthread_mutex_setdefaulttype_np
 +      pthread_win32_process_attach_np
 +      pthread_win32_process_detach_np
 +      pthread_win32_thread_attach_np
 +      pthread_win32_thread_detach_np
        ---------------------------
        Static Initializers (macros)
 @@ -265,10 +334,8 @@ The following functions are not implemented:        ---------------------------
        pthread_attr_getinheritsched
        pthread_attr_getschedpolicy
 -      pthread_attr_getscope
        pthread_attr_setinheritsched
        pthread_attr_setschedpolicy
 -      pthread_attr_setscope
        pthread_mutex_getprioceiling
        pthread_mutex_setprioceiling
        pthread_mutex_attr_getprioceiling
 @@ -344,20 +411,22 @@ Mailing List  There is a mailing list for discussing pthreads on Win32. To join,
  send email to:
 -        pthreads-win32-subscribe@sources.redhat.com
 +        pthreads-win32-subscribe@sourceware.cygnus.com
  Application Development Environments
  ------------------------------------
  MSVC:
 -MSVC using SEH works.
 -MSVC using C++ EH works.
 +MSVC using SEH works. Distribute pthreadVSE.dll with your application.
 +MSVC using C++ EH works. Distribute pthreadVCE.dll with your application.
  Mingw32:
  You need gcc-2.95.2-1 modified as per pthreads-win32 FAQ answer (6), with
  binutils-19990818-1 and msvcrt runtime-2000-03-27. Mingw32 must use
 -the thread-safe MSVCRT library (see the FAQ).
 +the thread-safe MSVCRT library (see the FAQ). You need to distribute
 +the gcc.dll DLL from Mingw32 with your application (as well as
 +pthreadGCE.dll of course).
  Cygwin: (http://sourceware.cygnus.com/cygwin/)
  Cygwin aims to provide a complete POSIX environment on top of Win32, including
 @@ -382,7 +451,7 @@ For convenience, the following pre-built files are available on the FTP site  	pthreadVCE.lib
  	pthreadVSE.dll	- built with MSVC compiler using SEH
  	pthreadVSE.lib
 -	pthreadGCE.dll	- built with Mingw32 G++
 +	pthreadGCE.dll	- built with Mingw32 G++ 2.95.2-1 
  	libpthreadw32.a	- derived from pthreadGCE.dll
  These are the only files you need in order to build POSIX threads
 diff --git a/CONTRIBUTORS b/CONTRIBUTORS index aa4dd3e..74fe21b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,5 +1,8 @@  Contributors (in approximate order of appearance)
 +[See also the ChangeLog file where individuals are
 +attributed in log entries. Likewise in the FAQ file.]
 +
  Ben Elliston		bje@cygnus.com
  Ross Johnson		rpj@ise.canberra.edu.au
  Robert Colquhoun	rjc@trump.net.au
 @@ -26,4 +29,6 @@ David Baggett	        dmb.itasoftware.com  Paul Redondo	        paul.matchvision.com
  Scott McCaskill	        scott.3dfx.om
  Thomas Pfaff            tpfaff@gmx.net
 -Franco Bez              ???
 +Franco Bez              franco.bez@gmx.de
 +Alexander Terekhov      TEREKHOV@de.ibm.com
 +Louis Thomas		lthomas@arbitrade.com
 @@ -1,2957 +1,3040 @@ -2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* Makefile: Back-out "for" loops which don't work. - -	* GNUmakefile: Remove the fake.a target; add the "realclean" -	target; don't remove built libs under the "clean" target. - -	* config.h: Add a guard against multiple inclusion. - -	* semaphore.h: Add some defines from config.h to make -	semaphore.h independent of config.h when building apps. - -	* pthread.h (_errno): Back-out previous fix until we know how to -	fix it properly. - -	* implement.h (lockCount): Add missing element to pthread_mutex_t_. - -	* sync.c (pthread_join): Spelling fix in comment. - -	* private.c (ptw32_threadStart): Reset original termination -	function (C++). -	(ptw32_threadStart): Cleanup detached threads early in case -	the library is statically linked. -	(ptw32_callUserDestroyRoutines): Remove [SEH] __try block from -	destructor call so that unhandled exceptions will be passed through -	to the 	system; call terminate() from [C++] try block for the same -	reason. - -	* tsd.c (pthread_getspecific): Add comment. - -	* mutex.c (pthread_mutex_init): Initialise new elements in -	pthread_mutex_t. -	(pthread_mutex_unlock): Invert "pthread_equal()" test. - -2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition. - -	* config.h.in (HAVE_MODE_T): Added. -	(_UWIN): Start adding defines for the UWIN package. - -	* private.c (ptw32_threadStart): Unhandled exceptions are -	now passed through to the system to deal with. This is consistent -	with normal Windows behaviour. C++ applications may use -	set_terminate() to override the default behaviour which is -	to call ptw32_terminate(). Ptw32_terminate() cleans up some -	POSIX thread stuff before calling the system default function -	which calls abort(). The users termination function should conform -	to standard C++ semantics which is to not return. It should -	exit the thread (call pthread_exit()) or exit the application. -	* private.c (ptw32_terminate): Added as the default set_terminate() -	function. It calls the system default function after cleaning up -	some POSIX thread stuff. - -	* implement.h (ptw32_try_enter_critical_section): Move -	declaration. -	* global.c (ptw32_try_enter_critical_section): Moved -	from dll.c. -	* dll.c: Move process and thread attach/detach code into -	functions in nonportable.c. -	* nonportable.c (pthread_win32_process_attach_np): Process -	attach code from dll.c is now available to static linked -	applications. -	* nonportable.c (pthread_win32_process_detach_np): Likewise. -	* nonportable.c (pthread_win32_thread_attach_np): Likewise. -	* nonportable.c (pthread_win32_thread_detach_np): Likewise. - -	* pthread.h: Add new non-portable prototypes for static -	linked applications. - -	* GNUmakefile (OPT): Increase optimisation flag and remove -	debug info flag. - -	* pthread.def: Add new non-portable exports for static -	linked applications. - -2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* FAQ: Update Answer 6 re getting a fully working -	Mingw32 built library. - -2000-10-10  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> -  -        * misc.c (pthread_self): Restore Win32 "last error" -        cleared by TlsGetValue() call in -        pthread_getspecific() -        - "Steven Reddie" <smr@essemer.com.au> -  -2000-09-20  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> -  -        * mutex.c (pthread_mutex_lock): Record the owner -        of the mutex. This requires also keeping count of -        recursive locks ourselves rather than leaving it -        to Win32 since we need to know when to NULL the -        thread owner when the mutex is unlocked. -        (pthread_mutex_trylock): Likewise. -        (pthread_mutex_unlock): Check that the calling -        thread owns the mutex, decrement the recursive -        lock count, and NULL the owner if zero. Return -        EPERM if the mutex is owned by another thread. -        * implement.h (pthread_mutex_t_): Add ownerThread -        and lockCount members. -        - reported by Arthur Kantor <akantor@bexusa.com> - -2000-09-13  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> - -	* mutex.c (pthread_mutex_init): Call -	TryEnterCriticalSection through the pointer -	rather than directly so that the dll can load -	on Windows versions that can't resolve the -	function, eg. Windows 95 -	- "Jef Gearhart" <jgearhart@tpssys.com> - -2000-09-09  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* pthread.h (ctime_r): Fix arg. - -2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS; -	doesn't seem to be needed though. - -	* cancel.c (pthread_cancel): Must get "self" through -	calling pthread_self() which will ensure a POSIX thread -	struct is built for non-POSIX threads; return an error -	if this fails -	- Ollie Leahy <ollie@mpt.ie> -	(pthread_setcancelstate): Likewise. -	(pthread_setcanceltype): Likewise. -	* misc.c (ptw32_cancelable_wait): Likewise. - -	* private.c (ptw32_tkAssocCreate): Remove unused #if 0 -	wrapped code. - -	* pthread.h (ptw32_get_exception_services_code): -	Needed to be forward declared unconditionally. - -2000-09-06  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cancel.c (pthread_cancel): If called from the main -	thread "self" would be NULL; get "self" via pthread_self() -	instead of directly from TLS so that an implicit -	pthread object is created. - -	* misc.c (pthread_equal): Strengthen test for NULLs. - -2000-09-02  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* condvar.c (ptw32_cond_wait_cleanup): Ensure that all -	waking threads check if they are the last, and notify -	the broadcaster if so - even if an error occurs in the -	waiter. - -	* semaphore.c (_decrease_semaphore): Should be -	a call to ptw32_decrease_semaphore. -	(_increase_semaphore): Should be a call to -	ptw32_increase_semaphore. - -	* misc.c (ptw32_cancelable_wait): Renamed from -	CancelableWait. -	* rwlock.c (_rwlock_check*): Renamed to -	ptw32_rwlock_check*. -	* mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*. -	* condvar.c (cond_timed*): Renamed to ptw32_cond_timed*. -	(_cond_check*): Renamed to ptw32_cond_check*. -	(cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*. -	(ptw32_cond_timedwait): Add comments. - -2000-08-22  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> - -	* private.c (ptw32_throw): Fix exception test; -	move exceptionInformation declaration. - -	* tsd.c (pthread_key_create): newkey wrongly declared. - -	* pthread.h: Fix comment block. - -2000-08-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> - -	* mutex.c (pthread_mutex_destroy): Check that the mutex isn't -	held; invalidate the mutex as early as possible to avoid -	contention; not perfect - FIXME! - -	* rwlock.c (pthread_rwlock_init): Remove redundant assignment -	to "rw". -	(pthread_rwlock_destroy): Invalidate the rwlock before -	freeing up any of it's resources - to avoid contention. - -	* private.c (ptw32_tkAssocCreate): Change assoc->lock -	to use a dynamically initialised mutex - only consumes -	a W32 mutex or critical section when first used, -	not before. - -	* mutex.c (pthread_mutex_init): Remove redundant assignment -	to "mx". -	(pthread_mutexattr_destroy): Set attribute to NULL -	before freeing it's memory - to avoid contention. - -	* implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT): -	Must be defined for all compilers - used as generic -	exception selectors by ptw32_throw(). - -	* 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 -	ptw32_ prefix to remove leading underscores -	from private library identifiers (single -	and double leading underscores are reserved in the -	ANSI C standard for compiler implementations). - -	* tsd.c (pthread_create_key): Initialise temporary -	key before returning it's address to avoid race -	conditions. - -2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* errno.c: Add _MD precompile condition; thus far -	had no effect when using /MD compile option but I -	thnk it should be there. - -	* exit.c: Add __cplusplus to various #if lines; -	was compiling SEH code even when VC++ had -	C++ compile options. - -	* private.c: ditto. - -	* create.c (pthread_create): Add PT_STDCALL macro to -	function pointer arg in _beginthread(). - -	* pthread.h: PT_STDCALL really does need to be defined -	in both this and impliment.h; don't set it to __cdecl -	- this macro is only used to extend function pointer -	casting for functions that will be passed as parameters. -	(~PThreadCleanup): add cast and group expression. -	(_errno): Add _MD compile conditional. -	(PtW32NoCatchWarn): Change pragma message. - -	* implement.h: Move and change PT_STDCALL define. - -	* need_errno.h: Add _MD to compilation conditional. - -	* GNUmakefile: Substantial rewrite for new naming -	convention; set for nil optimisation (turn it up -	when we have a working library build; add target -	"fake.a" to build a libpthreadw32.a from the VC++ -	built DLL pthreadVCE.dll. - -	* pthread.def (LIBRARY): Don't specify in the .def -	file - it is specified on the linker command line -	since we now use the same .def file for variously -	named .dlls. - -	* Makefile: Substantial rewrite for new naming -	convention; default nmake target only issues a -	help message; run nmake with specific target -	corresponding to the EH scheme being used. - -	* README: Update information; add naming convention -	explanation. - -	* ANNOUNCE: Update information. - -2000-08-12  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* pthread.h: Add compile-time message when using -	MSC_VER compiler and C++ EH to warn application -	programmers to use PtW32Catch instead of catch(...) -	if they want cancelation and pthread_exit to work. - -	* implement.h: Remove #include <semaphore.h>; we -	use our own local semaphore.h. - -2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cleanup.c (pthread_pop_cleanup): Remove _pthread -	prefix from __except and catch keywords; implement.h -	now simply undefines ptw32__except and -	ptw32_catch if defined; VC++ was not textually -	substituting ptw32_catch etc back to catch as -	it was redefined; the reason for using the prefixed -	version was to make it clear that it was not using -	the pthread.h redefined catch keyword. - -	* private.c (ptw32_threadStart): Ditto. -	(ptw32_callUserDestroyRoutines): Ditto. - -	* implement.h (ptw32__except): Remove #define. -	(ptw32_catch): Remove #define. - -	* GNUmakefile (pthread.a): New target to build -	libpthread32.a from pthread.dll using dlltool. - -	* buildlib.bat: Duplicate cl commands with args to -	build C++ EH version of pthread.dll; use of .bat -	files is redundant now that nmake compatible -	Makefile is included; used as a kludge only now. - -	* Makefile: Localise some macros and fix up the clean: -	target to extend it and work properly. - -	* CONTRIBUTORS: Add contributors. - -	* ANNOUNCE: Updated. - -	* README: Updated. - -2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* pthread.h: Remove #warning - VC++ doesn't accept it. - -2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* pthread.h (PtW32CatchAll): Add macro. When compiling -	applications using VC++ with C++ EH rather than SEH -	'PtW32CatchAll' must be used in place of any 'catch( ... )' -	if the application wants pthread cancelation or -	pthread_exit() to work. - -2000-08-03  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* pthread.h: Add a base class ptw32_exception for -	library internal exceptions and change the "catch" -	re-define macro to use it. - -2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* GNUmakefile (CFLAGS): Add -mthreads. -	Add new targets to generate cpp and asm output. - -	* sync.c (pthread_join): Remove dead code. - -2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* sched.c (sched_get_priority_max): Handle different WinCE and -	Win32 priority values together. -	(sched_get_priority_min): Ditto. -	- Tristan Savatier <tristan@mpegtv.com> - -	* create.c (pthread_create): Force new threads to wait until -	pthread_create has the new thread's handle; we also retain -	a local copy of the handle for internal use until -	pthread_create returns. - -	* private.c (ptw32_threadStart): Initialise ei[]. -	(ptw32_threadStart): When beginthread is used to start the -	thread, force waiting until the creator thread had the  -	thread handle. - -	* cancel.c (ptw32_cancel_thread): Include context switch -	code for defined(_X86_) environments in addition to _M_IX86. - -	* rwlock.c (pthread_rwlock_destroy): Assignment changed -	to avoid compiler warning. - -	* private.c (ptw32_get_exception_services_code): Cast -	NULL return value to avoid compiler warning. - -	* cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable -	to avoid compiler warnings. - -	* misc.c (ptw32_new): Change "new" variable to "t" to avoid -	confusion with the C++ keyword of the same name. - -	* condvar.c (cond_wait_cleanup): Initialise lastWaiter variable. -	(cond_timedwait): Remove unused local variables. to avoid -	compiler warnings. - -	* dll.c (dllMain): Remove 2000-07-21 change - problem -	appears to be in pthread_create(). - -2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* tsd.c (pthread_key_create): If a destructor was given -	and the pthread_mutex_init failed, then would try to -	reference a NULL pointer (*key); eliminate this section of -	code by using a dynamically initialised mutex -	(PTHREAD_MUTEX_INITIALIZER). - -	* tsd.c (pthread_setspecific): Return an error if -	unable to set the value; simplify cryptic conditional. - -	* tsd.c (pthread_key_delete): Locking threadsLock relied -	on mutex_lock returning an error if the key has no destructor. -	ThreadsLock is only initialised if the key has a destructor. -	Making this mutex a static could reduce the number of mutexes -	used by an application since it is actually created only at -	first use and it's often destroyed soon after. -	 -2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* FAQ: Added Q5 and Q6. - -2000-07-21  Ross Johnson  <rpj@setup1.ise.canberra.edu.au> - -	* create.c (pthread_create): Set threadH to 0 (zero) -	everywhere. Some assignments were using NULL. Maybe -	it should be NULL everywhere - need to check. (I know -	they are nearly always the same thing - but not by -	definition.) - -	* dll.c: Include resource leakage work-around. This is a -	partial FIXME which doesn't stop all leakage. The real -	problem needs to be found and fixed. -	- "David Baggett" <dmb@itasoftware.com> - -	* misc.c (pthread_self): Try to catch NULL thread handles -	at the point where they might be generated, even though -	they should always be valid at this point. - -	* tsd.c (pthread_setspecific): return an error value if -	pthread_self() returns NULL. - -	* sync.c (pthread_join): return an error value if -	pthread_self() returns NULL. - -	* signal.c (pthread_sigmask): return an error value if -	pthread_self() returns NULL. - -2000-03-02  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* attr.c (pthread_attr_init): Set default stacksize to zero (0) -	rather than PTHREAD_STACK_MIN even though these are now the same. - -	* pthread.h (PTHREAD_STACK_MIN): Lowered to 0. - -2000-01-28  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* mutex.c (pthread_mutex_init): Free mutex if it has been alloced; -	if critical sections can be used instead of Win32 mutexes, test -	that the critical section works and return an error if not. - -2000-01-07  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not -	compiling as C++. -	(pthread_push_cleanup): Include SEH code only if MSC is not -	compiling as C++. - -	* pthread.h: Include SEH code only if MSC is not -	compiling as C++. - -	* implement.h: Include SEH code only if MSC is not -	compiling as C++. - -	* cancel.c (ptw32_cancel_thread): Add _M_IX86 check. -	(pthread_testcancel): Include SEH code only if MSC is not -	compiling as C++. -	(ptw32_cancel_self): Include SEH code only if MSC is not -	compiling as C++. - -2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* Makefile: Remove inconsistencies in 'cl' args -	- Erik Hensema <erik.hensema@group2000.nl> - -2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* private.c (ptw32_get_exception_services_code): New; returns -	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_PTW32_SERVICES value instead of -	using the ptw32_exception_services variable which I had -	trouble exporting through pthread.def. - -	* global.c (ptw32_exception_services): Remove declaration. - -1999-11-22  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* implement.h: Forward declare ptw32_new(); - -	* misc.c (ptw32_new): New; alloc and initialise a new pthread_t. -	(pthread_self): New thread struct is generated 	by new routine -	ptw32_new(). - -	* create.c (pthread_create): New thread struct is generated -	by new routine ptw32_new(). - -1999-11-21  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* global.c (ptw32_exception_services): Declare new variable.  - -	* private.c (ptw32_threadStart): Destroy thread's -	cancelLock mutex; make 'catch' and '__except' usageimmune to -	redfinitions in pthread.h. -	(ptw32_processInitialize): Init new constant ptw32_exception_services. - -	* create.c (pthread_create): Initialise thread's cancelLock -	mutex. - -	* cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except' -	usage immune to redfinition s in pthread.h. - -	* private.c: Ditto. - -	* pthread.h (catch): Redefine 'catch' so that C++ applications -	won't catch our internal exceptions. -	(__except): ditto for __except. - -	* implement.h (ptw32_catch): Define internal version -	of 'catch' because 'catch' is redefined by pthread.h. -	(__except): ditto for __except. -	(struct pthread_t_): Add cancelLock mutex for async cancel -	safety. - -	* cancel.c (ptw32_cancel_self): New; part of the async -	cancellation implementation. -	(ptw32_cancel_thread): Ditto; this function is X86 -	processor specific. -	(pthread_setcancelstate): Add check for pending async -	cancel request and cancel the calling thread if -	required; add async-cancel safety lock. -	(pthread_setcanceltype): Ditto. -	- Jason Nye <jnye@nbnet.nb.ca> -	- Erik Hensema <erik.hensema@group2000.nl> - -1999-11-13  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile -	rather than Makefile. Makefile will become the MSC nmake compatible -	version -	- Erik Hensema <erik.hensema@group2000.nl> - -	* misc.c (pthread_self): Add a note about GetCurrentThread -	returning a pseudo-handle -	- John Bossom (John.Bossom@cognos.com> - -1999-11-10  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* dll.c (dllMain): Free kernel32 ASAP. -	If TryEnterCriticalSection is not being used, then free -	the kernel32.dll handle now, rather than leaving it until -	DLL_PROCESS_DETACH. - -	Note: this is not a pedantic exercise in freeing unused -	resources!  It is a work-around for a bug in Windows 95 -	(see microsoft knowledge base article, Q187684) which -	does Bad Things when FreeLibrary is called within -	the DLL_PROCESS_DETACH code, in certain situations. -	Since w95 just happens to be a platform which does not -	provide TryEnterCriticalSection, the bug will be -	effortlessly avoided. -	- Todd Owen <towen@lucidcalm.dropbear.id.au> - -	* sync.c (pthread_join): Make it a deferred cancelation point. - -	* misc.c (pthread_self): Explicitly initialise implicitly -	created thread state to default values. - -1999-11-05  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (winsock.h): Include unconditionally. -	(ETIMEDOUT): Change fallback value to that defined by winsock.h. -	 -	* general: Patched for portability to WinCE. The details are -	described in the file WinCE-PORT. Follow the instructions -	in README.WinCE to make the appropriate changes in config.h. -	- Tristan Savatier <tristan@mpegtv.com> - -1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* create.c (pthread_create): Explicitly initialise thread state to -	default values. - -	* cancel.c (pthread_setcancelstate): Check for NULL 'oldstate' -	for compatibility with Solaris pthreads; -	(pthread_setcanceltype): ditto: -	- Erik Hensema <erik.hensema@group2000.nl> - -1999-10-23  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (ctime_r): Fix incorrect argument "_tm" -	- Erik Hensema <erik.hensema@group2000.nl> - -1999-10-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (_POSIX_THREADS): Only define it if it isn't -	already defined. Projects may need to define this on -	the CC command line under Win32 as it doesn't have unistd.h -	- Aurelio Medina <aureliom@crt.com> - -1999-10-17  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* rwlock.c (pthread_rwlock_destroy): Add cast to remove compile -	warning. - -	* condvar.c (pthread_cond_broadcast): Only release semaphores -	if there are waiting threads. - -1999-10-15  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (cond_wait_cleanup): New static cleanup handler for -	cond_timedwait; -	(cond_timedwait): pthread_cleanup_push args changed; -	canceling a thread while it's in pthread_cond_wait -	will now decrement the waiters count and cleanup if it's the -	last waiter. -	- Lorin Hochstein <lmh@xiphos.ca> and  -	  Peter Slacik <Peter.Slacik@tatramed.sk>; -	the last waiter will now reset the CV's wasBroadcast flag -	- Graham Dumpleton <Graham.Dumpleton@ra.pad.otc.telstra.com.au>. - -Thu Sep 16 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* rwlock.c (pthread_rwlock_destroy): Add serialisation. -	(_rwlock_check_need_init): Check for detroyed rwlock. -	* rwlock.c: Check return codes from _rwlock_check_need_init(); -	modify comments; serialise access to rwlock objects during -	operations; rename rw_mutex to rw_lock. -	* implement.h: Rename rw_mutex to rw_lock. -	* mutex.c (pthread_mutex_destroy): Add serialisation. -	(_mutex_check_need_init): Check for detroyed mutex. -	* condvar.c (pthread_cond_destroy): Add serialisation. -	(_cond_check_need_init): Check for detroyed condvar. -	* mutex.c: Modify comments. -	* condvar.c: Modify comments. - -Sat Sep 10 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	The following code for POSIX read/write locks was contributed -	by Aurelio Medina. - -	* implement.h (pthread_rwlock_t_): Add. -	* pthread.h (pthread_rwlock_t): Add. -	(PTHREAD_RWLOCK_INITIALIZER): Add. -	Add rwlock function prototypes. -	* rwlock.c: New module. -	* pthread.def: Add new rwlock functions. -	* private.c (ptw32_processInitialize): initialise -	ptw32_rwlock_test_init_lock critical section. -	* global.c (ptw32_rwlock_test_init_lock): Add. - -	* mutex.c (pthread_mutex_destroy): Don't free mutex memory -	if mutex is PTHREAD_MUTEX_INITIALIZER and has not been -	initialised yet. - -Wed Sep  8 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* mutex.c (pthread_mutex_destroy): Free mutex memory. -	- Milan Gardian <mg@tatramed.sk> - -1999-08-22  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* exit.c (pthread_exit): Fix reference to potentially -	uninitialised pointer. - -1999-08-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_threadStart): Apply fix of 1999-08-19 -	this time to C++ and non-trapped C versions. Ommitted to -	do this the first time through. - -1999-08-19  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_threadStart): Return exit status from -	the application thread startup routine. -	- Milan Gardian <mg@tatramed.sk> - -1999-08-18  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* exit.c (pthread_exit): Put status into pthread_t->exitStatus -	- John Bossom <john.Bossom@cognos.com> -	* private.c (ptw32_threadStart): Set pthread->exitStatus -	on exit of try{} block. -	- John Bossom <john.Bossom@cognos.com> -	* sync.c (pthread_join): use pthread_exitStatus value if the -	thread exit doesn't return a value (for Mingw32 CRTDLL -	which uses endthread instead of _endthreadex). -	- John Bossom <john.Bossom@cognos.com> - -Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan@xraylith.wisc.edu> - -        * create.c (pthread_create): Add CRTDLL suppport. -        * exit.c (pthread_exit): Likewise. -        * private.c (ptw32_threadStart): Likewise. -        (ptw32_threadDestroy): Likewise. -        * sync.c (pthread_join): Likewise. -        * tests/join1.c (main): Warn about partial support for CRTDLL. - -Tue Aug 17 20:00:08 1999  Mumit Khan  <khan@xraylith.wisc.edu> - -        * Makefile.in (LD): Delete entry point. -        * acconfig.h (STDCALL): Delete unused macro. -        * configure.in: Remove test for STDCALL. -        * config.h.in: Regenerate. -        * errno.c (_errno): Fix self type. -        * pthread.h (PT_STDCALL): Move from here to -        * implement.h (PT_STDCALL): here. -        (ptw32_threadStart): Fix prototype. -        * private.c (ptw32_threadStart): Likewise. - -1999-08-14  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* exit.c (pthread_exit): Don't call pthread_self() but -	get thread handle directly from TSD for efficiency. -	 -1999-08-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_threadStart): ei[] only declared if _MSC_VER. - -	* exit.c (pthread_exit): Check for implicitly created threads -	to avoid raising an unhandled exception. -	 -1999-07-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (pthread_cond_destroy): Add critical section. -	(cond_timedwait): Add critical section; check for timeout -	waiting on semaphore. -	(pthread_cond_broadcast): Add critical section. -	- Peter Slacik <Peter.Slacik@tatramed.sk> - -1999-07-09  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	The following changes fix a bug identified by -	Lorin Hochstein <lmh@xiphos.ca> and solved by -	John Bossom <John.Bossom@Cognos.COM>. - -	The problem was that cleanup handlers were not executed when -	pthread_exit() was called. - -	* implement.h (pthread_t_): Add exceptionInformation element for -	C++ per-thread exception information. -	(general): Define and rename exceptions. - - -	* misc.c (CancelableWait):  PTW32_EPS_CANCEL (SEH) and -	ptw32_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. 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(). - -Sun May 30 00:25:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* semaphore.h (mode_t): Conditionally typedef it. - -Fri May 28 13:33:05 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* condvar.c (pthread_cond_broadcast): Fix possible memory fault -	- Mark E. Armstrong <avail@pacbell.net> -	 -Thu May 27 13:08:46 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* condvar.c (pthread_cond_broadcast): Fix logic bug -	- Peter Slacik <Peter.Slacik@tatramed.sk>; -	optimise sem_post loop -	- Bossom, John <John.Bossom@Cognos.COM>. - -Fri May 14 12:13:18 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* attr.c (pthread_attr_setdetachstate): Fix logic bug -	- Mike Russo <miker@eai.com>. - -Sat May  8 09:42:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.def (sem_open): Add. -	(sem_close): Add. -	(sem_unlink): Add. -	(sem_getvalue): Add. - -	* FAQ (Question 3): Add. - -Thu Apr  8 01:16:23 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* semaphore.c (sem_open): New function; returns an error (ENOSYS). -	(sem_close): ditto. -	(sem_unlink): ditto. -	(sem_getvalue): ditto. - -	* semaphore.h (_POSIX_SEMAPHORES): define. -	 -Wed Apr  7 14:09:52 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* errno.c (_REENTRANT || _MT): Invert condition. - -	* pthread.h (_errno): Conditionally include prototype. - -Wed Apr  7 09:37:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* *.c (comments): Remove individual attributions - these are -	documented sufficiently elsewhere. - -	* implement.h (pthread.h): Remove extraneous include. - -Sun Apr  4 11:05:57 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* sched.c (sched.h): Include. - -	* sched.h: New file for POSIX 1b scheduling. - -	* pthread.h: Move opaque structures to implement.h; move sched_* -	prototypes out and into sched.h. - -	* implement.h: Add opaque structures from pthread.h. - -	* sched.c (sched_yield): New function. - -	* condvar.c (ptw32_sem_*): Rename to sem_*; except for -	ptw32_sem_timedwait which is an private function. - -Sat Apr  3 23:28:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* Makefile.in (OBJS): Add errno.o. - -Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h (ptw32_sem_*): Remove prototypes now defined in -	semaphore.h. - -	* pthread.h (sempahore.h): Include. - -	* semaphore.h: New file for POSIX 1b semaphores. - -	* pthread.h (ptw32_sem_t): Change to sem_t.  - -	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions -	will be exported from the library; set errno on error. -	- John Bossom <jebossom@cognos.com> -	(ptw32_sem_timedwait): Moved to private.c. - -	* private.c (ptw32_sem_timedwait): Moved from semaphore.c; -	set errno on error. - -	* errno.c (_errno): New file. New function. -	- John Bossom - -	* pthread.h (pthread_t_): Add per-thread errno element. - -Fri Mar 26 14:11:45 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* semaphore.c (ptw32_sem_timedwait): Check for negative -	milliseconds. -	- Tor Lillqvist <tml@iki.fi> - -Wed Mar 24 11:32:07 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* misc.c (CancelableWait): Initialise exceptionInformation[2]. -	(pthread_self): Get a real Win32 thread handle for implicit threads. -	- John Bossom <jebossom@cognos.com> - -	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2]. -	- John Bossom <jebossom@cognos.com> - -	* implement.h (SE_INFORMATION): Fix values. -	- John Bossom <jebossom@cognos.com> - -	* private.c (ptw32_threadDestroy): Close the thread handle. -	- John Bossom <jebossom@cognos.com> - -Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cancel.c (comments): Update and cleanup. - -Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED. - -	* pthread.h (PTHREAD_CANCELED): defined. - -Tue Mar 16  1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* all: Add GNU LGPL and Copyright and Warranty. -	 -Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (pthread_cond_init): fix possible uninitialised use -	of cv. - -Sun Mar 14 21:01:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (pthread_cond_destroy): don't do full cleanup if -	static initialised cv has never been used. -	(cond_timedwait): check result of auto-initialisation. - -Thu Mar 11 09:01:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *); -	define a value to serve as PTHREAD_MUTEX_INITIALIZER. -	(pthread_mutex_t_): remove staticinit and valid elements. -	(pthread_cond_t): revert to (pthread_cond_t_ *); -	define a value to serve as PTHREAD_COND_INITIALIZER. -	(pthread_cond_t_): remove staticinit and valid elements. - -	* mutex.c (pthread_mutex_t args): adjust indirection of references. -	(all functions): check for PTHREAD_MUTEX_INITIALIZER value; -	check for NULL (invalid). - -	* condvar.c (pthread_cond_t args): adjust indirection of references. -	(all functions): check for PTHREAD_COND_INITIALIZER value; -	check for NULL (invalid). - -Wed Mar 10 17:18:12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* misc.c (CancelableWait): Undo changes from Mar 8 and 7. - -Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* misc.c (CancelableWait): Ensure cancelEvent handle is the lowest -	indexed element in the handles array. Enhance test for abandoned -	objects. - -	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not -	initialised are set to zero by the compiler. This avoids the -	problem of initialising the opaque critical section element in it. -	(PTHREAD_COND_INITIALIZER): Ditto. - -	* semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier. - -Sun Mar  7 12:31:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (pthread_cond_init): set semaphore initial value -	to 0, not 1. cond_timedwait was returning signaled immediately. - -	* misc.c (CancelableWait): Place the cancel event handle first -	in the handle table for WaitForMultipleObjects. This ensures that -	the cancel event is recognised and acted apon if both objects -	happen to be signaled together. - -	* private.c (ptw32_cond_test_init_lock): Initialise and destroy. - -	* implement.h (ptw32_cond_test_init_lock): Add extern. - -	* global.c (ptw32_cond_test_init_lock): Add declaration.  - -	* condvar.c (pthread_cond_destroy): check for valid initialised CV; -	flag destroyed CVs as invalid. -	(pthread_cond_init): pthread_cond_t is no longer just a pointer. -	This is because PTHREAD_COND_INITIALIZER needs state info to reside -	in pthread_cond_t so that it can initialise on first use. Will work on -	making pthread_cond_t (and other objects like it) opaque again, if -	possible, later. -	(cond_timedwait): add check for statically initialisation of -	CV; initialise on first use. -	(pthread_cond_signal): check for valid CV. -	(pthread_cond_broadcast): check for valid CV. -	(_cond_check_need_init): Add. - -	* pthread.h (PTHREAD_COND_INITIALIZER): Fix. -	(pthread_cond_t): no longer a pointer to pthread_cond_t_. -	(pthread_cond_t_): add 'staticinit' and 'valid' elements. - -Sat Mar 6 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h: Undate comments. - -Sun Feb 21 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around -	cs element initialiser. - -1999-02-21  Ben Elliston  <bje@cygnus.com> - -	* pthread.h (pthread_exit): The return type of this function is -	void, not int. - -	* exit.c (pthread_exit): Do not return 0. - -Sat Feb 20 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* dll.c (DLLMain): Expand TryEnterCriticalSection support test. - -	* mutex.c (pthread_mutex_trylock): The check for -	ptw32_try_enter_critical_section == NULL should have been -	removed long ago. - -Fri Feb 19 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* sync.c (pthread_join): Fix pthread_equal() test. - -	* mutex.c (pthread_mutex_trylock): Check mutex != NULL before -	using it. - -Thu Feb 18 16:17:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* misc.c (pthread_equal): Fix inverted result. - -	* Makefile.in: Use libpthread32.a as the name of the DLL export -	library instead of pthread.lib. - -	* condvar.c (pthread_cond_init): cv could have been used unitialised; -	initialise. - -	* create.c (pthread_create): parms could have been used unitialised; -	initialise. - -	* pthread.h (struct pthread_once_t_): Remove redefinition. - -Sat Feb 13 03:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (struct pthread_once_t_): Replaced. - -	* misc.c (pthread_once): Replace with John Bossom's version; -	has lighter weight serialisation; fixes problem of not holding -	competing threads until after the init_routine completes. - -Thu Feb 11 13:34:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* misc.c (CancelableWait): Change C++ exception throw. - -	* sync.c (pthread_join): Change FIXME comment - issue resolved. - -Wed Feb 10 12:49:11 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* configure: Various temporary changes. -	- Kevin Ruland <Kevin.Ruland@anheuser-busch.com> - -	* README: Update. - -	* pthread.def (pthread_attr_getstackaddr): uncomment -	(pthread_attr_setstackaddr): uncomment - -Fri Feb  5 13:42:30 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* semaphore.c: Comment format changes. - -Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* global.c: Remove ptw32_exception instantiation. - -	* cancel.c (pthread_testcancel): Change C++ exception throw. - -	* implement.h: Remove extern declaration. - -Wed Feb  3 13:04:44 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup(). - -	* pthread.def: Ditto. -	 -	* pthread.h: Ditto. - -	* pthread.def (pthread_cleanup_push): Remove from export list; -	the function is defined as a macro under all compilers. -	(pthread_cleanup_pop): Ditto. - -	* pthread.h: Remove #if defined(). - -Wed Feb  3 10:13:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* sync.c (pthread_join): Check for NULL value_ptr arg; -	check for detached threads. - -Tue Feb  2 18:07:43 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* implement.h: Add #include <pthread.h>. -	Change sem_t to ptw32_sem_t. - -	Various patches by Kevin Ruland <Kevin.Ruland@anheuser-busch.com> - -	* signal.c (pthread_sigmask): Add and modify casts. -	Reverse LHS/RHS bitwise assignments. - -	* pthread.h: Remove #include <semaphore.h>. -	(PTW32_ATTR_VALID): Add cast. -	(struct pthread_t_): Add sigmask element. - -	* dll.c: Add "extern C" for DLLMain. -	(DllMain): Add cast. - -	* create.c (pthread_create): Set sigmask in thread. - -	* condvar.c: Remove #include. Change sem_* to ptw32_sem_*. - -	* attr.c: Changed #include. - -	* Makefile.in: Additional targets and changes to build the library -	as a DLL. - -Fri Jan 29 11:56:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* Makefile.in (OBJS): Add semaphore.o to list. - -	* semaphore.c (ptw32_sem_timedwait): Move from private.c. -	Rename sem_* to ptw32_sem_*. - -	* pthread.h (pthread_cond_t): Change type of sem_t. -	_POSIX_SEMAPHORES no longer defined. - -	* semaphore.h: Contents moved to implement.h. -	Removed from source tree. - -	* implement.h: Add semaphore function prototypes and rename all -	functions to prepend 'ptw32_'. They are -	now private to the pthreads-win32 implementation. - -	* private.c: Change #warning. -	Move ptw32_sem_timedwait() to semaphore.c. - -	* cleanup.c: Change #warning. - -	* misc.c: Remove #include <errno.h> - -	* pthread.def: Cleanup CVS merge conflicts. - -	* global.c: Ditto. - -	* ChangeLog: Ditto. - -	* cleanup.c: Ditto. - -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 (ptw32_callUserDestroyRoutines): Redo conditional -	compilation. - -	* misc.c (CancelableWait): C++ version uses 'throw'. - -	* cancel.c (pthread_testcancel): Ditto. - -	* 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 -	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. - -	* mutex.c (pthread_mutex_init): Conditionally create Win32 mutex -	- from John Bossom's implementation. -	(pthread_mutex_destroy): Conditionally close Win32 mutex -	- from John Bossom's implementation. -	(pthread_mutexattr_init): Replaced by John Bossom's version. -	(pthread_mutexattr_destroy): Ditto. -	(pthread_mutexattr_getpshared): New function from John Bossom's -	implementation. -	(pthread_mutexattr_setpshared): New function from John Bossom's -	implementation. - -Tue Jan 19 18:27:42 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* pthread.h (pthreadCancelableTimedWait): New prototype. -	(pthreadCancelableWait): Remove second argument. - -	* misc.c (CancelableWait): New static function is  -	pthreadCancelableWait() renamed. -	(pthreadCancelableWait): Now just calls CancelableWait() with -	INFINITE timeout. -	(pthreadCancelableTimedWait): Just calls CancelableWait() -	with passed in timeout. - -	* private.c (ptw32_sem_timedwait): 'abstime' arg really is -	absolute time. Calculate relative time to wait from current -	time before passing timeout to new routine  -	pthreadCancelableTimedWait(). -	- Scott Lightner <scott@curriculum.com> - -Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (pthread_mutexattr_setforcecs_np): New prototype. -	 -	* mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs' -	attributes to 0. -	(pthread_mutexattr_setforcecs_np): New function (not portable). - -	* pthread.h (pthread_mutex_t):  -	Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER. -	The pthread_mutex_*() routines will try to optimise performance -	by choosing either mutexes or critical sections as the basis -	for pthread mutexes for each indevidual mutex. -	(pthread_mutexattr_t_): Add 'forcecs' element. -	Some applications may choose to force use of critical sections -	if they know that:- -	     the mutex is PROCESS_PRIVATE and,  -	         either the OS supports TryEnterCriticalSection() or -	         pthread_mutex_trylock() will never be called on the mutex. -	This attribute will be setable via a non-portable routine. - -	Note: We don't yet support PROCESS_SHARED mutexes, so the -	implementation as it stands will default to Win32 mutexes only if -	the OS doesn't support TryEnterCriticalSection. On Win9x, and early -	versions of NT 'forcecs' will need to be set in order to get -	critical section based mutexes. - -Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit' -	value to '1' and existing 'valid' value to '1'. - -	* global.c (ptw32_mutex_test_init_lock): Add. - -	* implement.h (ptw32_mutex_test_init_lock.): Add extern. - -	* private.c (ptw32_processInitialize): Init critical section for -	global lock used by _mutex_check_need_init(). -	(ptw32_processTerminate): Ditto (:s/Init/Destroy/). - -	* dll.c (dllMain): Move call to FreeLibrary() so that it is only -	called once when the process detaches. - -	* mutex.c (_mutex_check_need_init): New static function to test -	and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised -	access to the internal state of the uninitialised static mutex.  -	Called from pthread_mutex_trylock() and pthread_mutex_lock() which -	do a quick unguarded test to check if _mutex_check_need_init() -	needs to be called. This is safe as the test is conservative - 	and is repeated inside the guarded section of  -	_mutex_check_need_init(). Thus in all calls except the first -	calls to lock static mutexes, the additional overhead to lock any -	mutex is a single memory fetch and test for zero. - -	* pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes -	initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised -	until the first attempt to lock it. Using the 'valid' -	flag (which flags the mutex as destroyed or not) to record this -	information would be messy. It is possible for a statically -	initialised mutex such as this to be destroyed before ever being -	used. - -	* mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init() -	to test/init PTHREAD_MUTEX_INITIALIZER mutexes. -	(pthread_mutex_lock): Ditto. -	(pthread_mutex_unlock): Add check to ensure we don't try to unlock -	an unitialised static mutex. -	(pthread_mutex_destroy): Add check to ensure we don't try to delete -	a critical section that we never created. Allows us to destroy -	a static mutex that has never been locked (and hence initialised). -	(pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex. - -Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_sem_timedwait): Move from semaphore.c. - -	* semaphore.c : Remove redundant #includes. -	(ptw32_sem_timedwait): Move to private.c. -	(sem_wait): Add missing abstime arg to pthreadCancelableWait() call. - -Fri Jan 15 23:38:05 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (cond_timedwait): Remove comment. - -Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* pthread.h: Add new 'abstime' arg to pthreadCancelableWait() -	prototype. - -	* condvar.c (cond_timedwait): New generalised function called by -	both pthread_cond_wait() and pthread_cond_timedwait(). This is -	essentially pthread_cond_wait() renamed and modified to add the -	'abstime' arg and call the new ptw32_sem_timedwait() instead of -	sem_wait(). -	(pthread_cond_wait): Now just calls the internal static -	function cond_timedwait() with an INFINITE wait. -	(pthread_cond_timedwait): Now implemented. Calls the internal -	static function cond_timedwait(). - -	* implement.h (ptw32_sem_timedwait): New internal function -	prototype. - -	* misc.c (pthreadCancelableWait): Added new 'abstime' argument -	to allow shorter than INFINITE wait. - -	* semaphore.c (ptw32_sem_timedwait): New function for internal -	use.  This is essentially sem_wait() modified to add the -        'abstime' arg and call the modified (see above) -        pthreadCancelableWait(). - -Thu Jan 14 14:27:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cleanup.c: Correct _cplusplus to __cplusplus wherever used. - -	* Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS. -	The derived Makefile will compile all units of the package as C++ -	so that those which include try/catch exception handling should work -	properly. The package should compile ok if CC=gcc, however, exception -	handling will not be included and thus thread cancellation, for - 	example, will not work. - -	* cleanup.c (ptw32_pop_cleanup): Add #warning to compile this - 	file as C++ if using a cygwin32 environment. Perhaps the whole package -	should be compiled using g++ under cygwin. - -	* private.c (ptw32_threadStart): Change #error directive -	into #warning and bracket for __CYGWIN__ and derivative compilers. - -Wed Jan 13 09:34:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* build.bat: Delete old binaries before compiling/linking. - -Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* dll.c: The Microsoft compiler pragmas probably are more -	appropriately protected by _MSC_VER than by _WIN32. -	- Tor Lillqvist <tml@iki.fi>. - -	* condvar.c (pthread_cond_timedwait): Fix function description -	comments. - -	* pthread.h: Define ETIMEDOUT. This should be returned by -	pthread_cond_timedwait which is not implemented yet as of -	snapshot-1999-01-04-1305. It was implemented in the older version. -	The Microsoft compiler pragmas probably are more appropriately -	protected by _MSC_VER than by _WIN32. -	- Tor Lillqvist <tml@iki.fi>. - -	* pthread.def: pthread_mutex_destroy was missing from the def file -	- Tor Lillqvist <tml@iki.fi>. - -	* condvar.c (pthread_cond_broadcast): Ensure we only wait on threads -	if there were any waiting on the condition. -	I think pthread_cond_broadcast should do the WaitForSingleObject -	only if cv->waiters > 0? Otherwise it seems to hang, at least in the -	testg thread program from glib. -	- Tor Lillqvist <tml@iki.fi>.  - -	* semaphore.c (sem_post): Correct typo in comment. - -Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h: Re-arrange conditional compile of pthread_cleanup-* -	macros. - -	* cleanup.c (ptw32_push_cleanup): Provide conditional  -	compile of cleanup->prev. - -1999-01-11  Ben Elliston  <bje@cygnus.com> - -	* condvar.c (pthread_cond_init): Invert logic when testing the -	return value from calloc(). -	- Tor Lillqvist <tml@iki.fi>. - -Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h: Compile-time switch for CYGWIN derived environments -	to use CreateThread instead of _beginthreadex. Ditto for ExitThread. -	Patch provided by Anders Norlander  <anorland@hem2.passagen.se>. - -Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except -	block. Move trailing "}" out of #ifdef _WIN32 block left there by -	(rpj's) mistake. - -	* private.c: Remove #include <errno.h> which is included by pthread.h. - -1998-12-11  Ben Elliston  <bje@toilet.to.cygnus.com> - -	* README: Update info about subscribing to the mailing list. - -Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* all: No code changes, just cleanup. -	- remove #if 0 /* Pre Bossom */ enclosed code. -	- Remove some redundant #includes. -	* pthread.h: Update implemented/unimplemented routines list. -	* Tag the bossom merge branch getting ready to merge back to main -	trunk. - -Tue Dec 29 13:11:16 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h: Move the following struct definitions to pthread.h: -	pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_, -	pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_, -	pthread_condattr_t_, pthread_once_t_. - -	* pthread.h: Add "_" prefix to pthread_push_cleanup and  -	pthread_pop_cleanup internal routines, and associated struct and -	typedefs. - -	* buildlib.bat: Add compile command for semaphore.c - -	* pthread.def: Comment out pthread_atfork routine name.  -	Now unimplemented. - -	* tsd.c (pthread_setspecific): Rename tkAssocCreate to -	ptw32_tkAssocCreate. -	(pthread_key_delete): Rename tkAssocDestroy to -	ptw32_tkAssocDestroy. - -	* sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy - -	* sched.c (is_attr): attr is now **attr (was *attr), so add extra -	NULL pointer test. -	(pthread_attr_setschedparam): Increase redirection for attr which is -	now a **. -	(pthread_attr_getschedparam): Ditto. -	(pthread_setschedparam): Change thread validation and rename "thread" - 	Win32 thread Handle element name to match John Bossom's version. -	(pthread_getschedparam): Ditto. - -	* private.c (ptw32_threadDestroy): Rename call to -	callUserDestroyRoutines() as ptw32_callUserDestroyRoutines() - -	* misc.c: Add #include "implement.h". - -	* dll.c: Remove defined(KLUDGE) wrapped code. - -	* fork.c: Remove redefinition of ENOMEM. -	Remove pthread_atfork() and fork() with #if 0/#endif. - -	* create.c (pthread_create): Rename threadStart and threadDestroy calls -	to ptw32_threadStart and ptw32_threadDestroy. - -	* implement.h: Rename "detachedstate" to "detachstate". - -	* attr.c: Rename "detachedstate" to "detachstate". - -Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* semaphore.c: Initial version. From John Bossom's implementation. -	* semaphore.h: Initial version. From John Bossom's implementation. - -Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t. - -	* attr.c (pthread_attr_setstacksize): Merge with John Bossom's version. -	(pthread_attr_getstacksize): Merge with John Bossom's version. -	(pthread_attr_setstackaddr): Merge with John Bossom's version. -	(pthread_attr_getstackaddr): Merge with John Bossom's version. -	(pthread_attr_init): Merge with John Bossom's version. -	(pthread_attr_destroy): Merge with John Bossom's version. -	(pthread_attr_getdetachstate): Merge with John Bossom's version. -	(pthread_attr_setdetachstate): Merge with John Bossom's version. -	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer -	test. - -	* implement.h (pthread_attr_t_): Add and rename elements in JEB's -	version to correspond to original, so that it can be used with -	original attr routines. - -	* pthread.h: Add #endif at end which was truncated in merging. - -Sun Dec 20 14:51:58 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard -	but provides a hook that can be used to implement cancellation points in -	applications that use this library. - -	* pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses -	try/catch to emulate John Bossom's WIN32 __try/__finally behaviour. -	In the WIN32 version __finally block, add a test for AbnormalTermination otherwise -	cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation -	should cause the cleanup to run irrespective of the execute arg. - -	* condvar.c (pthread_condattr_init): Replaced by John Bossom's version. -	(pthread_condattr_destroy): Replaced by John Bossom's version. -	(pthread_condattr_getpshared): Replaced by John Bossom's version. -	(pthread_condattr_setpshared): Replaced by John Bossom's version. -	(pthread_cond_init): Replaced by John Bossom's version. -	Fix comment (refered to mutex rather than condition variable). -	(pthread_cond_destroy): Replaced by John Bossom's version. -	(pthread_cond_wait): Replaced by John Bossom's version. -	(pthread_cond_timedwait): Replaced by John Bossom's version. -	(pthread_cond_signal): Replaced by John Bossom's version. -	(pthread_cond_broadcast): Replaced by John Bossom's version. - -Thu Dec 17 19:10:46 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tsd.c (pthread_key_create): Replaced by John Bossom's version. -	(pthread_key_delete): Replaced by John Bossom's version. -	(pthread_setspecific): Replaced by John Bossom's version. -	(pthread_getspecific): Replaced by John Bossom's version. - -Mon Dec  7 09:44:40 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* cancel.c (pthread_setcancelstate): Replaced by John Bossom's version. -	(pthread_setcanceltype): Replaced by John Bossom's version. -	(pthread_testcancel): Replaced by John Bossom's version. -	(pthread_cancel): Replaced by John Bossom's version. -	 -	* exit.c (pthread_exit): Replaced by John Bossom's version. - -	* misc.c (pthread_self): Replaced by John Bossom's version. -	(pthread_equal): Replaced by John Bossom's version. - -	* sync.c (pthread_detach): Replaced by John Bossom's version. -	(pthread_join): Replaced by John Bossom's version. - -	* create.c (pthread_create): Replaced by John Bossom's version. - -	* private.c (ptw32_processInitialize): New by John Bossom. -	(ptw32_processTerminate): Non-public function by John Bossom. -	(ptw32_threadStart): Non-public function by John Bossom. - 	(ptw32_threadDestroy): Non-public function by John Bossom. -	(ptw32_cleanupStack): Non-public function by John Bossom. -	(ptw32_tkAssocCreate): Non-public function by John Bossom. -	(ptw32_tkAssocDestroy): Non-public function by John Bossom. -	(ptw32_callUserDestroyRoutines): Non-public function by John Bossom. - -	* implement.h: Added John Bossom's non-API structures and -	declarations. - -	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress -	to resolve compile warning from MSVC. - -	* dll.c (DLLmain): Replaced by John Bossom's version. -	* dll.c (PthreadsEntryPoint): -	Re-applied Anders Norlander's patch:- -	Initialize ptw32_try_enter_critical_section at startup -	and release kernel32 handle when DLL is being unloaded. - -Sun Dec  6 21:54:35 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* buildlib.bat: Fix args to CL when building the .DLL - -	* cleanup.c (ptw32_destructor_run_all): Fix TSD key management. -	This is a tidy-up before TSD and Thread management is completely -	replaced by John Bossom's code. - -	* tsd.c (pthread_key_create): Fix TSD key management. - -	* global.c (ptw32_key_virgin_next): Initialise. - -	* build.bat: New DOS script to compile and link a pthreads app -	using Microsoft's CL compiler linker. -	* buildlib.bat: New DOS script to compile all the object files -	and create pthread.lib and pthread.dll using Microsoft's CL -	compiler linker. - -1998-12-05  Anders Norlander  <anorland@hem2.passagen.se> - -	* implement.h (ptw32_try_enter_critical_section): New extern -	* dll.c (ptw32_try_enter_critical_section): New pointer to -	TryEnterCriticalSection if it exists; otherwise NULL. -	* dll.c (PthreadsEntryPoint): -	Initialize ptw32_try_enter_critical_section at startup -	and release kernel32 handle when DLL is being unloaded. -	* mutex.c (pthread_mutex_trylock): Replaced check for NT with -	a check if ptw32_try_enter_critical_section is valid -	pointer to a function. Call ptw32_try_enter_critical_section -	instead of TryEnterCriticalSection to avoid errors on Win95. - -Thu Dec 3 13:32:00 1998  Ross Johnson  <rpj@ise.canberra.edu.au> - -	* README: Correct cygwin32 compatibility statement. - -Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg. -	Fixup CVS merge conflicts. - -1998-10-30  Ben Elliston  <bje@cygnus.com> - -	* condvar.c (cond_wait): Fix semantic error. Test for equality -	instead of making an assignment. - -Fri Oct 30 15:15:50 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cleanup.c (ptw32_handler_push): Fixed bug appending new -	handler to list reported by Peter Slacik -	<Peter.Slacik@leibinger.freinet.de>. -	(new_thread): Rename poorly named local variable to -	"new_handler". - -Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* global.c: Add TSD key management array and index declarations. - -	* implement.h: Ditto for externs. - -Fri Oct 23 00:08:09 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* 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. - -	* cleanup.c (ptw32_destructor_run_all): Check for no more dirty -	keys to run destructors on. Assume that the destructor call always -	succeeds and set the key value to NULL. - -Thu Oct 22 21:44:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tsd.c (pthread_setspecific): Add key management code. -	(pthread_key_create): Ditto. -	(pthread_key_delete): Ditto. - -	* implement.h (struct ptw32_tsd_key): Add status member. - -	* tsd.c: Add description of pthread_key_delete() from the -	standard as a comment. - -Fri Oct 16 17:38:47 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cleanup.c (ptw32_destructor_run_all): Fix and improve -	stepping through the key table. - -Thu Oct 15 14:05:01 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* private.c (ptw32_new_thread): Remove init of destructorstack. -	No longer an element of pthread_t. - -	* tsd.c (pthread_setspecific): Fix type declaration and cast. -	(pthread_getspecific): Ditto. -	(pthread_getspecific): Change error return value to NULL if key -	is not in use. - -Thu Oct 15 11:53:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* global.c (ptw32_tsd_key_table): Fix declaration. - -	* implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern. -	(ptw32_tsd_mutex): Ditto. - -	* create.c (ptw32_start_call): Fix "keys" array declaration. -	Add comment. - -	* tsd.c (pthread_setspecific): Fix type declaration and cast. -	(pthread_getspecific): Ditto. - -	* cleanup.c (ptw32_destructor_run_all): Declare missing loop -	counter. - -Wed Oct 14 21:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_new_thread): Increment ptw32_threads_count. -	(ptw32_delete_thread): Decrement ptw32_threads_count. -	Remove some comments. - -	* exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that - 	should have been pthread_mutex_unlock() calls. -	(ptw32_vacuum): Remove call to ptw32_destructor_pop_all(). - -	* create.c (pthread_create): Fix two pthread_mutex_lock() calls that - 	should have been pthread_mutex_unlock() calls. - -	* global.c (ptw32_tsd_mutex): Add mutex for TSD operations. - -	* tsd.c (pthread_key_create): Add critical section. -	(pthread_setspecific): Ditto. -	(pthread_getspecific): Ditto. -	(pthread_key_delete): Ditto. - -	* sync.c (pthread_join): Fix two pthread_mutex_lock() calls that - 	should have been pthread_mutex_unlock() calls. - -Mon Oct 12 00:00:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h (ptw32_tsd_key_table): New. - -	* create.c (ptw32_start_call): Initialise per-thread TSD keys -	to NULL. - -	* misc.c (pthread_once): Correct typo in comment. - -	* implement.h (ptw32_destructor_push): Remove. -	(ptw32_destructor_pop): Remove. -	(ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all. -	(PTW32_TSD_KEY_DELETED): Add enum. -	(PTW32_TSD_KEY_INUSE): Add enum. - -	* cleanup.c (ptw32_destructor_push): Remove. -	(ptw32_destructor_pop): Remove. -	(ptw32_destructor_run_all): Totally revamped TSD. - -	* dll.c (ptw32_TSD_keys_TlsIndex): Initialise. - -	* tsd.c (pthread_setspecific): Totally revamped TSD. -	(pthread_getspecific): Ditto. -	(pthread_create): Ditto. -	(pthread_delete): Ditto. - -Sun Oct 11 22:44:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* global.c (ptw32_tsd_key_table): Add new global. - -	* implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key): -	Add. -	(struct _pthread): Remove destructorstack. - -	* cleanup.c (ptw32_destructor_run_all): Rename from - 	ptw32_destructor_pop_all. The key destructor stack was made - 	global rather than per-thread. No longer removes destructor nodes -	from the stack. Comments updated. - -1998-10-06  Ben Elliston  <bje@cygnus.com> - -	* condvar.c (cond_wait): Use POSIX, not Win32 mutex calls. -	(pthread_cond_broadcast): Likewise. -	(pthread_cond_signal): Likewise. - -1998-10-05  Ben Elliston  <bje@cygnus.com> - -	* pthread.def: Update. Some functions aren't available yet, others -	are macros in <pthread.h>. - -	* tests/join.c: Remove; useless. - -Mon Oct  5 14:25:08 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* pthread.def: New file for building the DLL. - -1998-10-05  Ben Elliston  <bje@cygnus.com> - -	* misc.c (pthread_equal): Correct inverted logic bug. -	(pthread_once): Use the POSIX mutex primitives, not Win32. Remove -	irrelevant FIXME comment. - -	* global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h. - -	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Define. -	(pthread_mutex_t): Reimplement as a struct containing a valid -	flag. If the flag is ever down upon entry to a mutex operation, -	we call pthread_mutex_create() to initialise the object. This -	fixes the problem of how to handle statically initialised objects -	that can't call InitializeCriticalSection() due to their context. -	(PTHREAD_ONCE_INIT): Define. - -	* mutex.c (pthread_mutex_init): Set valid flag. -	(pthread_mutex_destroy): Clear valid flag. -	(pthread_mutex_lock): Check and handle the valid flag. -	(pthread_mutex_unlock): Likewise. -	(pthread_mutex_trylock): Likewise. - -	* tests/mutex3.c: New file; test for the static initialisation -	macro. Passes. - -	* tests/create1.c: New file; test pthread_create(). Passes. -	 -	* tests/equal.c: Poor test; remove. -	 -	* tests/equal1.c New file; test pthread_equal(). Passes. - -	* tests/once1.c: New file; test for pthread_once(). Passes. - -	* tests/self.c: Remove; rename to self1.c. - -	* tests/self1.c: This is the old self.c. - -	* tests/self2.c: New file. Test pthread_self() with a single -	thread. Passes. - -	* tests/self3.c: New file. Test pthread_self() with a couple of -	threads to ensure their thread IDs differ. Passes. -	 -1998-10-04  Ben Elliston  <bje@cygnus.com> - -	* tests/mutex2.c: Test pthread_mutex_trylock(). Passes. - -	* tests/mutex1.c: New basic test for mutex functions (it passes). -	(main): Eliminate warning. - -	* configure.in: Test for __stdcall, not _stdcall. Typo. - -	* configure: Regenerate. - -	* attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32 -	does know about ENOSYS after all. -	(pthread_attr_setstackaddr): Likewise. - -1998-10-03  Ben Elliston  <bje@cygnus.com> - -	* configure.in: Test for the `_stdcall' keyword.  Define `STDCALL' -	to `_stdcall' if we have it, null otherwise. - -	* configure: Regenerate. - -	* acconfig.h (STDCALL): New define. - -	* config.h.in: Regenerate. - -	* create.c (ptw32_start_call): Add STDCALL prefix. -	 -	* mutex.c (pthread_mutex_init): Correct function signature. - -	* attr.c (pthread_attr_init): Only zero out the `sigmask' member -	if we have the sigset_t type. - -	* pthread.h: No need to include <unistd.h>.  It doesn't even exist -	on Win32! Again, an artifact of cross-compilation.	 -	(pthread_sigmask): Only provide if we have the sigset_t type. - -	* process.h: Remove. This was a stand-in before we started doing -	native compilation under Win32. - -	* pthread.h (pthread_mutex_init): Make `attr' argument const. - -1998-10-02  Ben Elliston  <bje@cygnus.com> - -	* COPYING: Remove. - -	* COPYING.LIB: Add. This library is under the LGPL. - -1998-09-13  Ben Elliston  <bje@cygnus.com> - -	* configure.in: Test for required system features. - -	* configure: Generate.  - -	* acconfig.h: New file. - -	* config.h.in: Generate. - -	* Makefile.in: Renamed from Makefile. - -	* COPYING: Import from a recent GNU package. - -	* config.guess: Likewise. - -	* config.sub: Likewise. - -	* install-sh: Likewise. - -	* config.h: Remove.   - -	* Makefile: Likewise. - -1998-09-12  Ben Elliston  <bje@cygnus.com> - -	* windows.h: No longer needed; remove. - -	* windows.c: Likewise. - -Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* windows.h: Remove error number definitions. These are in <errno.h> -	 -	* tsd.c: Add comment explaining rationale for not building -	POSIX TSD on top of Win32 TLS. - -1998-09-12  Ben Elliston  <bje@cygnus.com> - -	* {most}.c: Include <errno.h> to get POSIX error values. - -	* signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is -	defined. -  -	* config.h: #undef features, don't #define them.  This will be -	generated by autoconf very soon. -	 -1998-08-11  Ben Elliston  <bje@cygnus.com> - -	* Makefile (LIB): Define. -	(clean): Define target. -	(all): Build a library not just the object files. - -	* pthread.h: Provide a definition for struct timespec if we don't -	already have one. - -	* windows.c (TlsGetValue): Bug fix. -	 -Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* misc.c (pthread_once): Fix arg 1 of EnterCriticalSection() - 	and LeaveCriticalSection() calls to pass address-of lock. - -	* fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr -	in each ptw32_handler_push() call. - -	* exit.c (ptw32_exit): Fix attr arg in  -	pthread_attr_getdetachstate() call. - -	* private.c (ptw32_new_thread): Typecast (HANDLE) NULL. -	(ptw32_delete_thread): Ditto. - -	* implement.h: (PTW32_MAX_THREADS): Add define. This keeps -	changing in an attempt to make thread administration data types -	opaque and cleanup DLL startup. - -	* dll.c (PthreadsEntryPoint):  -	(ptw32_virgins): Remove malloc() and free() calls. -	(ptw32_reuse): Ditto. -	(ptw32_win32handle_map): Ditto. -	(ptw32_threads_mutex_table): Ditto. - -	* global.c (_POSIX_THREAD_THREADS_MAX): Initialise with  -	PTW32_MAX_THREADS. -	(ptw32_virgins): Ditto. -	(ptw32_reuse): Ditto. -	(ptw32_win32handle_map): Ditto. -	(ptw32_threads_mutex_table): Ditto. - -	* create.c (pthread_create): Typecast (HANDLE) NULL. -	Typecast (unsigned (*)(void *)) start_routine. - -	* condvar.c (pthread_cond_init): Add address-of operator & to -	arg 1 of pthread_mutex_init() call. -	(pthread_cond_destroy): Add address-of operator & to -	arg 1 of pthread_mutex_destroy() call.  - -	* cleanup.c (ptw32_destructor_pop_all): Add (int) cast to  -	pthread_getspecific() arg. -	(ptw32_destructor_pop): Add (void *) cast to "if" conditional. -	(ptw32_destructor_push): Add (void *) cast to -	ptw32_handler_push() "key" arg. -	(malloc.h): Add include. - -	* implement.h (ptw32_destructor_pop): Add prototype. - -	* tsd.c (implement.h): Add include. - -	* sync.c (pthread_join): Remove target_thread_mutex and it's -	initialisation. Rename getdetachedstate to getdetachstate. -	Remove unused variable "exitcode". -	(pthread_detach): Remove target_thread_mutex and it's -	initialisation. Rename getdetachedstate to getdetachstate. -	Rename setdetachedstate to setdetachstate. - -	* signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK. -	Cast "set" to (long *) in assignment to passify compiler warning. -	Add address-of operator & to thread->attr.sigmask in memcpy() call -	and assignment. -	(pthread_sigmask): Add address-of operator & to thread->attr.sigmask -	in memcpy() call and assignment. - -	* windows.h (THREAD_PRIORITY_ERROR_RETURN): Add. -	(THREAD_PRIORITY_LOWEST): Add. -	(THREAD_PRIORITY_HIGHEST): Add. - -	* sched.c (is_attr): Add function. -	(implement.h): Add include. -	(pthread_setschedparam): Rename all instances of "sched_policy" -	to "sched_priority". -	(pthread_getschedparam): Ditto. - -Tue Aug  4 16:57:58 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* private.c (ptw32_delete_thread): Fix typo. Add missing ';'. - -	* global.c (ptw32_virgins): Change types from pointer to  -	array pointer. -	(ptw32_reuse): Ditto. -	(ptw32_win32handle_map): Ditto. -	(ptw32_threads_mutex_table): Ditto. - -	* implement.h(ptw32_virgins): Change types from pointer to  -	array pointer. -	(ptw32_reuse): Ditto. -	(ptw32_win32handle_map): Ditto. -	(ptw32_threads_mutex_table): Ditto. - -	* private.c (ptw32_delete_thread): Fix "entry" should be "thread". - -	* misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex. - -	* global.c: Add comment. - -	* misc.c (pthread_once): Fix member -> dereferences. -	Change ptw32_once_flag to once_control->flag in "if" test. - -Tue Aug  4 00:09:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h(ptw32_virgins): Add extern. -	(ptw32_virgin_next): Ditto. -	(ptw32_reuse): Ditto. -	(ptw32_reuse_top): Ditto. -	(ptw32_win32handle_map): Ditto. -	(ptw32_threads_mutex_table): Ditto. - -	* global.c (ptw32_virgins): Changed from array to pointer. -	Storage allocation for the array moved into dll.c. -	(ptw32_reuse): Ditto. -	(ptw32_win32handle_map): Ditto. -	(ptw32_threads_mutex_table): Ditto. - -	* dll.c (PthreadsEntryPoint): Set up thread admin storage when -	DLL is loaded. - -	* fork.c (pthread_atfork): Fix function pointer arg to all -	ptw32_handler_push() calls. Change "arg" arg to NULL in child push. - -	* exit.c: Add windows.h and process.h includes. -	(ptw32_exit): Add local detachstate declaration. -	(ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate(). - -	* pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c -	(_POSIX_THREAD_ATTR_STACKADDR): Ditto. - -	* create.c (pthread_create): Fix #if should be #ifdef. -	(ptw32_start_call): Remove usused variables. - -	* process.h: Create. - -	* windows.h: Move _beginthreadex and _endthreadex into -	process.h - -Mon Aug  3 21:19:57 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar.c (pthread_cond_init): Add NULL attr to -	pthread_mutex_init() call - default attributes will be used. -	(cond_wait): Fix typo. -	(cond_wait): Fix typo - cv was ev. -	(pthread_cond_broadcast): Fix two identical typos. - -	* cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from -	PTHREAD_DESTRUCTOR_ITERATIONS. - -	* pthread.h: Move _POSIX_* values into posix.h - -	* pthread.h: Fix typo in pthread_mutex_init() prototype. - -	* attr.c (pthread_attr_init): Fix error in priority member init. - -	* windows.h (THREAD_PRIORITY_NORMAL): Add. - -	* pthread.h (sched_param): Add missing ';' to struct definition.  - -	* attr.c (pthread_attr_init): Remove obsolete pthread_attr_t -	member initialisation - cancelstate, canceltype, cancel_pending. -	(is_attr): Make arg "attr" a const. - -	* 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> - -	* windows.h: Remove duplicate TlsSetValue() prototype.  Add  -	TlsGetValue() prototype. -	(FALSE): Define. -	(TRUE): Likewise. -	Add forgotten errno values.  Guard against multiple #includes. - -	* windows.c: New file.  Implement stubs for Win32 functions. - -	* Makefile (SRCS): Remove.  Not explicitly needed. -	(CFLAGS): Add -Wall for all warnings with GCC. - -Sun Aug  2 19:03:42 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* config.h: Create. This is a temporary stand-in for autoconf yet -	to be done. - 	(HAVE_SIGNAL_H): Add. - -	* pthread.h: Minor rearrangement for temporary config.h. - -Fri Jul 31 14:00:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* cleanup.c (ptw32_destructor_pop): Implement. Removes -	destructors associated with a key without executing them. -	(ptw32_destructor_pop_all): Add FIXME comment. - -	* tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop(). - -Fri Jul 31 00:05:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tsd.c (pthread_key_create): Update to properly associate -	the destructor routine with the key. -	(pthread_key_delete): Add FIXME comment. - -	* exit.c (ptw32_vacuum): Add call to -	ptw32_destructor_pop_all(). - -	* implement.h (ptw32_handler_pop_all): Add prototype. -	(ptw32_destructor_pop_all): Ditto. - -	* cleanup.c (ptw32_destructor_push): Implement. This is just a -	call to ptw32_handler_push(). -	(ptw32_destructor_pop_all): Implement. This is significantly -	different to ptw32_handler_pop_all(). - -	* Makefile (SRCS): Create. Preliminary. - -	* windows.h: Create. Contains Win32 definitions for compile -	testing. This is just a standin for the real one. - -	* pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK. -	(windows.h): Add include. Required for CRITICAL_SECTION. -	(pthread_cond_t): Move enum declaration outside of struct -	definition. -	(unistd.h): Add include - may be temporary. - -	* condvar.c (windows.h): Add include. - -	* 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> - -	* implement.h: Remove ptw32_find_entry() prototype. - -	* private.c: Extend comments. -	Remove ptw32_find_entry() - no longer needed. - -	* create.c (ptw32_start_call): Add call to TlsSetValue() to -	store the thread ID. - -	* dll.c (PthreadsEntryPoint): Implement. This is called -	whenever a process loads the DLL. Used to initialise thread -	local storage. - -	* implement.h: Add ptw32_threadID_TlsIndex. -	Add ()s around PTW32_VALID expression. - -	* misc.c (pthread_self): Re-implement using Win32 TLS to store -	the threads own ID. - -Wed Jul 29 11:39:03 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c: Corrections in comments. -	(ptw32_new_thread): Alter "if" flow to be more natural. - -	* cleanup.c (ptw32_handler_push): Same as below. - -	* create.c (pthread_create): Same as below. - -	* private.c (ptw32_new_thread): Rename "new" to "new_thread". -	Since when has a C programmer been required to know C++? - -Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* 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". -	Remove extra local variable "target". -	(pthread_detach): Ditto. - -	* signal.c (pthread_sigmask): Move init of "us" out of inner block. -	Fix instance of "this" should have been "us". Rename "us" to "thread". - -	* sched.c (pthread_setschedparam): Modify to use the new thread -	type. -	(pthread_getschedparam): Ditto. - -	* private.c (ptw32_find_thread): Fix return type and arg. - -	* 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. -	(  PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE): -	Add. - - -	* create.c (pthread_create): Minor rename "us" to "new" (I need -	these cues but it doesn't stop me coming out with some major bugs -	at times). -	Load start_routine and arg into the thread so the wrapper can -	call it. - -	* exit.c (pthread_exit): Fix pthread_this should be pthread_self. - -	* cancel.c (pthread_setcancelstate): Change - 	ptw32_threads_thread_t * to pthread_t and init with - 	pthread_this(). -	(pthread_setcanceltype): Ditto. - -	* exit.c (ptw32_exit): Add new pthread_t arg. -	Rename ptw32_delete_thread_entry to ptw32_delete_thread. -	Rename "us" to "thread". -	(pthread_exit): Call ptw32_exit with added thread arg. - -	* create.c (ptw32_start_call): Insert missing ")". -	Add "us" arg to ptw32_exit() call. -	(pthread_create): Modify to use new thread allocation scheme. - -	* private.c: Added detailed explanation of the new thread -	allocation scheme. -	(ptw32_new_thread): Totally rewritten to use -	new thread allocation scheme. -	(ptw32_delete_thread): Ditto. -	(ptw32_find_thread): Obsolete. - -Mon Jul 27 17:46:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* create.c (pthread_create): Start of rewrite. Not completed yet. - -	* private.c (ptw32_new_thread_entry): Start of rewrite. Not -	complete. - -	* implement.h (ptw32_threads_thread): Rename, remove thread -	member, add win32handle and ptstatus members. -	(ptw32_t): Add. - -	* pthread.h: pthread_t is no longer mapped directly to a Win32 -	HANDLE type. This is so we can let the Win32 thread terminate and -	reuse the HANDLE while pthreads holds it's own thread ID until -	the last waiting join exits. - -Mon Jul 27 00:20:37 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_delete_thread_entry): Destroy the thread - 	entry attribute object before deleting the thread entry itself. - -	* attr.c (pthread_attr_init): Initialise cancel_pending = FALSE. -	(pthread_attr_setdetachstate): Rename "detached" to "detachedstate". -	(pthread_attr_getdetachstate): Ditto. - -	* exit.c (ptw32_exit): Fix incorrect check for detachedstate. - -	* implement.h (ptw32_call_t): Remove env member.  - -Sun Jul 26 13:06:12 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h (ptw32_new_thread_entry): Fix prototype. -	(ptw32_find_thread_entry): Ditto. -	(ptw32_delete_thread_entry): Ditto. -	(ptw32_exit): Add prototype. - -	* exit.c (ptw32_exit): New function. Called from pthread_exit() -	and ptw32_start_call() to exit the thread. It allows an extra -	argument which is the return code passed to _endthreadex(). -	(ptw32_exit): Move thread entry delete call from ptw32_vacuum() -	into here. Add more explanation of thread entry deletion. -	(ptw32_exit): Clarify comment. - -	* create.c (ptw32_start_call): Change pthread_exit() call to -	ptw32_exit() call. - -	* exit.c (ptw32_vacuum): Add thread entry deletion code -	moved from ptw32_start_call(). See next item. -	(pthread_exit): Remove longjmp(). Add mutex lock around thread table -	manipulation code. This routine now calls _enthreadex(). - -	* create.c (ptw32_start_call): Remove setjmp() call and move -	cleanup code out. Call pthread_exit(NULL) to terminate the thread. - -1998-07-26  Ben Elliston  <bje@cygnus.com> - -	* tsd.c (pthread_getspecific): Update comments. - -	* mutex.c (pthread_mutexattr_setpshared): Not supported; remove. -	(pthread_mutexattr_getpshared): Likewise. - -	* pthread.h (pthread_mutexattr_setpshared): Remove prototype. -	(pthread_mutexattr_getpshared): Likewise. - -Sun Jul 26 00:09:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* sync.c: Rename all instances of ptw32_count_mutex to -	ptw32_table_mutex. - -	* implement.h: Rename ptw32_count_mutex to -	ptw32_table_mutex. - -	* global.c: Rename ptw32_count_mutex to -	ptw32_table_mutex. - -	* create.c (pthread_create): Add critical sections. -	(ptw32_start_call): Rename ptw32_count_mutex to -	ptw32_table_mutex. - -	* cancel.c (pthread_setcancelstate): Fix indirection bug and rename -	"this" to "us". - -	* signal.c (pthread_sigmask): Rename "this" to "us" and fix some -	minor syntax errors. Declare "us" and initialise it. - -	* sync.c (pthread_detach): Rename "this" to "target". - -	* pthread.h: Converting PTHREAD_* defines to alias the (const int) -	values in global.c. - -	* global.c: Started converting PTHREAD_* defines to (const int) as - 	a part of making the eventual pthreads DLL binary compatible - 	through version changes. - -	* condvar.c (cond_wait): Add cancelation point. This applies the -	point to both pthread_cond_wait() and pthread_cond_timedwait(). - -	* exit.c (pthread_exit): Rename "this" to "us". - -	* implement.h: Add comment. - -	* sync.c (pthread_join): I've satisfied myself that pthread_detach() -	does set the detached attribute in the thread entry attributes -	to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test -	that attribute instead of a separate flag. - -	* create.c (pthread_create): Rename "this" to "us". -	(pthread_create): cancelstate and canceltype are not attributes -	so the copy to thread entry attribute storage was removed. -	Only the thread itself can change it's cancelstate or canceltype, -	ie. the thread must exist already. - -	* private.c (ptw32_delete_thread_entry): Mutex locks removed. -	Mutexes must be applied at the caller level. -	(ptw32_new_thread_entry): Ditto. -	(ptw32_new_thread_entry): Init cancelstate, canceltype, and -	cancel_pending to default values. -	(ptw32_new_thread_entry): Rename "this" to "new". -	(ptw32_find_thread_entry): Rename "this" to "entry". -	(ptw32_delete_thread_entry): Rename "thread_entry" to "entry". - -	* create.c (ptw32_start_call): Mutexes changed to -	ptw32_count_mutex. All access to the threads table entries is -	under the one mutex. Otherwise chaos reigns. - -Sat Jul 25 23:16:51 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h (ptw32_threads_thread): Move cancelstate and - 	canceltype members out of pthread_attr_t into here. - -	* fork.c (fork): Add comment. - -1998-07-25  Ben Elliston  <bje@cygnus.com> - -	* fork.c (fork): Autoconfiscate. - -Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* create.c (ptw32_start_call): Set thread priority.  Ensure our - 	thread entry is removed from the thread table but only if - 	pthread_detach() was called and there are no waiting joins. -	(pthread_create): Set detach flag in thread entry if the  -	thread is created PTHREAD_CREATE_DETACHED. - -	* pthread.h (pthread_attr_t): Rename member "detachedstate". - -	* attr.c (pthread_attr_init): Rename attr members. - -	* exit.c (pthread_exit): Fix indirection mistake. - -	* implement.h (PTW32_THREADS_TABLE_INDEX): Add. - -	* exit.c (ptw32_vacuum): Fix incorrect args to -	ptw32_handler_pop_all() calls. -	Make thread entry removal conditional. - -	* sync.c (pthread_join): Add multiple join and async detach handling. - -	* implement.h (PTW32_THREADS_TABLE_INDEX): Add. - -	* global.c (ptw32_threads_mutex_table): Add. - -	* implement.h (ptw32_once_flag): Remove. -	(ptw32_once_lock): Ditto. -	(ptw32_threads_mutex_table): Add. - -	* global.c (ptw32_once_flag): Remove. -	(ptw32_once_lock): Ditto. - -	* sync.c (pthread_join): Fix tests involving new return value -	from ptw32_find_thread_entry(). -	(pthread_detach): Ditto. - -	* private.c (ptw32_find_thread_entry): Failure return code -	changed from -1 to NULL. - -Fri Jul 24 23:09:33 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* create.c (pthread_create): Change . to -> in sigmask memcpy() args. - -	* pthread.h: (pthread_cancel): Add function prototype. -	(pthread_testcancel): Ditto. - -1998-07-24  Ben Elliston  <bje@cygnus.com> - -	* pthread.h (pthread_condattr_t): Rename dummy structure member. -	(pthread_mutexattr_t): Likewise. - -Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* cancel.c (pthread_cancel): Implement. -	(pthread_testcancel): Implement. - -	* exit.c (pthread_exit): Add comment explaining the longjmp(). - -	* implement.h (ptw32_threads_thread_t): New member cancelthread. -	(PTW32_YES): Define. -	(PTW32_NO): Define. -	(RND_SIZEOF): Remove. - -	* create.c (pthread_create): Rename cancelability to cancelstate. - -	* pthread.h (pthread_attr_t): Rename cancelability to cancelstate. -	(PTHREAD_CANCELED): Define. - -1998-07-24  Ben Elliston  <bje@cygnus.com> - -	* pthread.h (SIG_BLOCK): Define if not already defined. -	(SIG_UNBLOCK): Likewise. -	(SIG_SETMASK): Likewise. -	(pthread_attr_t): Add signal mask member. -	(pthread_sigmask): Add function prototype. - -	* signal.c (pthread_sigmask): Implement. - -	* create.c: #include <string.h> to get a prototype for memcpy(). -	(pthread_create): New threads inherit their creator's signal -	mask.  Copy the signal mask to the new thread structure if we know -	about signals. -	 -Fri Jul 24 16:33:17 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* fork.c (pthread_atfork): Add all the necessary push calls. -	Local implementation semantics: -	If we get an ENOMEM at any time then ALL handlers -	(including those from previous pthread_atfork() calls) will be -	popped off each of the three atfork stacks before we return. -	(fork): Add all the necessary pop calls. Add the thread cancellation -	and join calls to the child fork. -	Add #includes. - -	* implement.h: (ptw32_handler_push): Fix return type and stack arg -	type in prototype. -	(ptw32_handler_pop): Fix stack arg type in prototype. -	(ptw32_handler_pop_all): Fix stack arg type in prototype. - -	* cleanup.c (ptw32_handler_push): Change return type to int and -	return ENOMEM if malloc() fails. - -	* sync.c (pthread_detach): Use equality test, not assignment. - -	* create.c (ptw32_start_call): Add call to Win32 CloseHandle() -	if thread is detached. - -1998-07-24  Ben Elliston  <bje@cygnus.com> - -	* sync.c (pthread_detach): Close the Win32 thread handle to -	emulate detached (or daemon) threads. - -Fri Jul 24 03:00:25 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* sync.c (pthread_join): Save valueptr arg in joinvalueptr for -	pthread_exit() to use. - -	* private.c (ptw32_new_thread_entry): Initialise joinvalueptr to -	NULL. - -	* create.c (ptw32_start_call): Rewrite to facilitate joins. -	pthread_exit() will do a longjmp() back to here. Does appropriate -	cleanup and exit/return from the thread. -	(pthread_create): _beginthreadex() now passes a pointer to our -	thread table entry instead of just the call member of that entry. - -	* implement.h (ptw32_threads_thread): New member  -	void ** joinvalueptr. -	(ptw32_call_t): New member jmpbuf env. - -	* exit.c (pthread_exit): Major rewrite to handle joins and handing -	value pointer to joining thread. Uses longjmp() back to  -	ptw32_start_call(). - -	* create.c (pthread_create): Ensure values of new attribute members -	are copied to the thread attribute object. - -	* attr.c (pthread_attr_destroy):  Fix merge conflicts. -	(pthread_attr_getdetachstate):  Fix merge conflicts. -	(pthread_attr_setdetachstate):  Fix merge conflicts. - -	* pthread.h:  Fix merge conflicts. - -	* sync.c (pthread_join): Fix merge conflicts. - -Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* sync.c (pthread_join): Add check for valid and joinable -	thread. -	(pthread_detach): Implement. After checking for a valid and joinable -	thread, it's still a no-op. - -	* private.c (ptw32_find_thread_entry): Bug prevented returning -	an error value in some cases. - -	* attr.c (pthread_attr_setdetachedstate): Implement. -	(pthread_attr_getdetachedstate): Implement. - -	* implement.h: Move more hidden definitions into here from -	pthread.h. - -1998-07-24  Ben Elliston  <bje@cygnus.com> - -	* pthread.h (PTHREAD_CREATE_JOINABLE): Define. -	(PTHREAD_CREATE_DETACHED): Likewise. -	(pthread_attr_t): Add new structure member `detached'. -	(pthread_attr_getdetachstate): Add function prototype. -	(pthread_attr_setdetachstate): Likewise. - -	* sync.c (pthread_join): Return if the target thread is detached. - -	* attr.c (pthread_attr_init): Initialise cancelability and -	canceltype structure members. -	(pthread_attr_getdetachstate): Implement. -	(pthread_attr_setdetachstate): Likewise. - -	* 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. - -	* cancel.c: New file. - -	* pthread.h (sched_param): Define this type. -	(pthread_attr_getschedparam): Add function prototype. -	(pthread_attr_setschedparam): Likewise. -	(pthread_setcancelstate): Likewise. -	(pthread_setcanceltype): Likewise. -	(sched_get_priority_min): Likewise. -	(sched_get_priority_max): Likewise. -	(pthread_mutexattr_setprotocol): Remove; not supported. -	(pthread_mutexattr_getprotocol): Likewise. -	(pthread_mutexattr_setprioceiling): Likewise. -	(pthread_mutexattr_getprioceiling): Likewise. -	(pthread_attr_t): Add canceltype member.  Update comments. -	(SCHED_OTHER): Define this scheduling policy constant. -	(SCHED_FIFO): Likewise. -	(SCHED_RR): Likewise. -	(SCHED_MIN): Define the lowest possible value for this constant. -	(SCHED_MAX): Likewise, the maximum possible value. -	(PTHREAD_CANCEL_ASYNCHRONOUS): Redefine. -	(PTHREAD_CANCEL_DEFERRED): Likewise. -	 -	* sched.c: New file. -	(pthread_setschedparam): Implement. -	(pthread_getschedparam): Implement. -	(sched_get_priority_max): Validate policy argument. -	(sched_get_priority_min): Likewise. - -	* mutex.c (pthread_mutexattr_setprotocol): Remove; not supported. -	(pthread_mutexattr_getprotocol): Likewise. -	(pthread_mutexattr_setprioceiling): Likewise. -	(pthread_mutexattr_getprioceiling): Likewise. - -Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* create.c (pthread_create): Arg to ptw32_new_thread_entry() -	changed. See next entry. Move mutex locks out. Changes made yesterday -	and today allow us to start the new thread running rather than -	temporarily suspended. - -	* private.c (ptw32_new_thread_entry): ptw32_thread_table -	was changed back to a table of thread structures rather than pointers. -	As such we're trading storage for increaded speed. This routine -	was modified to work with the new table. Mutex lock put in around -	global data accesses. -	(ptw32_find_thread_entry): Ditto -	(ptw32_delete_thread_entry): Ditto - -Thu Jul 23 23:25:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* global.c: New. Global data objects declared here. These moved from -	pthread.h. - -	* pthread.h: Move implementation hidden definitions into -	implement.h. - -	* implement.h: Move implementation hidden definitions from -	pthread.h. Add constants to index into the different handler stacks. - -	* cleanup.c (ptw32_handler_push): Simplify args. Restructure. -	(ptw32_handler_pop): Simplify args. Restructure. -	(ptw32_handler_pop_all): Simplify args. Restructure. - -Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge -	conflicts. - -	* private.c (ptw32_find_thread_entry): Changes to return type -	to support leaner ptw32_threads_table[] which now only stores -	ptw32_thread_thread_t *. -	(ptw32_new_thread_entry): Internal changes. -	(ptw32_delete_thread_entry): Internal changes to avoid contention. - 	Calling routines changed accordingly. - -	* pthread.h: Modified cleanup macros to use new generic push and pop. -	Added destructor and atfork stacks to ptw32_threads_thread_t. - -	* cleanup.c (ptw32_handler_push, ptw32_handler_pop, -	ptw32_handler_pop_all): Renamed cleanup push and pop routines -	and made generic to handle destructors and atfork handlers as -	well. - -	* create.c (ptw32_start_call): New function is a wrapper for -	all new threads. It allows us to do some cleanup when the thread -	returns, ie. that is otherwise only done if the thread is cancelled. - -	* exit.c (ptw32_vacuum): New function contains code from  -	pthread_exit() that we need in the new ptw32_start_call() -	as well. - -	* implement.h: Various additions and minor changes. - -	* pthread.h: Various additions and minor changes. -	Change cleanup handler macros to use generic handler push and pop -	functions. - -	* attr.c: Minor mods to all functions. -	(is_attr): Implemented missing function. - -	* create.c (pthread_create): More clean up. - -	* private.c (ptw32_find_thread_entry): Implement. -	(ptw32_delete_thread_entry): Implement. -	(ptw32_new_thread_entry): Implement. -	These functions manipulate the implementations internal thread -	table and are part of general code cleanup and modularisation. -	They replace ptw32_getthreadindex() which was removed. - -	* exit.c (pthread_exit): Changed to use the new code above. - -	* pthread.h: Add cancelability constants. Update comments. - -1998-07-22  Ben Elliston  <bje@cygnus.com> - -	* attr.c (pthread_setstacksize): Update test of attr argument. -	(pthread_getstacksize): Likewise. -	(pthread_setstackaddr): Likewise. -	(pthread_getstackaddr): Likewise. -	(pthread_attr_init): No need to allocate any storage. -	(pthread_attr_destroy): No need to free any storage. - -	* mutex.c (is_attr): Not likely to be needed; remove. -	(remove_attr): Likewise. -	(insert_attr): Likewise. - -	* implement.h (ptw32_mutexattr_t): Moved to a public definition -	in pthread.h.  There was little gain in hiding these details. -	(ptw32_condattr_t): Likewise. -	(ptw32_attr_t): Likewise. - -	* pthread.h (pthread_atfork): Add function prototype. -	(pthread_attr_t): Moved here from implement.h. - -	* fork.c (pthread_atfork): Preliminary implementation. -	(ptw32_fork): Likewise. - -Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* cleanup.c (ptw32_cleanup_push): Implement. -	(ptw32_cleanup_pop): Implement. -	(ptw32_do_cancellation): Implement. -	These are private to the implementation. The real cleanup functions -	are macros. See below. - -	* pthread.h (pthread_cleanup_push): Implement as a macro. -	(pthread_cleanup_pop): Implement as a macro. -	Because these are macros which start and end a block, the POSIX scoping -	requirement is observed. See the comment in the file. - -	* exit.c (pthread_exit): Refine the code. - -	* create.c (pthread_create): Code cleanup. - -	* implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T) -	up to multiple of DWORD. -	Add function prototypes. - -	* private.c (ptw32_getthreadindex): "*thread" should have been  -	"thread". Detect empty slot fail condition. - -1998-07-20  Ben Elliston  <bje@cygnus.com> - -	* misc.c (pthread_once): Implement.  Don't use a per-application -	flag and mutex--make `pthread_once_t' contain these elements in -	their structure.  The earlier version had incorrect semantics. -	 -	* pthread.h (ptw32_once_flag): Add new variable.  Remove. -	(ptw32_once_lock): Add new mutex lock to ensure integrity of -	access to ptw32_once_flag.  Remove. -	(pthread_once): Add function prototype. -	(pthread_once_t): Define this type. -	 -Mon Jul 20 02:31:05 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* private.c (ptw32_getthreadindex): Implement. - -	* pthread.h: Add application static data dependent on -	_PTHREADS_BUILD_DLL define. This is needed to avoid allocating -	non-sharable static data within the pthread DLL. - -	* implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t -	and PTW32_HASH_INDEX. - -	* exit.c (pthread_exit): Begin work on cleanup and de-allocate -	thread-private storage. - -	* create.c (pthread_create): Add thread to thread table. -	Keep a thread-private copy of the attributes with default values -	filled in when necessary. Same for the cleanup stack. Make  -	pthread_create C run-time library friendly by using _beginthreadex() -	instead of CreateThread(). Fix error returns. - -Sun Jul 19 16:26:23 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h: Rename pthreads_thread_count to ptw32_threads_count. -	Create ptw32_threads_thread_t struct to keep thread specific data. - -	* create.c: Rename pthreads_thread_count to ptw32_threads_count. -	(pthread_create): Handle errors from CreateThread(). - -1998-07-19  Ben Elliston  <bje@cygnus.com> - -	* condvar.c (pthread_cond_wait): Generalise.  Moved from here .. -	(cond_wait): To here. -	(pthread_cond_timedwait): Implement; use generalised cond_wait(). - -	* pthread.h (pthread_key_t): Define this type. -	(pthread_key_create): Add function prototype. -	(pthread_setspecific): Likewise. -	(pthread_getspecific): Likwise. -	(pthread_key_delete): Likewise. - -	* tsd.c (pthread_key_create): Implement. -	(pthread_setspecific): Likewise. -	(pthread_getspecific): Likewise. -	(pthread_key_delete): Likewise. - -	* mutex.c (pthread_mutex_trylock): Return ENOSYS if this function -	is called on a Win32 platform which is not Windows NT. - -1998-07-18  Ben Elliston  <bje@cygnus.com> - -	* condvar.c (pthread_condattr_init): Do not attempt to malloc any -	storage; none is needed now that condattr_t is an empty struct. -	(pthread_condattr_destory): Likewise; do not free storage. -	(pthread_condattr_setpshared): No longer supported; return ENOSYS. -	(pthread_condattr_getpshared): Likewise. -	(pthread_cond_init): Implement with help from Douglas Schmidt. -	Remember to initialise the cv's internal mutex. -	(pthread_cond_wait): Likewise. -	(pthread_cond_signal): Likewise. -	(pthread_cond_broadcast): Likewise. -	(pthread_cond_timedwait): Preliminary implementation, but I need -	to see some API documentation for `WaitForMultipleObject'. -	(pthread_destory): Implement. - -	* pthread.h (pthread_cond_init): Add function protoype. -	(pthread_cond_broadcast): Likewise. -	(pthread_cond_signal): Likewise. -	(pthread_cond_timedwait): Likewise. -	(pthread_cond_wait): Likewise. -	(pthread_cond_destroy): Likewise. -	(pthread_cond_t): Define this type.  Fix for u_int.  Do not assume -	that the mutex contained withing the pthread_cond_t structure will -	be a critical section.  Use our new POSIX type! - -	* implement.h (ptw32_condattr_t): Remove shared attribute. - -1998-07-17  Ben Elliston  <bje@cygnus.com> - -	* pthread.h (PTHREADS_PROCESS_PRIVATE): Remove. -	(PTHREAD_PROCESS_SHARED): Likewise.  No support for mutexes shared -	across processes for now. -	(pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better -	performance. -	 -	* implement.h (ptw32_mutexattr_t): Remove shared attribute. -	 -	* mutex.c (pthread_mutexattr_setpshared): This optional function -	is no longer supported, since we want to implement POSIX mutex -	variables using the much more efficient Win32 critical section -	primitives.  Critical section objects in Win32 cannot be shared -	between processes. -	(pthread_mutexattr_getpshared): Likewise. -	(pthread_mutexattr_init): No need to malloc any storage; the -	attributes structure is now empty. -	(pthread_mutexattr_destroy): This is now a nop. -	(pthread_mutex_init): Use InitializeCriticalSection(). -	(pthread_mutex_destroy): Use DeleteCriticalSection(). -	(pthread_mutex_lock): Use EnterCriticalSection(). -	(pthread_mutex_trylock): Use TryEnterCriticalSection().  This is -	not supported by Windows 9x, but trylock is a hack anyway, IMHO. -	(pthread_mutex_unlock): Use LeaveCriticalSection(). - -1998-07-14  Ben Elliston  <bje@cygnus.com> - -	* attr.c (pthread_attr_setstacksize): Implement. -	(pthread_attr_getstacksize): Likewise. -	(pthread_attr_setstackaddr): Likewise. -	(pthread_attr_getstackaddr): Likewise. -	(pthread_attr_init): Likewise. -	(pthread_attr_destroy): Likewise. -	 -	* condvar.c (pthread_condattr_init): Add `_cond' to function name. - -	* mutex.c (pthread_mutex_lock): Add `_mutex' to function name. -	(pthread_mutex_trylock): Likewise. -	(pthread_mutex_unlock): Likewise. - -	* pthread.h (pthread_condattr_setpshared): Fix typo. -	(pthread_attr_init): Add function prototype. -	(pthread_attr_destroy): Likewise. -	(pthread_attr_setstacksize): Likewise. -	(pthread_attr_getstacksize): Likewise. -	(pthread_attr_setstackaddr): Likewise. -	(pthread_attr_getstackaddr): Likewise. -	 -Mon Jul 13 01:09:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h: Wrap in #ifndef _IMPLEMENT_H - -	* create.c (pthread_create): Map stacksize attr to Win32. - -	* mutex.c: Include implement.h - -1998-07-13  Ben Elliston  <bje@cygnus.com> - -	* condvar.c (pthread_condattr_init): Implement. -	(pthread_condattr_destroy): Likewise. -	(pthread_condattr_setpshared): Likewise. -	(pthread_condattr_getpshared): Likewise. -	 -	* implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon. -	(PTHREAD_STACK_MIN): Specify; needs confirming. -	(ptw32_attr_t): Define this type. -	(ptw32_condattr_t): Likewise. - -	* pthread.h (pthread_mutex_t): Define this type. -	(pthread_condattr_t): Likewise. -	(pthread_mutex_destroy): Add function prototype. -	(pthread_lock): Likewise. -	(pthread_trylock): Likewise. -	(pthread_unlock): Likewise. -	(pthread_condattr_init): Likewise. -	(pthread_condattr_destroy): Likewise. -	(pthread_condattr_setpshared): Likewise. -	(pthread_condattr_getpshared): Likewise. - -	* mutex.c (pthread_mutex_init): Implement. -	(pthread_mutex_destroy): Likewise. -	(pthread_lock): Likewise. -	(pthread_trylock): Likewise. -	(pthread_unlock): Likewise. - -1998-07-12  Ben Elliston  <bje@cygnus.com> - -	* implement.h (ptw32_mutexattr_t): Define this implementation -	internal type.  Application programmers only see a mutex attribute -	object as a void pointer. - -	* pthread.h (pthread_mutexattr_t): Define this type. -	(pthread_mutexattr_init): Add function prototype. -	(pthread_mutexattr_destroy): Likewise. -	(pthread_mutexattr_setpshared): Likewise. -	(pthread_mutexattr_getpshared): Likewise. -	(pthread_mutexattr_setprotocol): Likewise. -	(pthread_mutexattr_getprotocol): Likewise. -	(pthread_mutexattr_setprioceiling): Likewise. -	(pthread_mutexattr_getprioceiling): Likewise. -	(PTHREAD_PROCESS_PRIVATE): Define. -	(PTHREAD_PROCESS_SHARED): Define. - -	* mutex.c (pthread_mutexattr_init): Implement. -	(pthread_mutexattr_destroy): Implement. -	(pthread_mutexattr_setprotocol): Implement. -	(pthread_mutexattr_getprotocol): Likewise. -	(pthread_mutexattr_setprioceiling): Likewise. -	(pthread_mutexattr_getprioceiling): Likewise. -	(pthread_mutexattr_setpshared): Likewise. -	(pthread_mutexattr_getpshared): Likewise. -	(insert_attr): New function; very preliminary implementation! -	(is_attr): Likewise. -	(remove_attr): Likewise. -	 -Sat Jul 11 14:48:54 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* implement.h: Preliminary implementation specific defines. - -	* create.c (pthread_create): Preliminary implementation. - -1998-07-11  Ben Elliston  <bje@cygnus.com> - -	* sync.c (pthread_join): Implement. - -	* misc.c (pthread_equal): Likewise. -	 -	* pthread.h (pthread_join): Add function prototype. -	(pthread_equal): Likewise. -	 -1998-07-10  Ben Elliston  <bje@cygnus.com> - -	* misc.c (pthread_self): Implement. - -	* exit.c (pthread_exit): Implement. - -	* pthread.h (pthread_exit): Add function prototype. -	(pthread_self): Likewise. -	(pthread_t): Define this type. - -1998-07-09  Ben Elliston  <bje@cygnus.com> - -	* create.c (pthread_create): A dummy stub right now. - -	* pthread.h (pthread_create): Add function prototype. - +2001-05-30  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	* pthread.h (rand_r): Fake using _seed argument to quell
 +	compiler warning (compiler should optimise this away later).
 +
 +	* GNUmakefile (OPT): Leave symbolic information out of the library
 +	and increase optimisation level - for smaller faster prebuilt
 +	dlls.
 +	
 +2001-05-29  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	Contributed by  - Milan Gardian <Milan.Gardian@LEIBINGER.com>
 +
 +	* Makefile: fix typo.
 +	* pthreads.h: Fix problems with stdcall/cdecl conventions, in particular
 +	remove the need for PT_STDCALL everywhere; remove warning supression.
 +	* (errno): Fix the longstanding "inconsistent dll linkage" problem
 +	with errno; now also works with /MD debugging libs - 
 +	warnings emerged when compiling pthreads library with /MD (or /MDd)
 +	compiler switch, instead of /MT (or /MTd) (i.e. when compiling pthreads
 +	using Multithreaded DLL CRT instead of Multithreaded statically linked
 +	CRT).
 +	* create.c (pthread_create): Likewise; fix typo.
 +	* private.c (ptw32_threadStart): Eliminate use of terminate() which doesn't
 +	throw exceptions.
 +	* Remove unnecessary #includes from a number of modules -
 +	[I had to #include malloc.h in implement.h for gcc - rpj].
 +
 +2001-05-29  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	Contributed by 	- Thomas Pfaff <tpfaff@gmx.net>
 +
 +	* pthread.h (PTHREAD_MUTEX_DEFAULT): New; equivalent to
 +	PTHREAD_MUTEX_DEFAULT_NP.
 +	* (PTHREAD_MUTEX_NORMAL): Similarly.
 +	* (PTHREAD_MUTEX_ERRORCHECK): Similarly.
 +	* (PTHREAD_MUTEX_RECURSIVE): Similarly.
 +	* (pthread_mutex_setdefaultkind_np): New; Linux compatibility stub
 +	for pthread_mutexattr_settype.
 +	* (pthread_mutexattr_getkind_np): New; Linux compatibility stub
 +	for pthread_mutexattr_gettype.
 +	* mutex.c (pthread_mutexattr_settype): New; allow
 +	the following types of mutex:
 +	  PTHREAD_MUTEX_DEFAULT_NP
 +	  PTHREAD_MUTEX_NORMAL_NP
 +	  PTHREAD_MUTEX_ERRORCHECK_NP
 +	  PTHREAD_MUTEX_RECURSIVE_NP
 +	* Note that PTHREAD_MUTEX_DEFAULT is equivalent to
 +	PTHREAD_MUTEX_NORMAL - ie. mutexes should no longer
 +	be recursive by default, and a thread will deadlock if it
 +	tries to relock a mutex it already owns. This is inline with
 +	other pthreads implementations.
 +	* (pthread_mutex_lock): Process the lock request
 +	according to the mutex type.
 +	* (pthread_mutex_init): Eliminate use of Win32 mutexes as the
 +	basis of POSIX mutexes - instead, a combination of one critical section
 +	and one semaphore are used in conjunction with Win32 Interlocked* routines.
 +	* (pthread_mutex_destroy): Likewise.
 +	* (pthread_mutex_lock): Likewise.
 +	* (pthread_mutex_trylock): Likewise.
 +	* (pthread_mutex_unlock): Likewise.
 +	* Use longjmp/setjmp to implement cancelation when building the library
 +	using a C compiler which doesn't support exceptions, e.g. gcc -x c (note
 +	that gcc -x c++ uses exceptions).
 +	* Also fixed some of the same typos and eliminated PT_STDCALL as
 +	Milan Gardian's patches above.
 +
 +2001-02-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	Contributed by  - Alexander Terekhov <TEREKHOV@de.ibm.com>
 +	
 +	* rwlock.c: Revamped.
 +	* implement.h (pthread_rwlock_t_): Redefined.
 +	This implementation does not have reader/writer starvation problem.
 +	Rwlock attempts to behave more like a normal mutex with
 +	races and scheduling policy determining who is more important;
 +	It also supports recursive locking,
 +	has less synchronization overhead (no broadcasts at all,
 +	readers are not blocked on any condition variable) and seem to
 +	be faster than the current implementation [W98 appears to be
 +	approximately 15 percent faster at least - on top of speed increase
 +	from Thomas Pfaff's changes to mutex.c - rpj].
 +
 +2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* Makefile: Back-out "for" loops which don't work.
 +
 +	* GNUmakefile: Remove the fake.a target; add the "realclean"
 +	target; don't remove built libs under the "clean" target.
 +
 +	* config.h: Add a guard against multiple inclusion.
 +
 +	* semaphore.h: Add some defines from config.h to make
 +	semaphore.h independent of config.h when building apps.
 +
 +	* pthread.h (_errno): Back-out previous fix until we know how to
 +	fix it properly.
 +
 +	* implement.h (lockCount): Add missing element to pthread_mutex_t_.
 +
 +	* sync.c (pthread_join): Spelling fix in comment.
 +
 +	* private.c (ptw32_threadStart): Reset original termination
 +	function (C++).
 +	(ptw32_threadStart): Cleanup detached threads early in case
 +	the library is statically linked.
 +	(ptw32_callUserDestroyRoutines): Remove [SEH] __try block from
 +	destructor call so that unhandled exceptions will be passed through
 +	to the 	system; call terminate() from [C++] try block for the same
 +	reason.
 +
 +	* tsd.c (pthread_getspecific): Add comment.
 +
 +	* mutex.c (pthread_mutex_init): Initialise new elements in
 +	pthread_mutex_t.
 +	(pthread_mutex_unlock): Invert "pthread_equal()" test.
 +
 +2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* semaphore.c (mode_t): Use ifndef HAVE_MODE_T to include definition.
 +
 +	* config.h.in (HAVE_MODE_T): Added.
 +	(_UWIN): Start adding defines for the UWIN package.
 +
 +	* private.c (ptw32_threadStart): Unhandled exceptions are
 +	now passed through to the system to deal with. This is consistent
 +	with normal Windows behaviour. C++ applications may use
 +	set_terminate() to override the default behaviour which is
 +	to call ptw32_terminate(). Ptw32_terminate() cleans up some
 +	POSIX thread stuff before calling the system default function
 +	which calls abort(). The users termination function should conform
 +	to standard C++ semantics which is to not return. It should
 +	exit the thread (call pthread_exit()) or exit the application.
 +	* private.c (ptw32_terminate): Added as the default set_terminate()
 +	function. It calls the system default function after cleaning up
 +	some POSIX thread stuff.
 +
 +	* implement.h (ptw32_try_enter_critical_section): Move
 +	declaration.
 +	* global.c (ptw32_try_enter_critical_section): Moved
 +	from dll.c.
 +	* dll.c: Move process and thread attach/detach code into
 +	functions in nonportable.c.
 +	* nonportable.c (pthread_win32_process_attach_np): Process
 +	attach code from dll.c is now available to static linked
 +	applications.
 +	* nonportable.c (pthread_win32_process_detach_np): Likewise.
 +	* nonportable.c (pthread_win32_thread_attach_np): Likewise.
 +	* nonportable.c (pthread_win32_thread_detach_np): Likewise.
 +
 +	* pthread.h: Add new non-portable prototypes for static
 +	linked applications.
 +
 +	* GNUmakefile (OPT): Increase optimisation flag and remove
 +	debug info flag.
 +
 +	* pthread.def: Add new non-portable exports for static
 +	linked applications.
 +
 +2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* FAQ: Update Answer 6 re getting a fully working
 +	Mingw32 built library.
 +
 +2000-10-10  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 + 
 +        * misc.c (pthread_self): Restore Win32 "last error"
 +        cleared by TlsGetValue() call in
 +        pthread_getspecific()
 +        - "Steven Reddie" <smr@essemer.com.au>
 + 
 +2000-09-20  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 + 
 +        * mutex.c (pthread_mutex_lock): Record the owner
 +        of the mutex. This requires also keeping count of
 +        recursive locks ourselves rather than leaving it
 +        to Win32 since we need to know when to NULL the
 +        thread owner when the mutex is unlocked.
 +        (pthread_mutex_trylock): Likewise.
 +        (pthread_mutex_unlock): Check that the calling
 +        thread owns the mutex, decrement the recursive
 +        lock count, and NULL the owner if zero. Return
 +        EPERM if the mutex is owned by another thread.
 +        * implement.h (pthread_mutex_t_): Add ownerThread
 +        and lockCount members.
 +        - reported by Arthur Kantor <akantor@bexusa.com>
 +
 +2000-09-13  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	* mutex.c (pthread_mutex_init): Call
 +	TryEnterCriticalSection through the pointer
 +	rather than directly so that the dll can load
 +	on Windows versions that can't resolve the
 +	function, eg. Windows 95
 +	- "Jef Gearhart" <jgearhart@tpssys.com>
 +
 +2000-09-09  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* pthread.h (ctime_r): Fix arg.
 +
 +2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* GNUmakefile(_WIN32_WINNT=0x400): Define in CFLAGS;
 +	doesn't seem to be needed though.
 +
 +	* cancel.c (pthread_cancel): Must get "self" through
 +	calling pthread_self() which will ensure a POSIX thread
 +	struct is built for non-POSIX threads; return an error
 +	if this fails
 +	- Ollie Leahy <ollie@mpt.ie>
 +	(pthread_setcancelstate): Likewise.
 +	(pthread_setcanceltype): Likewise.
 +	* misc.c (ptw32_cancelable_wait): Likewise.
 +
 +	* private.c (ptw32_tkAssocCreate): Remove unused #if 0
 +	wrapped code.
 +
 +	* pthread.h (ptw32_get_exception_services_code):
 +	Needed to be forward declared unconditionally.
 +
 +2000-09-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cancel.c (pthread_cancel): If called from the main
 +	thread "self" would be NULL; get "self" via pthread_self()
 +	instead of directly from TLS so that an implicit
 +	pthread object is created.
 +
 +	* misc.c (pthread_equal): Strengthen test for NULLs.
 +
 +2000-09-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* condvar.c (ptw32_cond_wait_cleanup): Ensure that all
 +	waking threads check if they are the last, and notify
 +	the broadcaster if so - even if an error occurs in the
 +	waiter.
 +
 +	* semaphore.c (_decrease_semaphore): Should be
 +	a call to ptw32_decrease_semaphore.
 +	(_increase_semaphore): Should be a call to
 +	ptw32_increase_semaphore.
 +
 +	* misc.c (ptw32_cancelable_wait): Renamed from
 +	CancelableWait.
 +	* rwlock.c (_rwlock_check*): Renamed to
 +	ptw32_rwlock_check*.
 +	* mutex.c (_mutex_check*): Renamed to ptw32_mutex_check*.
 +	* condvar.c (cond_timed*): Renamed to ptw32_cond_timed*.
 +	(_cond_check*): Renamed to ptw32_cond_check*.
 +	(cond_wait_cleanup*): Rename to ptw32_cond_wait_cleanup*.
 +	(ptw32_cond_timedwait): Add comments.
 +
 +2000-08-22  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	* private.c (ptw32_throw): Fix exception test;
 +	move exceptionInformation declaration.
 +
 +	* tsd.c (pthread_key_create): newkey wrongly declared.
 +
 +	* pthread.h: Fix comment block.
 +
 +2000-08-18  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	* mutex.c (pthread_mutex_destroy): Check that the mutex isn't
 +	held; invalidate the mutex as early as possible to avoid
 +	contention; not perfect - FIXME!
 +
 +	* rwlock.c (pthread_rwlock_init): Remove redundant assignment
 +	to "rw".
 +	(pthread_rwlock_destroy): Invalidate the rwlock before
 +	freeing up any of it's resources - to avoid contention.
 +
 +	* private.c (ptw32_tkAssocCreate): Change assoc->lock
 +	to use a dynamically initialised mutex - only consumes
 +	a W32 mutex or critical section when first used,
 +	not before.
 +
 +	* mutex.c (pthread_mutex_init): Remove redundant assignment
 +	to "mx".
 +	(pthread_mutexattr_destroy): Set attribute to NULL
 +	before freeing it's memory - to avoid contention.
 +
 +	* implement.h (PTW32_EPS_CANCEL/PTW32_EPS_EXIT):
 +	Must be defined for all compilers - used as generic
 +	exception selectors by ptw32_throw().
 +
 +	* 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
 +	ptw32_ prefix to remove leading underscores
 +	from private library identifiers (single
 +	and double leading underscores are reserved in the
 +	ANSI C standard for compiler implementations).
 +
 +	* tsd.c (pthread_create_key): Initialise temporary
 +	key before returning it's address to avoid race
 +	conditions.
 +
 +2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* errno.c: Add _MD precompile condition; thus far
 +	had no effect when using /MD compile option but I
 +	thnk it should be there.
 +
 +	* exit.c: Add __cplusplus to various #if lines;
 +	was compiling SEH code even when VC++ had
 +	C++ compile options.
 +
 +	* private.c: ditto.
 +
 +	* create.c (pthread_create): Add PT_STDCALL macro to
 +	function pointer arg in _beginthread().
 +
 +	* pthread.h: PT_STDCALL really does need to be defined
 +	in both this and impliment.h; don't set it to __cdecl
 +	- this macro is only used to extend function pointer
 +	casting for functions that will be passed as parameters.
 +	(~PThreadCleanup): add cast and group expression.
 +	(_errno): Add _MD compile conditional.
 +	(PtW32NoCatchWarn): Change pragma message.
 +
 +	* implement.h: Move and change PT_STDCALL define.
 +
 +	* need_errno.h: Add _MD to compilation conditional.
 +
 +	* GNUmakefile: Substantial rewrite for new naming
 +	convention; set for nil optimisation (turn it up
 +	when we have a working library build; add target
 +	"fake.a" to build a libpthreadw32.a from the VC++
 +	built DLL pthreadVCE.dll.
 +
 +	* pthread.def (LIBRARY): Don't specify in the .def
 +	file - it is specified on the linker command line
 +	since we now use the same .def file for variously
 +	named .dlls.
 +
 +	* Makefile: Substantial rewrite for new naming
 +	convention; default nmake target only issues a
 +	help message; run nmake with specific target
 +	corresponding to the EH scheme being used.
 +
 +	* README: Update information; add naming convention
 +	explanation.
 +
 +	* ANNOUNCE: Update information.
 +
 +2000-08-12  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* pthread.h: Add compile-time message when using
 +	MSC_VER compiler and C++ EH to warn application
 +	programmers to use PtW32Catch instead of catch(...)
 +	if they want cancelation and pthread_exit to work.
 +
 +	* implement.h: Remove #include <semaphore.h>; we
 +	use our own local semaphore.h.
 +
 +2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cleanup.c (pthread_pop_cleanup): Remove _pthread
 +	prefix from __except and catch keywords; implement.h
 +	now simply undefines ptw32__except and
 +	ptw32_catch if defined; VC++ was not textually
 +	substituting ptw32_catch etc back to catch as
 +	it was redefined; the reason for using the prefixed
 +	version was to make it clear that it was not using
 +	the pthread.h redefined catch keyword.
 +
 +	* private.c (ptw32_threadStart): Ditto.
 +	(ptw32_callUserDestroyRoutines): Ditto.
 +
 +	* implement.h (ptw32__except): Remove #define.
 +	(ptw32_catch): Remove #define.
 +
 +	* GNUmakefile (pthread.a): New target to build
 +	libpthread32.a from pthread.dll using dlltool.
 +
 +	* buildlib.bat: Duplicate cl commands with args to
 +	build C++ EH version of pthread.dll; use of .bat
 +	files is redundant now that nmake compatible
 +	Makefile is included; used as a kludge only now.
 +
 +	* Makefile: Localise some macros and fix up the clean:
 +	target to extend it and work properly.
 +
 +	* CONTRIBUTORS: Add contributors.
 +
 +	* ANNOUNCE: Updated.
 +
 +	* README: Updated.
 +
 +2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* pthread.h: Remove #warning - VC++ doesn't accept it.
 +
 +2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* pthread.h (PtW32CatchAll): Add macro. When compiling
 +	applications using VC++ with C++ EH rather than SEH
 +	'PtW32CatchAll' must be used in place of any 'catch( ... )'
 +	if the application wants pthread cancelation or
 +	pthread_exit() to work.
 +
 +2000-08-03  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* pthread.h: Add a base class ptw32_exception for
 +	library internal exceptions and change the "catch"
 +	re-define macro to use it.
 +
 +2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* GNUmakefile (CFLAGS): Add -mthreads.
 +	Add new targets to generate cpp and asm output.
 +
 +	* sync.c (pthread_join): Remove dead code.
 +
 +2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* sched.c (sched_get_priority_max): Handle different WinCE and
 +	Win32 priority values together.
 +	(sched_get_priority_min): Ditto.
 +	- Tristan Savatier <tristan@mpegtv.com>
 +
 +	* create.c (pthread_create): Force new threads to wait until
 +	pthread_create has the new thread's handle; we also retain
 +	a local copy of the handle for internal use until
 +	pthread_create returns.
 +
 +	* private.c (ptw32_threadStart): Initialise ei[].
 +	(ptw32_threadStart): When beginthread is used to start the
 +	thread, force waiting until the creator thread had the 
 +	thread handle.
 +
 +	* cancel.c (ptw32_cancel_thread): Include context switch
 +	code for defined(_X86_) environments in addition to _M_IX86.
 +
 +	* rwlock.c (pthread_rwlock_destroy): Assignment changed
 +	to avoid compiler warning.
 +
 +	* private.c (ptw32_get_exception_services_code): Cast
 +	NULL return value to avoid compiler warning.
 +
 +	* cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
 +	to avoid compiler warnings.
 +
 +	* misc.c (ptw32_new): Change "new" variable to "t" to avoid
 +	confusion with the C++ keyword of the same name.
 +
 +	* condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
 +	(cond_timedwait): Remove unused local variables. to avoid
 +	compiler warnings.
 +
 +	* dll.c (dllMain): Remove 2000-07-21 change - problem
 +	appears to be in pthread_create().
 +
 +2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* tsd.c (pthread_key_create): If a destructor was given
 +	and the pthread_mutex_init failed, then would try to
 +	reference a NULL pointer (*key); eliminate this section of
 +	code by using a dynamically initialised mutex
 +	(PTHREAD_MUTEX_INITIALIZER).
 +
 +	* tsd.c (pthread_setspecific): Return an error if
 +	unable to set the value; simplify cryptic conditional.
 +
 +	* tsd.c (pthread_key_delete): Locking threadsLock relied
 +	on mutex_lock returning an error if the key has no destructor.
 +	ThreadsLock is only initialised if the key has a destructor.
 +	Making this mutex a static could reduce the number of mutexes
 +	used by an application since it is actually created only at
 +	first use and it's often destroyed soon after.
 +	
 +2000-07-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* FAQ: Added Q5 and Q6.
 +
 +2000-07-21  Ross Johnson  <rpj@setup1.ise.canberra.edu.au>
 +
 +	* create.c (pthread_create): Set threadH to 0 (zero)
 +	everywhere. Some assignments were using NULL. Maybe
 +	it should be NULL everywhere - need to check. (I know
 +	they are nearly always the same thing - but not by
 +	definition.)
 +
 +	* dll.c: Include resource leakage work-around. This is a
 +	partial FIXME which doesn't stop all leakage. The real
 +	problem needs to be found and fixed.
 +	- "David Baggett" <dmb@itasoftware.com>
 +
 +	* misc.c (pthread_self): Try to catch NULL thread handles
 +	at the point where they might be generated, even though
 +	they should always be valid at this point.
 +
 +	* tsd.c (pthread_setspecific): return an error value if
 +	pthread_self() returns NULL.
 +
 +	* sync.c (pthread_join): return an error value if
 +	pthread_self() returns NULL.
 +
 +	* signal.c (pthread_sigmask): return an error value if
 +	pthread_self() returns NULL.
 +
 +2000-03-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* attr.c (pthread_attr_init): Set default stacksize to zero (0)
 +	rather than PTHREAD_STACK_MIN even though these are now the same.
 +
 +	* pthread.h (PTHREAD_STACK_MIN): Lowered to 0.
 +
 +2000-01-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* mutex.c (pthread_mutex_init): Free mutex if it has been alloced;
 +	if critical sections can be used instead of Win32 mutexes, test
 +	that the critical section works and return an error if not.
 +
 +2000-01-07  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cleanup.c (pthread_pop_cleanup): Include SEH code only if MSC is not
 +	compiling as C++.
 +	(pthread_push_cleanup): Include SEH code only if MSC is not
 +	compiling as C++.
 +
 +	* pthread.h: Include SEH code only if MSC is not
 +	compiling as C++.
 +
 +	* implement.h: Include SEH code only if MSC is not
 +	compiling as C++.
 +
 +	* cancel.c (ptw32_cancel_thread): Add _M_IX86 check.
 +	(pthread_testcancel): Include SEH code only if MSC is not
 +	compiling as C++.
 +	(ptw32_cancel_self): Include SEH code only if MSC is not
 +	compiling as C++.
 +
 +2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* Makefile: Remove inconsistencies in 'cl' args
 +	- Erik Hensema <erik.hensema@group2000.nl>
 +
 +2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* private.c (ptw32_get_exception_services_code): New; returns
 +	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_PTW32_SERVICES value instead of
 +	using the ptw32_exception_services variable which I had
 +	trouble exporting through pthread.def.
 +
 +	* global.c (ptw32_exception_services): Remove declaration.
 +
 +1999-11-22  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* implement.h: Forward declare ptw32_new();
 +
 +	* misc.c (ptw32_new): New; alloc and initialise a new pthread_t.
 +	(pthread_self): New thread struct is generated 	by new routine
 +	ptw32_new().
 +
 +	* create.c (pthread_create): New thread struct is generated
 +	by new routine ptw32_new().
 +
 +1999-11-21  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* global.c (ptw32_exception_services): Declare new variable. 
 +
 +	* private.c (ptw32_threadStart): Destroy thread's
 +	cancelLock mutex; make 'catch' and '__except' usageimmune to
 +	redfinitions in pthread.h.
 +	(ptw32_processInitialize): Init new constant ptw32_exception_services.
 +
 +	* create.c (pthread_create): Initialise thread's cancelLock
 +	mutex.
 +
 +	* cleanup.c (pthread_pop_cleanup): Make 'catch' and '__except'
 +	usage immune to redfinition s in pthread.h.
 +
 +	* private.c: Ditto.
 +
 +	* pthread.h (catch): Redefine 'catch' so that C++ applications
 +	won't catch our internal exceptions.
 +	(__except): ditto for __except.
 +
 +	* implement.h (ptw32_catch): Define internal version
 +	of 'catch' because 'catch' is redefined by pthread.h.
 +	(__except): ditto for __except.
 +	(struct pthread_t_): Add cancelLock mutex for async cancel
 +	safety.
 +
 +	* cancel.c (ptw32_cancel_self): New; part of the async
 +	cancellation implementation.
 +	(ptw32_cancel_thread): Ditto; this function is X86
 +	processor specific.
 +	(pthread_setcancelstate): Add check for pending async
 +	cancel request and cancel the calling thread if
 +	required; add async-cancel safety lock.
 +	(pthread_setcanceltype): Ditto.
 +	- Jason Nye <jnye@nbnet.nb.ca>
 +	- Erik Hensema <erik.hensema@group2000.nl>
 +
 +1999-11-13  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* configure.in (AC_OUTPUT): Put generated output into GNUmakefile
 +	rather than Makefile. Makefile will become the MSC nmake compatible
 +	version
 +	- Erik Hensema <erik.hensema@group2000.nl>
 +
 +	* misc.c (pthread_self): Add a note about GetCurrentThread
 +	returning a pseudo-handle
 +	- John Bossom (John.Bossom@cognos.com>
 +
 +1999-11-10  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* dll.c (dllMain): Free kernel32 ASAP.
 +	If TryEnterCriticalSection is not being used, then free
 +	the kernel32.dll handle now, rather than leaving it until
 +	DLL_PROCESS_DETACH.
 +
 +	Note: this is not a pedantic exercise in freeing unused
 +	resources!  It is a work-around for a bug in Windows 95
 +	(see microsoft knowledge base article, Q187684) which
 +	does Bad Things when FreeLibrary is called within
 +	the DLL_PROCESS_DETACH code, in certain situations.
 +	Since w95 just happens to be a platform which does not
 +	provide TryEnterCriticalSection, the bug will be
 +	effortlessly avoided.
 +	- Todd Owen <towen@lucidcalm.dropbear.id.au>
 +
 +	* sync.c (pthread_join): Make it a deferred cancelation point.
 +
 +	* misc.c (pthread_self): Explicitly initialise implicitly
 +	created thread state to default values.
 +
 +1999-11-05  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (winsock.h): Include unconditionally.
 +	(ETIMEDOUT): Change fallback value to that defined by winsock.h.
 +	
 +	* general: Patched for portability to WinCE. The details are
 +	described in the file WinCE-PORT. Follow the instructions
 +	in README.WinCE to make the appropriate changes in config.h.
 +	- Tristan Savatier <tristan@mpegtv.com>
 +
 +1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* create.c (pthread_create): Explicitly initialise thread state to
 +	default values.
 +
 +	* cancel.c (pthread_setcancelstate): Check for NULL 'oldstate'
 +	for compatibility with Solaris pthreads;
 +	(pthread_setcanceltype): ditto:
 +	- Erik Hensema <erik.hensema@group2000.nl>
 +
 +1999-10-23  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (ctime_r): Fix incorrect argument "_tm"
 +	- Erik Hensema <erik.hensema@group2000.nl>
 +
 +1999-10-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (_POSIX_THREADS): Only define it if it isn't
 +	already defined. Projects may need to define this on
 +	the CC command line under Win32 as it doesn't have unistd.h
 +	- Aurelio Medina <aureliom@crt.com>
 +
 +1999-10-17  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* rwlock.c (pthread_rwlock_destroy): Add cast to remove compile
 +	warning.
 +
 +	* condvar.c (pthread_cond_broadcast): Only release semaphores
 +	if there are waiting threads.
 +
 +1999-10-15  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (cond_wait_cleanup): New static cleanup handler for
 +	cond_timedwait;
 +	(cond_timedwait): pthread_cleanup_push args changed;
 +	canceling a thread while it's in pthread_cond_wait
 +	will now decrement the waiters count and cleanup if it's the
 +	last waiter.
 +	- Lorin Hochstein <lmh@xiphos.ca> and 
 +	  Peter Slacik <Peter.Slacik@tatramed.sk>;
 +	the last waiter will now reset the CV's wasBroadcast flag
 +	- Graham Dumpleton <Graham.Dumpleton@ra.pad.otc.telstra.com.au>.
 +
 +Thu Sep 16 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* rwlock.c (pthread_rwlock_destroy): Add serialisation.
 +	(_rwlock_check_need_init): Check for detroyed rwlock.
 +	* rwlock.c: Check return codes from _rwlock_check_need_init();
 +	modify comments; serialise access to rwlock objects during
 +	operations; rename rw_mutex to rw_lock.
 +	* implement.h: Rename rw_mutex to rw_lock.
 +	* mutex.c (pthread_mutex_destroy): Add serialisation.
 +	(_mutex_check_need_init): Check for detroyed mutex.
 +	* condvar.c (pthread_cond_destroy): Add serialisation.
 +	(_cond_check_need_init): Check for detroyed condvar.
 +	* mutex.c: Modify comments.
 +	* condvar.c: Modify comments.
 +
 +Sat Sep 10 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	The following code for POSIX read/write locks was contributed
 +	by Aurelio Medina.
 +
 +	* implement.h (pthread_rwlock_t_): Add.
 +	* pthread.h (pthread_rwlock_t): Add.
 +	(PTHREAD_RWLOCK_INITIALIZER): Add.
 +	Add rwlock function prototypes.
 +	* rwlock.c: New module.
 +	* pthread.def: Add new rwlock functions.
 +	* private.c (ptw32_processInitialize): initialise
 +	ptw32_rwlock_test_init_lock critical section.
 +	* global.c (ptw32_rwlock_test_init_lock): Add.
 +
 +	* mutex.c (pthread_mutex_destroy): Don't free mutex memory
 +	if mutex is PTHREAD_MUTEX_INITIALIZER and has not been
 +	initialised yet.
 +
 +Wed Sep  8 12:56:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* mutex.c (pthread_mutex_destroy): Free mutex memory.
 +	- Milan Gardian <mg@tatramed.sk>
 +
 +1999-08-22  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* exit.c (pthread_exit): Fix reference to potentially
 +	uninitialised pointer.
 +
 +1999-08-21  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_threadStart): Apply fix of 1999-08-19
 +	this time to C++ and non-trapped C versions. Ommitted to
 +	do this the first time through.
 +
 +1999-08-19  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_threadStart): Return exit status from
 +	the application thread startup routine.
 +	- Milan Gardian <mg@tatramed.sk>
 +
 +1999-08-18  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* exit.c (pthread_exit): Put status into pthread_t->exitStatus
 +	- John Bossom <john.Bossom@cognos.com>
 +	* private.c (ptw32_threadStart): Set pthread->exitStatus
 +	on exit of try{} block.
 +	- John Bossom <john.Bossom@cognos.com>
 +	* sync.c (pthread_join): use pthread_exitStatus value if the
 +	thread exit doesn't return a value (for Mingw32 CRTDLL
 +	which uses endthread instead of _endthreadex).
 +	- John Bossom <john.Bossom@cognos.com>
 +
 +Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan@xraylith.wisc.edu>
 +
 +        * create.c (pthread_create): Add CRTDLL suppport.
 +        * exit.c (pthread_exit): Likewise.
 +        * private.c (ptw32_threadStart): Likewise.
 +        (ptw32_threadDestroy): Likewise.
 +        * sync.c (pthread_join): Likewise.
 +        * tests/join1.c (main): Warn about partial support for CRTDLL.
 +
 +Tue Aug 17 20:00:08 1999  Mumit Khan  <khan@xraylith.wisc.edu>
 +
 +        * Makefile.in (LD): Delete entry point.
 +        * acconfig.h (STDCALL): Delete unused macro.
 +        * configure.in: Remove test for STDCALL.
 +        * config.h.in: Regenerate.
 +        * errno.c (_errno): Fix self type.
 +        * pthread.h (PT_STDCALL): Move from here to
 +        * implement.h (PT_STDCALL): here.
 +        (ptw32_threadStart): Fix prototype.
 +        * private.c (ptw32_threadStart): Likewise.
 +
 +1999-08-14  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* exit.c (pthread_exit): Don't call pthread_self() but
 +	get thread handle directly from TSD for efficiency.
 +	
 +1999-08-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_threadStart): ei[] only declared if _MSC_VER.
 +
 +	* exit.c (pthread_exit): Check for implicitly created threads
 +	to avoid raising an unhandled exception.
 +	
 +1999-07-12  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_destroy): Add critical section.
 +	(cond_timedwait): Add critical section; check for timeout
 +	waiting on semaphore.
 +	(pthread_cond_broadcast): Add critical section.
 +	- Peter Slacik <Peter.Slacik@tatramed.sk>
 +
 +1999-07-09  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	The following changes fix a bug identified by
 +	Lorin Hochstein <lmh@xiphos.ca> and solved by
 +	John Bossom <John.Bossom@Cognos.COM>.
 +
 +	The problem was that cleanup handlers were not executed when
 +	pthread_exit() was called.
 +
 +	* implement.h (pthread_t_): Add exceptionInformation element for
 +	C++ per-thread exception information.
 +	(general): Define and rename exceptions.
 +
 +
 +	* misc.c (CancelableWait):  PTW32_EPS_CANCEL (SEH) and
 +	ptw32_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. 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().
 +
 +Sun May 30 00:25:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* semaphore.h (mode_t): Conditionally typedef it.
 +
 +Fri May 28 13:33:05 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_broadcast): Fix possible memory fault
 +	- Mark E. Armstrong <avail@pacbell.net>
 +	
 +Thu May 27 13:08:46 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_broadcast): Fix logic bug
 +	- Peter Slacik <Peter.Slacik@tatramed.sk>;
 +	optimise sem_post loop
 +	- Bossom, John <John.Bossom@Cognos.COM>.
 +
 +Fri May 14 12:13:18 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* attr.c (pthread_attr_setdetachstate): Fix logic bug
 +	- Mike Russo <miker@eai.com>.
 +
 +Sat May  8 09:42:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.def (sem_open): Add.
 +	(sem_close): Add.
 +	(sem_unlink): Add.
 +	(sem_getvalue): Add.
 +
 +	* FAQ (Question 3): Add.
 +
 +Thu Apr  8 01:16:23 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* semaphore.c (sem_open): New function; returns an error (ENOSYS).
 +	(sem_close): ditto.
 +	(sem_unlink): ditto.
 +	(sem_getvalue): ditto.
 +
 +	* semaphore.h (_POSIX_SEMAPHORES): define.
 +	
 +Wed Apr  7 14:09:52 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* errno.c (_REENTRANT || _MT): Invert condition.
 +
 +	* pthread.h (_errno): Conditionally include prototype.
 +
 +Wed Apr  7 09:37:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* *.c (comments): Remove individual attributions - these are
 +	documented sufficiently elsewhere.
 +
 +	* implement.h (pthread.h): Remove extraneous include.
 +
 +Sun Apr  4 11:05:57 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* sched.c (sched.h): Include.
 +
 +	* sched.h: New file for POSIX 1b scheduling.
 +
 +	* pthread.h: Move opaque structures to implement.h; move sched_*
 +	prototypes out and into sched.h.
 +
 +	* implement.h: Add opaque structures from pthread.h.
 +
 +	* sched.c (sched_yield): New function.
 +
 +	* condvar.c (ptw32_sem_*): Rename to sem_*; except for
 +	ptw32_sem_timedwait which is an private function.
 +
 +Sat Apr  3 23:28:00 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* Makefile.in (OBJS): Add errno.o.
 +
 +Fri Apr  2 11:08:50 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h (ptw32_sem_*): Remove prototypes now defined in
 +	semaphore.h.
 +
 +	* pthread.h (sempahore.h): Include.
 +
 +	* semaphore.h: New file for POSIX 1b semaphores.
 +
 +	* pthread.h (ptw32_sem_t): Change to sem_t. 
 +
 +	* semaphore.c (ptw32_sem_*): Change to sem_*; these functions
 +	will be exported from the library; set errno on error.
 +	- John Bossom <jebossom@cognos.com>
 +	(ptw32_sem_timedwait): Moved to private.c.
 +
 +	* private.c (ptw32_sem_timedwait): Moved from semaphore.c;
 +	set errno on error.
 +
 +	* errno.c (_errno): New file. New function.
 +	- John Bossom
 +
 +	* pthread.h (pthread_t_): Add per-thread errno element.
 +
 +Fri Mar 26 14:11:45 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* semaphore.c (ptw32_sem_timedwait): Check for negative
 +	milliseconds.
 +	- Tor Lillqvist <tml@iki.fi>
 +
 +Wed Mar 24 11:32:07 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* misc.c (CancelableWait): Initialise exceptionInformation[2].
 +	(pthread_self): Get a real Win32 thread handle for implicit threads.
 +	- John Bossom <jebossom@cognos.com>
 +
 +	* cancel.c (pthread_testcancel): Initialise exceptionInformation[2].
 +	- John Bossom <jebossom@cognos.com>
 +
 +	* implement.h (SE_INFORMATION): Fix values.
 +	- John Bossom <jebossom@cognos.com>
 +
 +	* private.c (ptw32_threadDestroy): Close the thread handle.
 +	- John Bossom <jebossom@cognos.com>
 +
 +Fri Mar 19 12:57:27 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cancel.c (comments): Update and cleanup.
 +
 +Fri Mar 19 09:12:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_threadStart): status returns PTHREAD_CANCELED.
 +
 +	* pthread.h (PTHREAD_CANCELED): defined.
 +
 +Tue Mar 16  1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* all: Add GNU LGPL and Copyright and Warranty.
 +	
 +Mon Mar 15 00:20:13 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_init): fix possible uninitialised use
 +	of cv.
 +
 +Sun Mar 14 21:01:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_destroy): don't do full cleanup if
 +	static initialised cv has never been used.
 +	(cond_timedwait): check result of auto-initialisation.
 +
 +Thu Mar 11 09:01:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (pthread_mutex_t): revert to (pthread_mutex_t *);
 +	define a value to serve as PTHREAD_MUTEX_INITIALIZER.
 +	(pthread_mutex_t_): remove staticinit and valid elements.
 +	(pthread_cond_t): revert to (pthread_cond_t_ *);
 +	define a value to serve as PTHREAD_COND_INITIALIZER.
 +	(pthread_cond_t_): remove staticinit and valid elements.
 +
 +	* mutex.c (pthread_mutex_t args): adjust indirection of references.
 +	(all functions): check for PTHREAD_MUTEX_INITIALIZER value;
 +	check for NULL (invalid).
 +
 +	* condvar.c (pthread_cond_t args): adjust indirection of references.
 +	(all functions): check for PTHREAD_COND_INITIALIZER value;
 +	check for NULL (invalid).
 +
 +Wed Mar 10 17:18:12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* misc.c (CancelableWait): Undo changes from Mar 8 and 7.
 +
 +Mon Mar  8 11:18:59 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* misc.c (CancelableWait): Ensure cancelEvent handle is the lowest
 +	indexed element in the handles array. Enhance test for abandoned
 +	objects.
 +
 +	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Trailing elements not
 +	initialised are set to zero by the compiler. This avoids the
 +	problem of initialising the opaque critical section element in it.
 +	(PTHREAD_COND_INITIALIZER): Ditto.
 +
 +	* semaphore.c (ptw32_sem_timedwait): Check sem == NULL earlier.
 +
 +Sun Mar  7 12:31:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_init): set semaphore initial value
 +	to 0, not 1. cond_timedwait was returning signaled immediately.
 +
 +	* misc.c (CancelableWait): Place the cancel event handle first
 +	in the handle table for WaitForMultipleObjects. This ensures that
 +	the cancel event is recognised and acted apon if both objects
 +	happen to be signaled together.
 +
 +	* private.c (ptw32_cond_test_init_lock): Initialise and destroy.
 +
 +	* implement.h (ptw32_cond_test_init_lock): Add extern.
 +
 +	* global.c (ptw32_cond_test_init_lock): Add declaration. 
 +
 +	* condvar.c (pthread_cond_destroy): check for valid initialised CV;
 +	flag destroyed CVs as invalid.
 +	(pthread_cond_init): pthread_cond_t is no longer just a pointer.
 +	This is because PTHREAD_COND_INITIALIZER needs state info to reside
 +	in pthread_cond_t so that it can initialise on first use. Will work on
 +	making pthread_cond_t (and other objects like it) opaque again, if
 +	possible, later.
 +	(cond_timedwait): add check for statically initialisation of
 +	CV; initialise on first use.
 +	(pthread_cond_signal): check for valid CV.
 +	(pthread_cond_broadcast): check for valid CV.
 +	(_cond_check_need_init): Add.
 +
 +	* pthread.h (PTHREAD_COND_INITIALIZER): Fix.
 +	(pthread_cond_t): no longer a pointer to pthread_cond_t_.
 +	(pthread_cond_t_): add 'staticinit' and 'valid' elements.
 +
 +Sat Mar 6 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h: Undate comments.
 +
 +Sun Feb 21 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (PTHREAD_MUTEX_INITIALIZER): missing braces around
 +	cs element initialiser.
 +
 +1999-02-21  Ben Elliston  <bje@cygnus.com>
 +
 +	* pthread.h (pthread_exit): The return type of this function is
 +	void, not int.
 +
 +	* exit.c (pthread_exit): Do not return 0.
 +
 +Sat Feb 20 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* dll.c (DLLMain): Expand TryEnterCriticalSection support test.
 +
 +	* mutex.c (pthread_mutex_trylock): The check for
 +	ptw32_try_enter_critical_section == NULL should have been
 +	removed long ago.
 +
 +Fri Feb 19 16:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* sync.c (pthread_join): Fix pthread_equal() test.
 +
 +	* mutex.c (pthread_mutex_trylock): Check mutex != NULL before
 +	using it.
 +
 +Thu Feb 18 16:17:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* misc.c (pthread_equal): Fix inverted result.
 +
 +	* Makefile.in: Use libpthread32.a as the name of the DLL export
 +	library instead of pthread.lib.
 +
 +	* condvar.c (pthread_cond_init): cv could have been used unitialised;
 +	initialise.
 +
 +	* create.c (pthread_create): parms could have been used unitialised;
 +	initialise.
 +
 +	* pthread.h (struct pthread_once_t_): Remove redefinition.
 +
 +Sat Feb 13 03:03:30 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (struct pthread_once_t_): Replaced.
 +
 +	* misc.c (pthread_once): Replace with John Bossom's version;
 +	has lighter weight serialisation; fixes problem of not holding
 +	competing threads until after the init_routine completes.
 +
 +Thu Feb 11 13:34:14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* misc.c (CancelableWait): Change C++ exception throw.
 +
 +	* sync.c (pthread_join): Change FIXME comment - issue resolved.
 +
 +Wed Feb 10 12:49:11 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* configure: Various temporary changes.
 +	- Kevin Ruland <Kevin.Ruland@anheuser-busch.com>
 +
 +	* README: Update.
 +
 +	* pthread.def (pthread_attr_getstackaddr): uncomment
 +	(pthread_attr_setstackaddr): uncomment
 +
 +Fri Feb  5 13:42:30 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* semaphore.c: Comment format changes.
 +
 +Thu Feb  4 10:07:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* global.c: Remove ptw32_exception instantiation.
 +
 +	* cancel.c (pthread_testcancel): Change C++ exception throw.
 +
 +	* implement.h: Remove extern declaration.
 +
 +Wed Feb  3 13:04:44 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cleanup.c: Rename ptw32_*_cleanup() to pthread_*_cleanup().
 +
 +	* pthread.def: Ditto.
 +	
 +	* pthread.h: Ditto.
 +
 +	* pthread.def (pthread_cleanup_push): Remove from export list;
 +	the function is defined as a macro under all compilers.
 +	(pthread_cleanup_pop): Ditto.
 +
 +	* pthread.h: Remove #if defined().
 +
 +Wed Feb  3 10:13:48 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* sync.c (pthread_join): Check for NULL value_ptr arg;
 +	check for detached threads.
 +
 +Tue Feb  2 18:07:43 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* implement.h: Add #include <pthread.h>.
 +	Change sem_t to ptw32_sem_t.
 +
 +	Various patches by Kevin Ruland <Kevin.Ruland@anheuser-busch.com>
 +
 +	* signal.c (pthread_sigmask): Add and modify casts.
 +	Reverse LHS/RHS bitwise assignments.
 +
 +	* pthread.h: Remove #include <semaphore.h>.
 +	(PTW32_ATTR_VALID): Add cast.
 +	(struct pthread_t_): Add sigmask element.
 +
 +	* dll.c: Add "extern C" for DLLMain.
 +	(DllMain): Add cast.
 +
 +	* create.c (pthread_create): Set sigmask in thread.
 +
 +	* condvar.c: Remove #include. Change sem_* to ptw32_sem_*.
 +
 +	* attr.c: Changed #include.
 +
 +	* Makefile.in: Additional targets and changes to build the library
 +	as a DLL.
 +
 +Fri Jan 29 11:56:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* Makefile.in (OBJS): Add semaphore.o to list.
 +
 +	* semaphore.c (ptw32_sem_timedwait): Move from private.c.
 +	Rename sem_* to ptw32_sem_*.
 +
 +	* pthread.h (pthread_cond_t): Change type of sem_t.
 +	_POSIX_SEMAPHORES no longer defined.
 +
 +	* semaphore.h: Contents moved to implement.h.
 +	Removed from source tree.
 +
 +	* implement.h: Add semaphore function prototypes and rename all
 +	functions to prepend 'ptw32_'. They are
 +	now private to the pthreads-win32 implementation.
 +
 +	* private.c: Change #warning.
 +	Move ptw32_sem_timedwait() to semaphore.c.
 +
 +	* cleanup.c: Change #warning.
 +
 +	* misc.c: Remove #include <errno.h>
 +
 +	* pthread.def: Cleanup CVS merge conflicts.
 +
 +	* global.c: Ditto.
 +
 +	* ChangeLog: Ditto.
 +
 +	* cleanup.c: Ditto.
 +
 +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 (ptw32_callUserDestroyRoutines): Redo conditional
 +	compilation.
 +
 +	* misc.c (CancelableWait): C++ version uses 'throw'.
 +
 +	* cancel.c (pthread_testcancel): Ditto.
 +
 +	* 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
 +	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.
 +
 +	* mutex.c (pthread_mutex_init): Conditionally create Win32 mutex
 +	- from John Bossom's implementation.
 +	(pthread_mutex_destroy): Conditionally close Win32 mutex
 +	- from John Bossom's implementation.
 +	(pthread_mutexattr_init): Replaced by John Bossom's version.
 +	(pthread_mutexattr_destroy): Ditto.
 +	(pthread_mutexattr_getpshared): New function from John Bossom's
 +	implementation.
 +	(pthread_mutexattr_setpshared): New function from John Bossom's
 +	implementation.
 +
 +Tue Jan 19 18:27:42 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* pthread.h (pthreadCancelableTimedWait): New prototype.
 +	(pthreadCancelableWait): Remove second argument.
 +
 +	* misc.c (CancelableWait): New static function is 
 +	pthreadCancelableWait() renamed.
 +	(pthreadCancelableWait): Now just calls CancelableWait() with
 +	INFINITE timeout.
 +	(pthreadCancelableTimedWait): Just calls CancelableWait()
 +	with passed in timeout.
 +
 +	* private.c (ptw32_sem_timedwait): 'abstime' arg really is
 +	absolute time. Calculate relative time to wait from current
 +	time before passing timeout to new routine 
 +	pthreadCancelableTimedWait().
 +	- Scott Lightner <scott@curriculum.com>
 +
 +Tue Jan 19 10:27:39 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (pthread_mutexattr_setforcecs_np): New prototype.
 +	
 +	* mutex.c (pthread_mutexattr_init): Init 'pshared' and 'forcecs'
 +	attributes to 0.
 +	(pthread_mutexattr_setforcecs_np): New function (not portable).
 +
 +	* pthread.h (pthread_mutex_t): 
 +	Add 'mutex' element. Set to NULL in PTHREAD_MUTEX_INITIALIZER.
 +	The pthread_mutex_*() routines will try to optimise performance
 +	by choosing either mutexes or critical sections as the basis
 +	for pthread mutexes for each indevidual mutex.
 +	(pthread_mutexattr_t_): Add 'forcecs' element.
 +	Some applications may choose to force use of critical sections
 +	if they know that:-
 +	     the mutex is PROCESS_PRIVATE and, 
 +	         either the OS supports TryEnterCriticalSection() or
 +	         pthread_mutex_trylock() will never be called on the mutex.
 +	This attribute will be setable via a non-portable routine.
 +
 +	Note: We don't yet support PROCESS_SHARED mutexes, so the
 +	implementation as it stands will default to Win32 mutexes only if
 +	the OS doesn't support TryEnterCriticalSection. On Win9x, and early
 +	versions of NT 'forcecs' will need to be set in order to get
 +	critical section based mutexes.
 +
 +Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Init new 'staticinit'
 +	value to '1' and existing 'valid' value to '1'.
 +
 +	* global.c (ptw32_mutex_test_init_lock): Add.
 +
 +	* implement.h (ptw32_mutex_test_init_lock.): Add extern.
 +
 +	* private.c (ptw32_processInitialize): Init critical section for
 +	global lock used by _mutex_check_need_init().
 +	(ptw32_processTerminate): Ditto (:s/Init/Destroy/).
 +
 +	* dll.c (dllMain): Move call to FreeLibrary() so that it is only
 +	called once when the process detaches.
 +
 +	* mutex.c (_mutex_check_need_init): New static function to test
 +	and init PTHREAD_MUTEX_INITIALIZER mutexes. Provides serialised
 +	access to the internal state of the uninitialised static mutex. 
 +	Called from pthread_mutex_trylock() and pthread_mutex_lock() which
 +	do a quick unguarded test to check if _mutex_check_need_init()
 +	needs to be called. This is safe as the test is conservative
 + 	and is repeated inside the guarded section of 
 +	_mutex_check_need_init(). Thus in all calls except the first
 +	calls to lock static mutexes, the additional overhead to lock any
 +	mutex is a single memory fetch and test for zero.
 +
 +	* pthread.h (pthread_mutex_t_): Add 'staticinit' member. Mutexes
 +	initialised by PTHREAD_MUTEX_INITIALIZER aren't really initialised
 +	until the first attempt to lock it. Using the 'valid'
 +	flag (which flags the mutex as destroyed or not) to record this
 +	information would be messy. It is possible for a statically
 +	initialised mutex such as this to be destroyed before ever being
 +	used.
 +
 +	* mutex.c (pthread_mutex_trylock): Call _mutex_check_need_init()
 +	to test/init PTHREAD_MUTEX_INITIALIZER mutexes.
 +	(pthread_mutex_lock): Ditto.
 +	(pthread_mutex_unlock): Add check to ensure we don't try to unlock
 +	an unitialised static mutex.
 +	(pthread_mutex_destroy): Add check to ensure we don't try to delete
 +	a critical section that we never created. Allows us to destroy
 +	a static mutex that has never been locked (and hence initialised).
 +	(pthread_mutex_init): Set 'staticinit' flag to 0 for the new mutex.
 +
 +Sun Jan 17 12:01:26 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_sem_timedwait): Move from semaphore.c.
 +
 +	* semaphore.c : Remove redundant #includes.
 +	(ptw32_sem_timedwait): Move to private.c.
 +	(sem_wait): Add missing abstime arg to pthreadCancelableWait() call.
 +
 +Fri Jan 15 23:38:05 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (cond_timedwait): Remove comment.
 +
 +Fri Jan 15 15:41:28 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* pthread.h: Add new 'abstime' arg to pthreadCancelableWait()
 +	prototype.
 +
 +	* condvar.c (cond_timedwait): New generalised function called by
 +	both pthread_cond_wait() and pthread_cond_timedwait(). This is
 +	essentially pthread_cond_wait() renamed and modified to add the
 +	'abstime' arg and call the new ptw32_sem_timedwait() instead of
 +	sem_wait().
 +	(pthread_cond_wait): Now just calls the internal static
 +	function cond_timedwait() with an INFINITE wait.
 +	(pthread_cond_timedwait): Now implemented. Calls the internal
 +	static function cond_timedwait().
 +
 +	* implement.h (ptw32_sem_timedwait): New internal function
 +	prototype.
 +
 +	* misc.c (pthreadCancelableWait): Added new 'abstime' argument
 +	to allow shorter than INFINITE wait.
 +
 +	* semaphore.c (ptw32_sem_timedwait): New function for internal
 +	use.  This is essentially sem_wait() modified to add the
 +        'abstime' arg and call the modified (see above)
 +        pthreadCancelableWait().
 +
 +Thu Jan 14 14:27:13 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cleanup.c: Correct _cplusplus to __cplusplus wherever used.
 +
 +	* Makefile.in: Add CC=g++ and add -fhandle-exceptions to CFLAGS.
 +	The derived Makefile will compile all units of the package as C++
 +	so that those which include try/catch exception handling should work
 +	properly. The package should compile ok if CC=gcc, however, exception
 +	handling will not be included and thus thread cancellation, for
 + 	example, will not work.
 +
 +	* cleanup.c (ptw32_pop_cleanup): Add #warning to compile this
 + 	file as C++ if using a cygwin32 environment. Perhaps the whole package
 +	should be compiled using g++ under cygwin.
 +
 +	* private.c (ptw32_threadStart): Change #error directive
 +	into #warning and bracket for __CYGWIN__ and derivative compilers.
 +
 +Wed Jan 13 09:34:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* build.bat: Delete old binaries before compiling/linking.
 +
 +Tue Jan 12 09:58:38 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* dll.c: The Microsoft compiler pragmas probably are more
 +	appropriately protected by _MSC_VER than by _WIN32.
 +	- Tor Lillqvist <tml@iki.fi>.
 +
 +	* condvar.c (pthread_cond_timedwait): Fix function description
 +	comments.
 +
 +	* pthread.h: Define ETIMEDOUT. This should be returned by
 +	pthread_cond_timedwait which is not implemented yet as of
 +	snapshot-1999-01-04-1305. It was implemented in the older version.
 +	The Microsoft compiler pragmas probably are more appropriately
 +	protected by _MSC_VER than by _WIN32.
 +	- Tor Lillqvist <tml@iki.fi>.
 +
 +	* pthread.def: pthread_mutex_destroy was missing from the def file
 +	- Tor Lillqvist <tml@iki.fi>.
 +
 +	* condvar.c (pthread_cond_broadcast): Ensure we only wait on threads
 +	if there were any waiting on the condition.
 +	I think pthread_cond_broadcast should do the WaitForSingleObject
 +	only if cv->waiters > 0? Otherwise it seems to hang, at least in the
 +	testg thread program from glib.
 +	- Tor Lillqvist <tml@iki.fi>. 
 +
 +	* semaphore.c (sem_post): Correct typo in comment.
 +
 +Mon Jan 11 20:33:19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h: Re-arrange conditional compile of pthread_cleanup-*
 +	macros.
 +
 +	* cleanup.c (ptw32_push_cleanup): Provide conditional 
 +	compile of cleanup->prev.
 +
 +1999-01-11  Ben Elliston  <bje@cygnus.com>
 +
 +	* condvar.c (pthread_cond_init): Invert logic when testing the
 +	return value from calloc().
 +	- Tor Lillqvist <tml@iki.fi>.
 +
 +Sat Jan  9 14:32:08 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h: Compile-time switch for CYGWIN derived environments
 +	to use CreateThread instead of _beginthreadex. Ditto for ExitThread.
 +	Patch provided by Anders Norlander  <anorland@hem2.passagen.se>.
 +
 +Tue Jan  5 16:33:04 1999  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cleanup.c (ptw32_pop_cleanup): Add C++ version of __try/__except
 +	block. Move trailing "}" out of #ifdef _WIN32 block left there by
 +	(rpj's) mistake.
 +
 +	* private.c: Remove #include <errno.h> which is included by pthread.h.
 +
 +1998-12-11  Ben Elliston  <bje@toilet.to.cygnus.com>
 +
 +	* README: Update info about subscribing to the mailing list.
 +
 +Mon Jan  4 11:23:40 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* all: No code changes, just cleanup.
 +	- remove #if 0 /* Pre Bossom */ enclosed code.
 +	- Remove some redundant #includes.
 +	* pthread.h: Update implemented/unimplemented routines list.
 +	* Tag the bossom merge branch getting ready to merge back to main
 +	trunk.
 +
 +Tue Dec 29 13:11:16 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h: Move the following struct definitions to pthread.h:
 +	pthread_t_, pthread_attr_t_, pthread_mutex_t_, pthread_mutex_t_,
 +	pthread_mutexattr_t_, pthread_key_t_, pthread_cond_t_,
 +	pthread_condattr_t_, pthread_once_t_.
 +
 +	* pthread.h: Add "_" prefix to pthread_push_cleanup and 
 +	pthread_pop_cleanup internal routines, and associated struct and
 +	typedefs.
 +
 +	* buildlib.bat: Add compile command for semaphore.c
 +
 +	* pthread.def: Comment out pthread_atfork routine name. 
 +	Now unimplemented.
 +
 +	* tsd.c (pthread_setspecific): Rename tkAssocCreate to
 +	ptw32_tkAssocCreate.
 +	(pthread_key_delete): Rename tkAssocDestroy to
 +	ptw32_tkAssocDestroy.
 +
 +	* sync.c (pthread_join): Rename threadDestroy to ptw32_threadDestroy
 +
 +	* sched.c (is_attr): attr is now **attr (was *attr), so add extra
 +	NULL pointer test.
 +	(pthread_attr_setschedparam): Increase redirection for attr which is
 +	now a **.
 +	(pthread_attr_getschedparam): Ditto.
 +	(pthread_setschedparam): Change thread validation and rename "thread"
 + 	Win32 thread Handle element name to match John Bossom's version.
 +	(pthread_getschedparam): Ditto.
 +
 +	* private.c (ptw32_threadDestroy): Rename call to
 +	callUserDestroyRoutines() as ptw32_callUserDestroyRoutines()
 +
 +	* misc.c: Add #include "implement.h".
 +
 +	* dll.c: Remove defined(KLUDGE) wrapped code.
 +
 +	* fork.c: Remove redefinition of ENOMEM.
 +	Remove pthread_atfork() and fork() with #if 0/#endif.
 +
 +	* create.c (pthread_create): Rename threadStart and threadDestroy calls
 +	to ptw32_threadStart and ptw32_threadDestroy.
 +
 +	* implement.h: Rename "detachedstate" to "detachstate".
 +
 +	* attr.c: Rename "detachedstate" to "detachstate".
 +
 +Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* semaphore.c: Initial version. From John Bossom's implementation.
 +	* semaphore.h: Initial version. From John Bossom's implementation.
 +
 +Mon Dec 28 09:54:39 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.h (pthread_attr_t_): Change to *pthread_attr_t.
 +
 +	* attr.c (pthread_attr_setstacksize): Merge with John Bossom's version.
 +	(pthread_attr_getstacksize): Merge with John Bossom's version.
 +	(pthread_attr_setstackaddr): Merge with John Bossom's version.
 +	(pthread_attr_getstackaddr): Merge with John Bossom's version.
 +	(pthread_attr_init): Merge with John Bossom's version.
 +	(pthread_attr_destroy): Merge with John Bossom's version.
 +	(pthread_attr_getdetachstate): Merge with John Bossom's version.
 +	(pthread_attr_setdetachstate): Merge with John Bossom's version.
 +	(is_attr): attr is now **attr (was *attr), so add extra NULL pointer
 +	test.
 +
 +	* implement.h (pthread_attr_t_): Add and rename elements in JEB's
 +	version to correspond to original, so that it can be used with
 +	original attr routines.
 +
 +	* pthread.h: Add #endif at end which was truncated in merging.
 +
 +Sun Dec 20 14:51:58 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* misc.c (pthreadCancelableWait): New function by John Bossom. Non-standard
 +	but provides a hook that can be used to implement cancellation points in
 +	applications that use this library.
 +
 +	* pthread.h (pthread_cleanup_pop): C++ (non-WIN32) version uses
 +	try/catch to emulate John Bossom's WIN32 __try/__finally behaviour.
 +	In the WIN32 version __finally block, add a test for AbnormalTermination otherwise
 +	cleanup is only run if the cleanup_pop execute arg is non-zero. Cancellation
 +	should cause the cleanup to run irrespective of the execute arg.
 +
 +	* condvar.c (pthread_condattr_init): Replaced by John Bossom's version.
 +	(pthread_condattr_destroy): Replaced by John Bossom's version.
 +	(pthread_condattr_getpshared): Replaced by John Bossom's version.
 +	(pthread_condattr_setpshared): Replaced by John Bossom's version.
 +	(pthread_cond_init): Replaced by John Bossom's version.
 +	Fix comment (refered to mutex rather than condition variable).
 +	(pthread_cond_destroy): Replaced by John Bossom's version.
 +	(pthread_cond_wait): Replaced by John Bossom's version.
 +	(pthread_cond_timedwait): Replaced by John Bossom's version.
 +	(pthread_cond_signal): Replaced by John Bossom's version.
 +	(pthread_cond_broadcast): Replaced by John Bossom's version.
 +
 +Thu Dec 17 19:10:46 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tsd.c (pthread_key_create): Replaced by John Bossom's version.
 +	(pthread_key_delete): Replaced by John Bossom's version.
 +	(pthread_setspecific): Replaced by John Bossom's version.
 +	(pthread_getspecific): Replaced by John Bossom's version.
 +
 +Mon Dec  7 09:44:40 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* cancel.c (pthread_setcancelstate): Replaced by John Bossom's version.
 +	(pthread_setcanceltype): Replaced by John Bossom's version.
 +	(pthread_testcancel): Replaced by John Bossom's version.
 +	(pthread_cancel): Replaced by John Bossom's version.
 +	
 +	* exit.c (pthread_exit): Replaced by John Bossom's version.
 +
 +	* misc.c (pthread_self): Replaced by John Bossom's version.
 +	(pthread_equal): Replaced by John Bossom's version.
 +
 +	* sync.c (pthread_detach): Replaced by John Bossom's version.
 +	(pthread_join): Replaced by John Bossom's version.
 +
 +	* create.c (pthread_create): Replaced by John Bossom's version.
 +
 +	* private.c (ptw32_processInitialize): New by John Bossom.
 +	(ptw32_processTerminate): Non-public function by John Bossom.
 +	(ptw32_threadStart): Non-public function by John Bossom.
 + 	(ptw32_threadDestroy): Non-public function by John Bossom.
 +	(ptw32_cleanupStack): Non-public function by John Bossom.
 +	(ptw32_tkAssocCreate): Non-public function by John Bossom.
 +	(ptw32_tkAssocDestroy): Non-public function by John Bossom.
 +	(ptw32_callUserDestroyRoutines): Non-public function by John Bossom.
 +
 +	* implement.h: Added John Bossom's non-API structures and
 +	declarations.
 +
 +	* dll.c (PthreadsEntryPoint): Cast return value of GetProcAddress
 +	to resolve compile warning from MSVC.
 +
 +	* dll.c (DLLmain): Replaced by John Bossom's version.
 +	* dll.c (PthreadsEntryPoint):
 +	Re-applied Anders Norlander's patch:-
 +	Initialize ptw32_try_enter_critical_section at startup
 +	and release kernel32 handle when DLL is being unloaded.
 +
 +Sun Dec  6 21:54:35 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* buildlib.bat: Fix args to CL when building the .DLL
 +
 +	* cleanup.c (ptw32_destructor_run_all): Fix TSD key management.
 +	This is a tidy-up before TSD and Thread management is completely
 +	replaced by John Bossom's code.
 +
 +	* tsd.c (pthread_key_create): Fix TSD key management.
 +
 +	* global.c (ptw32_key_virgin_next): Initialise.
 +
 +	* build.bat: New DOS script to compile and link a pthreads app
 +	using Microsoft's CL compiler linker.
 +	* buildlib.bat: New DOS script to compile all the object files
 +	and create pthread.lib and pthread.dll using Microsoft's CL
 +	compiler linker.
 +
 +1998-12-05  Anders Norlander  <anorland@hem2.passagen.se>
 +
 +	* implement.h (ptw32_try_enter_critical_section): New extern
 +	* dll.c (ptw32_try_enter_critical_section): New pointer to
 +	TryEnterCriticalSection if it exists; otherwise NULL.
 +	* dll.c (PthreadsEntryPoint):
 +	Initialize ptw32_try_enter_critical_section at startup
 +	and release kernel32 handle when DLL is being unloaded.
 +	* mutex.c (pthread_mutex_trylock): Replaced check for NT with
 +	a check if ptw32_try_enter_critical_section is valid
 +	pointer to a function. Call ptw32_try_enter_critical_section
 +	instead of TryEnterCriticalSection to avoid errors on Win95.
 +
 +Thu Dec 3 13:32:00 1998  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +	* README: Correct cygwin32 compatibility statement.
 +
 +Sun Nov 15 21:24:06 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* cleanup.c (ptw32_destructor_run_all): Declare missing void * arg.
 +	Fixup CVS merge conflicts.
 +
 +1998-10-30  Ben Elliston  <bje@cygnus.com>
 +
 +	* condvar.c (cond_wait): Fix semantic error. Test for equality
 +	instead of making an assignment.
 +
 +Fri Oct 30 15:15:50 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cleanup.c (ptw32_handler_push): Fixed bug appending new
 +	handler to list reported by Peter Slacik
 +	<Peter.Slacik@leibinger.freinet.de>.
 +	(new_thread): Rename poorly named local variable to
 +	"new_handler".
 +
 +Sat Oct 24 18:34:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* global.c: Add TSD key management array and index declarations.
 +
 +	* implement.h: Ditto for externs.
 +
 +Fri Oct 23 00:08:09 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* 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.
 +
 +	* cleanup.c (ptw32_destructor_run_all): Check for no more dirty
 +	keys to run destructors on. Assume that the destructor call always
 +	succeeds and set the key value to NULL.
 +
 +Thu Oct 22 21:44:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tsd.c (pthread_setspecific): Add key management code.
 +	(pthread_key_create): Ditto.
 +	(pthread_key_delete): Ditto.
 +
 +	* implement.h (struct ptw32_tsd_key): Add status member.
 +
 +	* tsd.c: Add description of pthread_key_delete() from the
 +	standard as a comment.
 +
 +Fri Oct 16 17:38:47 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cleanup.c (ptw32_destructor_run_all): Fix and improve
 +	stepping through the key table.
 +
 +Thu Oct 15 14:05:01 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* private.c (ptw32_new_thread): Remove init of destructorstack.
 +	No longer an element of pthread_t.
 +
 +	* tsd.c (pthread_setspecific): Fix type declaration and cast.
 +	(pthread_getspecific): Ditto.
 +	(pthread_getspecific): Change error return value to NULL if key
 +	is not in use.
 +
 +Thu Oct 15 11:53:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* global.c (ptw32_tsd_key_table): Fix declaration.
 +
 +	* implement.h(ptw32_TSD_keys_TlsIndex): Add missing extern.
 +	(ptw32_tsd_mutex): Ditto.
 +
 +	* create.c (ptw32_start_call): Fix "keys" array declaration.
 +	Add comment.
 +
 +	* tsd.c (pthread_setspecific): Fix type declaration and cast.
 +	(pthread_getspecific): Ditto.
 +
 +	* cleanup.c (ptw32_destructor_run_all): Declare missing loop
 +	counter.
 +
 +Wed Oct 14 21:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_new_thread): Increment ptw32_threads_count.
 +	(ptw32_delete_thread): Decrement ptw32_threads_count.
 +	Remove some comments.
 +
 +	* exit.c (ptw32_exit): : Fix two pthread_mutex_lock() calls that
 + 	should have been pthread_mutex_unlock() calls.
 +	(ptw32_vacuum): Remove call to ptw32_destructor_pop_all().
 +
 +	* create.c (pthread_create): Fix two pthread_mutex_lock() calls that
 + 	should have been pthread_mutex_unlock() calls.
 +
 +	* global.c (ptw32_tsd_mutex): Add mutex for TSD operations.
 +
 +	* tsd.c (pthread_key_create): Add critical section.
 +	(pthread_setspecific): Ditto.
 +	(pthread_getspecific): Ditto.
 +	(pthread_key_delete): Ditto.
 +
 +	* sync.c (pthread_join): Fix two pthread_mutex_lock() calls that
 + 	should have been pthread_mutex_unlock() calls.
 +
 +Mon Oct 12 00:00:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h (ptw32_tsd_key_table): New.
 +
 +	* create.c (ptw32_start_call): Initialise per-thread TSD keys
 +	to NULL.
 +
 +	* misc.c (pthread_once): Correct typo in comment.
 +
 +	* implement.h (ptw32_destructor_push): Remove.
 +	(ptw32_destructor_pop): Remove.
 +	(ptw32_destructor_run_all): Rename from ptw32_destructor_pop_all.
 +	(PTW32_TSD_KEY_DELETED): Add enum.
 +	(PTW32_TSD_KEY_INUSE): Add enum.
 +
 +	* cleanup.c (ptw32_destructor_push): Remove.
 +	(ptw32_destructor_pop): Remove.
 +	(ptw32_destructor_run_all): Totally revamped TSD.
 +
 +	* dll.c (ptw32_TSD_keys_TlsIndex): Initialise.
 +
 +	* tsd.c (pthread_setspecific): Totally revamped TSD.
 +	(pthread_getspecific): Ditto.
 +	(pthread_create): Ditto.
 +	(pthread_delete): Ditto.
 +
 +Sun Oct 11 22:44:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* global.c (ptw32_tsd_key_table): Add new global.
 +
 +	* implement.h (ptw32_tsd_key_t and struct ptw32_tsd_key):
 +	Add.
 +	(struct _pthread): Remove destructorstack.
 +
 +	* cleanup.c (ptw32_destructor_run_all): Rename from
 + 	ptw32_destructor_pop_all. The key destructor stack was made
 + 	global rather than per-thread. No longer removes destructor nodes
 +	from the stack. Comments updated.
 +
 +1998-10-06  Ben Elliston  <bje@cygnus.com>
 +
 +	* condvar.c (cond_wait): Use POSIX, not Win32 mutex calls.
 +	(pthread_cond_broadcast): Likewise.
 +	(pthread_cond_signal): Likewise.
 +
 +1998-10-05  Ben Elliston  <bje@cygnus.com>
 +
 +	* pthread.def: Update. Some functions aren't available yet, others
 +	are macros in <pthread.h>.
 +
 +	* tests/join.c: Remove; useless.
 +
 +Mon Oct  5 14:25:08 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* pthread.def: New file for building the DLL.
 +
 +1998-10-05  Ben Elliston  <bje@cygnus.com>
 +
 +	* misc.c (pthread_equal): Correct inverted logic bug.
 +	(pthread_once): Use the POSIX mutex primitives, not Win32. Remove
 +	irrelevant FIXME comment.
 +
 +	* global.c (PTHREAD_MUTEX_INITIALIZER): Move to pthread.h.
 +
 +	* pthread.h (PTHREAD_MUTEX_INITIALIZER): Define.
 +	(pthread_mutex_t): Reimplement as a struct containing a valid
 +	flag. If the flag is ever down upon entry to a mutex operation,
 +	we call pthread_mutex_create() to initialise the object. This
 +	fixes the problem of how to handle statically initialised objects
 +	that can't call InitializeCriticalSection() due to their context.
 +	(PTHREAD_ONCE_INIT): Define.
 +
 +	* mutex.c (pthread_mutex_init): Set valid flag.
 +	(pthread_mutex_destroy): Clear valid flag.
 +	(pthread_mutex_lock): Check and handle the valid flag.
 +	(pthread_mutex_unlock): Likewise.
 +	(pthread_mutex_trylock): Likewise.
 +
 +	* tests/mutex3.c: New file; test for the static initialisation
 +	macro. Passes.
 +
 +	* tests/create1.c: New file; test pthread_create(). Passes.
 +	
 +	* tests/equal.c: Poor test; remove.
 +	
 +	* tests/equal1.c New file; test pthread_equal(). Passes.
 +
 +	* tests/once1.c: New file; test for pthread_once(). Passes.
 +
 +	* tests/self.c: Remove; rename to self1.c.
 +
 +	* tests/self1.c: This is the old self.c.
 +
 +	* tests/self2.c: New file. Test pthread_self() with a single
 +	thread. Passes.
 +
 +	* tests/self3.c: New file. Test pthread_self() with a couple of
 +	threads to ensure their thread IDs differ. Passes.
 +	
 +1998-10-04  Ben Elliston  <bje@cygnus.com>
 +
 +	* tests/mutex2.c: Test pthread_mutex_trylock(). Passes.
 +
 +	* tests/mutex1.c: New basic test for mutex functions (it passes).
 +	(main): Eliminate warning.
 +
 +	* configure.in: Test for __stdcall, not _stdcall. Typo.
 +
 +	* configure: Regenerate.
 +
 +	* attr.c (pthread_attr_setstackaddr): Remove FIXME comment. Win32
 +	does know about ENOSYS after all.
 +	(pthread_attr_setstackaddr): Likewise.
 +
 +1998-10-03  Ben Elliston  <bje@cygnus.com>
 +
 +	* configure.in: Test for the `_stdcall' keyword.  Define `STDCALL'
 +	to `_stdcall' if we have it, null otherwise.
 +
 +	* configure: Regenerate.
 +
 +	* acconfig.h (STDCALL): New define.
 +
 +	* config.h.in: Regenerate.
 +
 +	* create.c (ptw32_start_call): Add STDCALL prefix.
 +	
 +	* mutex.c (pthread_mutex_init): Correct function signature.
 +
 +	* attr.c (pthread_attr_init): Only zero out the `sigmask' member
 +	if we have the sigset_t type.
 +
 +	* pthread.h: No need to include <unistd.h>.  It doesn't even exist
 +	on Win32! Again, an artifact of cross-compilation.	
 +	(pthread_sigmask): Only provide if we have the sigset_t type.
 +
 +	* process.h: Remove. This was a stand-in before we started doing
 +	native compilation under Win32.
 +
 +	* pthread.h (pthread_mutex_init): Make `attr' argument const.
 +
 +1998-10-02  Ben Elliston  <bje@cygnus.com>
 +
 +	* COPYING: Remove.
 +
 +	* COPYING.LIB: Add. This library is under the LGPL.
 +
 +1998-09-13  Ben Elliston  <bje@cygnus.com>
 +
 +	* configure.in: Test for required system features.
 +
 +	* configure: Generate. 
 +
 +	* acconfig.h: New file.
 +
 +	* config.h.in: Generate.
 +
 +	* Makefile.in: Renamed from Makefile.
 +
 +	* COPYING: Import from a recent GNU package.
 +
 +	* config.guess: Likewise.
 +
 +	* config.sub: Likewise.
 +
 +	* install-sh: Likewise.
 +
 +	* config.h: Remove.  
 +
 +	* Makefile: Likewise.
 +
 +1998-09-12  Ben Elliston  <bje@cygnus.com>
 +
 +	* windows.h: No longer needed; remove.
 +
 +	* windows.c: Likewise.
 +
 +Sat Sep 12 20:09:24 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* windows.h: Remove error number definitions. These are in <errno.h>
 +	
 +	* tsd.c: Add comment explaining rationale for not building
 +	POSIX TSD on top of Win32 TLS.
 +
 +1998-09-12  Ben Elliston  <bje@cygnus.com>
 +
 +	* {most}.c: Include <errno.h> to get POSIX error values.
 +
 +	* signal.c (pthread_sigmask): Only provide if HAVE_SIGSET_T is
 +	defined.
 + 
 +	* config.h: #undef features, don't #define them.  This will be
 +	generated by autoconf very soon.
 +	
 +1998-08-11  Ben Elliston  <bje@cygnus.com>
 +
 +	* Makefile (LIB): Define.
 +	(clean): Define target.
 +	(all): Build a library not just the object files.
 +
 +	* pthread.h: Provide a definition for struct timespec if we don't
 +	already have one.
 +
 +	* windows.c (TlsGetValue): Bug fix.
 +	
 +Thu Aug  6 15:19:22 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* misc.c (pthread_once): Fix arg 1 of EnterCriticalSection()
 + 	and LeaveCriticalSection() calls to pass address-of lock.
 +
 +	* fork.c (pthread_atfork): Typecast (void (*)(void *)) funcptr
 +	in each ptw32_handler_push() call.
 +
 +	* exit.c (ptw32_exit): Fix attr arg in 
 +	pthread_attr_getdetachstate() call.
 +
 +	* private.c (ptw32_new_thread): Typecast (HANDLE) NULL.
 +	(ptw32_delete_thread): Ditto.
 +
 +	* implement.h: (PTW32_MAX_THREADS): Add define. This keeps
 +	changing in an attempt to make thread administration data types
 +	opaque and cleanup DLL startup.
 +
 +	* dll.c (PthreadsEntryPoint): 
 +	(ptw32_virgins): Remove malloc() and free() calls.
 +	(ptw32_reuse): Ditto.
 +	(ptw32_win32handle_map): Ditto.
 +	(ptw32_threads_mutex_table): Ditto.
 +
 +	* global.c (_POSIX_THREAD_THREADS_MAX): Initialise with 
 +	PTW32_MAX_THREADS.
 +	(ptw32_virgins): Ditto.
 +	(ptw32_reuse): Ditto.
 +	(ptw32_win32handle_map): Ditto.
 +	(ptw32_threads_mutex_table): Ditto.
 +
 +	* create.c (pthread_create): Typecast (HANDLE) NULL.
 +	Typecast (unsigned (*)(void *)) start_routine.
 +
 +	* condvar.c (pthread_cond_init): Add address-of operator & to
 +	arg 1 of pthread_mutex_init() call.
 +	(pthread_cond_destroy): Add address-of operator & to
 +	arg 1 of pthread_mutex_destroy() call. 
 +
 +	* cleanup.c (ptw32_destructor_pop_all): Add (int) cast to 
 +	pthread_getspecific() arg.
 +	(ptw32_destructor_pop): Add (void *) cast to "if" conditional.
 +	(ptw32_destructor_push): Add (void *) cast to
 +	ptw32_handler_push() "key" arg.
 +	(malloc.h): Add include.
 +
 +	* implement.h (ptw32_destructor_pop): Add prototype.
 +
 +	* tsd.c (implement.h): Add include.
 +
 +	* sync.c (pthread_join): Remove target_thread_mutex and it's
 +	initialisation. Rename getdetachedstate to getdetachstate.
 +	Remove unused variable "exitcode".
 +	(pthread_detach): Remove target_thread_mutex and it's
 +	initialisation. Rename getdetachedstate to getdetachstate.
 +	Rename setdetachedstate to setdetachstate.
 +
 +	* signal.c (pthread_sigmask): Rename SIG_SET to SIG_SETMASK.
 +	Cast "set" to (long *) in assignment to passify compiler warning.
 +	Add address-of operator & to thread->attr.sigmask in memcpy() call
 +	and assignment.
 +	(pthread_sigmask): Add address-of operator & to thread->attr.sigmask
 +	in memcpy() call and assignment.
 +
 +	* windows.h (THREAD_PRIORITY_ERROR_RETURN): Add.
 +	(THREAD_PRIORITY_LOWEST): Add.
 +	(THREAD_PRIORITY_HIGHEST): Add.
 +
 +	* sched.c (is_attr): Add function.
 +	(implement.h): Add include.
 +	(pthread_setschedparam): Rename all instances of "sched_policy"
 +	to "sched_priority".
 +	(pthread_getschedparam): Ditto.
 +
 +Tue Aug  4 16:57:58 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* private.c (ptw32_delete_thread): Fix typo. Add missing ';'.
 +
 +	* global.c (ptw32_virgins): Change types from pointer to 
 +	array pointer.
 +	(ptw32_reuse): Ditto.
 +	(ptw32_win32handle_map): Ditto.
 +	(ptw32_threads_mutex_table): Ditto.
 +
 +	* implement.h(ptw32_virgins): Change types from pointer to 
 +	array pointer.
 +	(ptw32_reuse): Ditto.
 +	(ptw32_win32handle_map): Ditto.
 +	(ptw32_threads_mutex_table): Ditto.
 +
 +	* private.c (ptw32_delete_thread): Fix "entry" should be "thread".
 +
 +	* misc.c (pthread_self): Add extern for ptw32_threadID_TlsIndex.
 +
 +	* global.c: Add comment.
 +
 +	* misc.c (pthread_once): Fix member -> dereferences.
 +	Change ptw32_once_flag to once_control->flag in "if" test.
 +
 +Tue Aug  4 00:09:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h(ptw32_virgins): Add extern.
 +	(ptw32_virgin_next): Ditto.
 +	(ptw32_reuse): Ditto.
 +	(ptw32_reuse_top): Ditto.
 +	(ptw32_win32handle_map): Ditto.
 +	(ptw32_threads_mutex_table): Ditto.
 +
 +	* global.c (ptw32_virgins): Changed from array to pointer.
 +	Storage allocation for the array moved into dll.c.
 +	(ptw32_reuse): Ditto.
 +	(ptw32_win32handle_map): Ditto.
 +	(ptw32_threads_mutex_table): Ditto.
 +
 +	* dll.c (PthreadsEntryPoint): Set up thread admin storage when
 +	DLL is loaded.
 +
 +	* fork.c (pthread_atfork): Fix function pointer arg to all
 +	ptw32_handler_push() calls. Change "arg" arg to NULL in child push.
 +
 +	* exit.c: Add windows.h and process.h includes.
 +	(ptw32_exit): Add local detachstate declaration.
 +	(ptw32_exit): Fix incorrect name for pthread_attr_getdetachstate().
 +
 +	* pthread.h (_POSIX_THREAD_ATTR_STACKSIZE): Move from global.c
 +	(_POSIX_THREAD_ATTR_STACKADDR): Ditto.
 +
 +	* create.c (pthread_create): Fix #if should be #ifdef.
 +	(ptw32_start_call): Remove usused variables.
 +
 +	* process.h: Create.
 +
 +	* windows.h: Move _beginthreadex and _endthreadex into
 +	process.h
 +
 +Mon Aug  3 21:19:57 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar.c (pthread_cond_init): Add NULL attr to
 +	pthread_mutex_init() call - default attributes will be used.
 +	(cond_wait): Fix typo.
 +	(cond_wait): Fix typo - cv was ev.
 +	(pthread_cond_broadcast): Fix two identical typos.
 +
 +	* cleanup.c (ptw32_destructor_pop_all): Remove _ prefix from
 +	PTHREAD_DESTRUCTOR_ITERATIONS.
 +
 +	* pthread.h: Move _POSIX_* values into posix.h
 +
 +	* pthread.h: Fix typo in pthread_mutex_init() prototype.
 +
 +	* attr.c (pthread_attr_init): Fix error in priority member init.
 +
 +	* windows.h (THREAD_PRIORITY_NORMAL): Add.
 +
 +	* pthread.h (sched_param): Add missing ';' to struct definition. 
 +
 +	* attr.c (pthread_attr_init): Remove obsolete pthread_attr_t
 +	member initialisation - cancelstate, canceltype, cancel_pending.
 +	(is_attr): Make arg "attr" a const.
 +
 +	* 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>
 +
 +	* windows.h: Remove duplicate TlsSetValue() prototype.  Add 
 +	TlsGetValue() prototype.
 +	(FALSE): Define.
 +	(TRUE): Likewise.
 +	Add forgotten errno values.  Guard against multiple #includes.
 +
 +	* windows.c: New file.  Implement stubs for Win32 functions.
 +
 +	* Makefile (SRCS): Remove.  Not explicitly needed.
 +	(CFLAGS): Add -Wall for all warnings with GCC.
 +
 +Sun Aug  2 19:03:42 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* config.h: Create. This is a temporary stand-in for autoconf yet
 +	to be done.
 + 	(HAVE_SIGNAL_H): Add.
 +
 +	* pthread.h: Minor rearrangement for temporary config.h.
 +
 +Fri Jul 31 14:00:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* cleanup.c (ptw32_destructor_pop): Implement. Removes
 +	destructors associated with a key without executing them.
 +	(ptw32_destructor_pop_all): Add FIXME comment.
 +
 +	* tsd.c (pthread_key_delete): Add call to ptw32_destructor_pop().
 +
 +Fri Jul 31 00:05:45 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tsd.c (pthread_key_create): Update to properly associate
 +	the destructor routine with the key.
 +	(pthread_key_delete): Add FIXME comment.
 +
 +	* exit.c (ptw32_vacuum): Add call to
 +	ptw32_destructor_pop_all().
 +
 +	* implement.h (ptw32_handler_pop_all): Add prototype.
 +	(ptw32_destructor_pop_all): Ditto.
 +
 +	* cleanup.c (ptw32_destructor_push): Implement. This is just a
 +	call to ptw32_handler_push().
 +	(ptw32_destructor_pop_all): Implement. This is significantly
 +	different to ptw32_handler_pop_all().
 +
 +	* Makefile (SRCS): Create. Preliminary.
 +
 +	* windows.h: Create. Contains Win32 definitions for compile
 +	testing. This is just a standin for the real one.
 +
 +	* pthread.h (SIG_UNBLOCK): Fix typo. Was SIG_BLOCK.
 +	(windows.h): Add include. Required for CRITICAL_SECTION.
 +	(pthread_cond_t): Move enum declaration outside of struct
 +	definition.
 +	(unistd.h): Add include - may be temporary.
 +
 +	* condvar.c (windows.h): Add include.
 +
 +	* 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>
 +
 +	* implement.h: Remove ptw32_find_entry() prototype.
 +
 +	* private.c: Extend comments.
 +	Remove ptw32_find_entry() - no longer needed.
 +
 +	* create.c (ptw32_start_call): Add call to TlsSetValue() to
 +	store the thread ID.
 +
 +	* dll.c (PthreadsEntryPoint): Implement. This is called
 +	whenever a process loads the DLL. Used to initialise thread
 +	local storage.
 +
 +	* implement.h: Add ptw32_threadID_TlsIndex.
 +	Add ()s around PTW32_VALID expression.
 +
 +	* misc.c (pthread_self): Re-implement using Win32 TLS to store
 +	the threads own ID.
 +
 +Wed Jul 29 11:39:03 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c: Corrections in comments.
 +	(ptw32_new_thread): Alter "if" flow to be more natural.
 +
 +	* cleanup.c (ptw32_handler_push): Same as below.
 +
 +	* create.c (pthread_create): Same as below.
 +
 +	* private.c (ptw32_new_thread): Rename "new" to "new_thread".
 +	Since when has a C programmer been required to know C++?
 +
 +Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* 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".
 +	Remove extra local variable "target".
 +	(pthread_detach): Ditto.
 +
 +	* signal.c (pthread_sigmask): Move init of "us" out of inner block.
 +	Fix instance of "this" should have been "us". Rename "us" to "thread".
 +
 +	* sched.c (pthread_setschedparam): Modify to use the new thread
 +	type.
 +	(pthread_getschedparam): Ditto.
 +
 +	* private.c (ptw32_find_thread): Fix return type and arg.
 +
 +	* 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.
 +	(  PTW32_NEW, PTW32_INUSE, PTW32_EXITED, PTW32_REUSE):
 +	Add.
 +
 +
 +	* create.c (pthread_create): Minor rename "us" to "new" (I need
 +	these cues but it doesn't stop me coming out with some major bugs
 +	at times).
 +	Load start_routine and arg into the thread so the wrapper can
 +	call it.
 +
 +	* exit.c (pthread_exit): Fix pthread_this should be pthread_self.
 +
 +	* cancel.c (pthread_setcancelstate): Change
 + 	ptw32_threads_thread_t * to pthread_t and init with
 + 	pthread_this().
 +	(pthread_setcanceltype): Ditto.
 +
 +	* exit.c (ptw32_exit): Add new pthread_t arg.
 +	Rename ptw32_delete_thread_entry to ptw32_delete_thread.
 +	Rename "us" to "thread".
 +	(pthread_exit): Call ptw32_exit with added thread arg.
 +
 +	* create.c (ptw32_start_call): Insert missing ")".
 +	Add "us" arg to ptw32_exit() call.
 +	(pthread_create): Modify to use new thread allocation scheme.
 +
 +	* private.c: Added detailed explanation of the new thread
 +	allocation scheme.
 +	(ptw32_new_thread): Totally rewritten to use
 +	new thread allocation scheme.
 +	(ptw32_delete_thread): Ditto.
 +	(ptw32_find_thread): Obsolete.
 +
 +Mon Jul 27 17:46:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* create.c (pthread_create): Start of rewrite. Not completed yet.
 +
 +	* private.c (ptw32_new_thread_entry): Start of rewrite. Not
 +	complete.
 +
 +	* implement.h (ptw32_threads_thread): Rename, remove thread
 +	member, add win32handle and ptstatus members.
 +	(ptw32_t): Add.
 +
 +	* pthread.h: pthread_t is no longer mapped directly to a Win32
 +	HANDLE type. This is so we can let the Win32 thread terminate and
 +	reuse the HANDLE while pthreads holds it's own thread ID until
 +	the last waiting join exits.
 +
 +Mon Jul 27 00:20:37 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_delete_thread_entry): Destroy the thread
 + 	entry attribute object before deleting the thread entry itself.
 +
 +	* attr.c (pthread_attr_init): Initialise cancel_pending = FALSE.
 +	(pthread_attr_setdetachstate): Rename "detached" to "detachedstate".
 +	(pthread_attr_getdetachstate): Ditto.
 +
 +	* exit.c (ptw32_exit): Fix incorrect check for detachedstate.
 +
 +	* implement.h (ptw32_call_t): Remove env member. 
 +
 +Sun Jul 26 13:06:12 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h (ptw32_new_thread_entry): Fix prototype.
 +	(ptw32_find_thread_entry): Ditto.
 +	(ptw32_delete_thread_entry): Ditto.
 +	(ptw32_exit): Add prototype.
 +
 +	* exit.c (ptw32_exit): New function. Called from pthread_exit()
 +	and ptw32_start_call() to exit the thread. It allows an extra
 +	argument which is the return code passed to _endthreadex().
 +	(ptw32_exit): Move thread entry delete call from ptw32_vacuum()
 +	into here. Add more explanation of thread entry deletion.
 +	(ptw32_exit): Clarify comment.
 +
 +	* create.c (ptw32_start_call): Change pthread_exit() call to
 +	ptw32_exit() call.
 +
 +	* exit.c (ptw32_vacuum): Add thread entry deletion code
 +	moved from ptw32_start_call(). See next item.
 +	(pthread_exit): Remove longjmp(). Add mutex lock around thread table
 +	manipulation code. This routine now calls _enthreadex().
 +
 +	* create.c (ptw32_start_call): Remove setjmp() call and move
 +	cleanup code out. Call pthread_exit(NULL) to terminate the thread.
 +
 +1998-07-26  Ben Elliston  <bje@cygnus.com>
 +
 +	* tsd.c (pthread_getspecific): Update comments.
 +
 +	* mutex.c (pthread_mutexattr_setpshared): Not supported; remove.
 +	(pthread_mutexattr_getpshared): Likewise.
 +
 +	* pthread.h (pthread_mutexattr_setpshared): Remove prototype.
 +	(pthread_mutexattr_getpshared): Likewise.
 +
 +Sun Jul 26 00:09:59 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* sync.c: Rename all instances of ptw32_count_mutex to
 +	ptw32_table_mutex.
 +
 +	* implement.h: Rename ptw32_count_mutex to
 +	ptw32_table_mutex.
 +
 +	* global.c: Rename ptw32_count_mutex to
 +	ptw32_table_mutex.
 +
 +	* create.c (pthread_create): Add critical sections.
 +	(ptw32_start_call): Rename ptw32_count_mutex to
 +	ptw32_table_mutex.
 +
 +	* cancel.c (pthread_setcancelstate): Fix indirection bug and rename
 +	"this" to "us".
 +
 +	* signal.c (pthread_sigmask): Rename "this" to "us" and fix some
 +	minor syntax errors. Declare "us" and initialise it.
 +
 +	* sync.c (pthread_detach): Rename "this" to "target".
 +
 +	* pthread.h: Converting PTHREAD_* defines to alias the (const int)
 +	values in global.c.
 +
 +	* global.c: Started converting PTHREAD_* defines to (const int) as
 + 	a part of making the eventual pthreads DLL binary compatible
 + 	through version changes.
 +
 +	* condvar.c (cond_wait): Add cancelation point. This applies the
 +	point to both pthread_cond_wait() and pthread_cond_timedwait().
 +
 +	* exit.c (pthread_exit): Rename "this" to "us".
 +
 +	* implement.h: Add comment.
 +
 +	* sync.c (pthread_join): I've satisfied myself that pthread_detach()
 +	does set the detached attribute in the thread entry attributes
 +	to PTHREAD_CREATE_DETACHED. "if" conditions were changed to test
 +	that attribute instead of a separate flag.
 +
 +	* create.c (pthread_create): Rename "this" to "us".
 +	(pthread_create): cancelstate and canceltype are not attributes
 +	so the copy to thread entry attribute storage was removed.
 +	Only the thread itself can change it's cancelstate or canceltype,
 +	ie. the thread must exist already.
 +
 +	* private.c (ptw32_delete_thread_entry): Mutex locks removed.
 +	Mutexes must be applied at the caller level.
 +	(ptw32_new_thread_entry): Ditto.
 +	(ptw32_new_thread_entry): Init cancelstate, canceltype, and
 +	cancel_pending to default values.
 +	(ptw32_new_thread_entry): Rename "this" to "new".
 +	(ptw32_find_thread_entry): Rename "this" to "entry".
 +	(ptw32_delete_thread_entry): Rename "thread_entry" to "entry".
 +
 +	* create.c (ptw32_start_call): Mutexes changed to
 +	ptw32_count_mutex. All access to the threads table entries is
 +	under the one mutex. Otherwise chaos reigns.
 +
 +Sat Jul 25 23:16:51 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h (ptw32_threads_thread): Move cancelstate and
 + 	canceltype members out of pthread_attr_t into here.
 +
 +	* fork.c (fork): Add comment.
 +
 +1998-07-25  Ben Elliston  <bje@cygnus.com>
 +
 +	* fork.c (fork): Autoconfiscate.
 +
 +Sat Jul 25 00:00:13 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* create.c (ptw32_start_call): Set thread priority.  Ensure our
 + 	thread entry is removed from the thread table but only if
 + 	pthread_detach() was called and there are no waiting joins.
 +	(pthread_create): Set detach flag in thread entry if the 
 +	thread is created PTHREAD_CREATE_DETACHED.
 +
 +	* pthread.h (pthread_attr_t): Rename member "detachedstate".
 +
 +	* attr.c (pthread_attr_init): Rename attr members.
 +
 +	* exit.c (pthread_exit): Fix indirection mistake.
 +
 +	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
 +
 +	* exit.c (ptw32_vacuum): Fix incorrect args to
 +	ptw32_handler_pop_all() calls.
 +	Make thread entry removal conditional.
 +
 +	* sync.c (pthread_join): Add multiple join and async detach handling.
 +
 +	* implement.h (PTW32_THREADS_TABLE_INDEX): Add.
 +
 +	* global.c (ptw32_threads_mutex_table): Add.
 +
 +	* implement.h (ptw32_once_flag): Remove.
 +	(ptw32_once_lock): Ditto.
 +	(ptw32_threads_mutex_table): Add.
 +
 +	* global.c (ptw32_once_flag): Remove.
 +	(ptw32_once_lock): Ditto.
 +
 +	* sync.c (pthread_join): Fix tests involving new return value
 +	from ptw32_find_thread_entry().
 +	(pthread_detach): Ditto.
 +
 +	* private.c (ptw32_find_thread_entry): Failure return code
 +	changed from -1 to NULL.
 +
 +Fri Jul 24 23:09:33 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* create.c (pthread_create): Change . to -> in sigmask memcpy() args.
 +
 +	* pthread.h: (pthread_cancel): Add function prototype.
 +	(pthread_testcancel): Ditto.
 +
 +1998-07-24  Ben Elliston  <bje@cygnus.com>
 +
 +	* pthread.h (pthread_condattr_t): Rename dummy structure member.
 +	(pthread_mutexattr_t): Likewise.
 +
 +Fri Jul 24 21:13:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* cancel.c (pthread_cancel): Implement.
 +	(pthread_testcancel): Implement.
 +
 +	* exit.c (pthread_exit): Add comment explaining the longjmp().
 +
 +	* implement.h (ptw32_threads_thread_t): New member cancelthread.
 +	(PTW32_YES): Define.
 +	(PTW32_NO): Define.
 +	(RND_SIZEOF): Remove.
 +
 +	* create.c (pthread_create): Rename cancelability to cancelstate.
 +
 +	* pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
 +	(PTHREAD_CANCELED): Define.
 +
 +1998-07-24  Ben Elliston  <bje@cygnus.com>
 +
 +	* pthread.h (SIG_BLOCK): Define if not already defined.
 +	(SIG_UNBLOCK): Likewise.
 +	(SIG_SETMASK): Likewise.
 +	(pthread_attr_t): Add signal mask member.
 +	(pthread_sigmask): Add function prototype.
 +
 +	* signal.c (pthread_sigmask): Implement.
 +
 +	* create.c: #include <string.h> to get a prototype for memcpy().
 +	(pthread_create): New threads inherit their creator's signal
 +	mask.  Copy the signal mask to the new thread structure if we know
 +	about signals.
 +	
 +Fri Jul 24 16:33:17 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* fork.c (pthread_atfork): Add all the necessary push calls.
 +	Local implementation semantics:
 +	If we get an ENOMEM at any time then ALL handlers
 +	(including those from previous pthread_atfork() calls) will be
 +	popped off each of the three atfork stacks before we return.
 +	(fork): Add all the necessary pop calls. Add the thread cancellation
 +	and join calls to the child fork.
 +	Add #includes.
 +
 +	* implement.h: (ptw32_handler_push): Fix return type and stack arg
 +	type in prototype.
 +	(ptw32_handler_pop): Fix stack arg type in prototype.
 +	(ptw32_handler_pop_all): Fix stack arg type in prototype.
 +
 +	* cleanup.c (ptw32_handler_push): Change return type to int and
 +	return ENOMEM if malloc() fails.
 +
 +	* sync.c (pthread_detach): Use equality test, not assignment.
 +
 +	* create.c (ptw32_start_call): Add call to Win32 CloseHandle()
 +	if thread is detached.
 +
 +1998-07-24  Ben Elliston  <bje@cygnus.com>
 +
 +	* sync.c (pthread_detach): Close the Win32 thread handle to
 +	emulate detached (or daemon) threads.
 +
 +Fri Jul 24 03:00:25 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* sync.c (pthread_join): Save valueptr arg in joinvalueptr for
 +	pthread_exit() to use.
 +
 +	* private.c (ptw32_new_thread_entry): Initialise joinvalueptr to
 +	NULL.
 +
 +	* create.c (ptw32_start_call): Rewrite to facilitate joins.
 +	pthread_exit() will do a longjmp() back to here. Does appropriate
 +	cleanup and exit/return from the thread.
 +	(pthread_create): _beginthreadex() now passes a pointer to our
 +	thread table entry instead of just the call member of that entry.
 +
 +	* implement.h (ptw32_threads_thread): New member 
 +	void ** joinvalueptr.
 +	(ptw32_call_t): New member jmpbuf env.
 +
 +	* exit.c (pthread_exit): Major rewrite to handle joins and handing
 +	value pointer to joining thread. Uses longjmp() back to 
 +	ptw32_start_call().
 +
 +	* create.c (pthread_create): Ensure values of new attribute members
 +	are copied to the thread attribute object.
 +
 +	* attr.c (pthread_attr_destroy):  Fix merge conflicts.
 +	(pthread_attr_getdetachstate):  Fix merge conflicts.
 +	(pthread_attr_setdetachstate):  Fix merge conflicts.
 +
 +	* pthread.h:  Fix merge conflicts.
 +
 +	* sync.c (pthread_join): Fix merge conflicts.
 +
 +Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* sync.c (pthread_join): Add check for valid and joinable
 +	thread.
 +	(pthread_detach): Implement. After checking for a valid and joinable
 +	thread, it's still a no-op.
 +
 +	* private.c (ptw32_find_thread_entry): Bug prevented returning
 +	an error value in some cases.
 +
 +	* attr.c (pthread_attr_setdetachedstate): Implement.
 +	(pthread_attr_getdetachedstate): Implement.
 +
 +	* implement.h: Move more hidden definitions into here from
 +	pthread.h.
 +
 +1998-07-24  Ben Elliston  <bje@cygnus.com>
 +
 +	* pthread.h (PTHREAD_CREATE_JOINABLE): Define.
 +	(PTHREAD_CREATE_DETACHED): Likewise.
 +	(pthread_attr_t): Add new structure member `detached'.
 +	(pthread_attr_getdetachstate): Add function prototype.
 +	(pthread_attr_setdetachstate): Likewise.
 +
 +	* sync.c (pthread_join): Return if the target thread is detached.
 +
 +	* attr.c (pthread_attr_init): Initialise cancelability and
 +	canceltype structure members.
 +	(pthread_attr_getdetachstate): Implement.
 +	(pthread_attr_setdetachstate): Likewise.
 +
 +	* 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.
 +
 +	* cancel.c: New file.
 +
 +	* pthread.h (sched_param): Define this type.
 +	(pthread_attr_getschedparam): Add function prototype.
 +	(pthread_attr_setschedparam): Likewise.
 +	(pthread_setcancelstate): Likewise.
 +	(pthread_setcanceltype): Likewise.
 +	(sched_get_priority_min): Likewise.
 +	(sched_get_priority_max): Likewise.
 +	(pthread_mutexattr_setprotocol): Remove; not supported.
 +	(pthread_mutexattr_getprotocol): Likewise.
 +	(pthread_mutexattr_setprioceiling): Likewise.
 +	(pthread_mutexattr_getprioceiling): Likewise.
 +	(pthread_attr_t): Add canceltype member.  Update comments.
 +	(SCHED_OTHER): Define this scheduling policy constant.
 +	(SCHED_FIFO): Likewise.
 +	(SCHED_RR): Likewise.
 +	(SCHED_MIN): Define the lowest possible value for this constant.
 +	(SCHED_MAX): Likewise, the maximum possible value.
 +	(PTHREAD_CANCEL_ASYNCHRONOUS): Redefine.
 +	(PTHREAD_CANCEL_DEFERRED): Likewise.
 +	
 +	* sched.c: New file.
 +	(pthread_setschedparam): Implement.
 +	(pthread_getschedparam): Implement.
 +	(sched_get_priority_max): Validate policy argument.
 +	(sched_get_priority_min): Likewise.
 +
 +	* mutex.c (pthread_mutexattr_setprotocol): Remove; not supported.
 +	(pthread_mutexattr_getprotocol): Likewise.
 +	(pthread_mutexattr_setprioceiling): Likewise.
 +	(pthread_mutexattr_getprioceiling): Likewise.
 +
 +Fri Jul 24 00:21:21 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* create.c (pthread_create): Arg to ptw32_new_thread_entry()
 +	changed. See next entry. Move mutex locks out. Changes made yesterday
 +	and today allow us to start the new thread running rather than
 +	temporarily suspended.
 +
 +	* private.c (ptw32_new_thread_entry): ptw32_thread_table
 +	was changed back to a table of thread structures rather than pointers.
 +	As such we're trading storage for increaded speed. This routine
 +	was modified to work with the new table. Mutex lock put in around
 +	global data accesses.
 +	(ptw32_find_thread_entry): Ditto
 +	(ptw32_delete_thread_entry): Ditto
 +
 +Thu Jul 23 23:25:30 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* global.c: New. Global data objects declared here. These moved from
 +	pthread.h.
 +
 +	* pthread.h: Move implementation hidden definitions into
 +	implement.h.
 +
 +	* implement.h: Move implementation hidden definitions from
 +	pthread.h. Add constants to index into the different handler stacks.
 +
 +	* cleanup.c (ptw32_handler_push): Simplify args. Restructure.
 +	(ptw32_handler_pop): Simplify args. Restructure.
 +	(ptw32_handler_pop_all): Simplify args. Restructure.
 +
 +Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge
 +	conflicts.
 +
 +	* private.c (ptw32_find_thread_entry): Changes to return type
 +	to support leaner ptw32_threads_table[] which now only stores
 +	ptw32_thread_thread_t *.
 +	(ptw32_new_thread_entry): Internal changes.
 +	(ptw32_delete_thread_entry): Internal changes to avoid contention.
 + 	Calling routines changed accordingly.
 +
 +	* pthread.h: Modified cleanup macros to use new generic push and pop.
 +	Added destructor and atfork stacks to ptw32_threads_thread_t.
 +
 +	* cleanup.c (ptw32_handler_push, ptw32_handler_pop,
 +	ptw32_handler_pop_all): Renamed cleanup push and pop routines
 +	and made generic to handle destructors and atfork handlers as
 +	well.
 +
 +	* create.c (ptw32_start_call): New function is a wrapper for
 +	all new threads. It allows us to do some cleanup when the thread
 +	returns, ie. that is otherwise only done if the thread is cancelled.
 +
 +	* exit.c (ptw32_vacuum): New function contains code from 
 +	pthread_exit() that we need in the new ptw32_start_call()
 +	as well.
 +
 +	* implement.h: Various additions and minor changes.
 +
 +	* pthread.h: Various additions and minor changes.
 +	Change cleanup handler macros to use generic handler push and pop
 +	functions.
 +
 +	* attr.c: Minor mods to all functions.
 +	(is_attr): Implemented missing function.
 +
 +	* create.c (pthread_create): More clean up.
 +
 +	* private.c (ptw32_find_thread_entry): Implement.
 +	(ptw32_delete_thread_entry): Implement.
 +	(ptw32_new_thread_entry): Implement.
 +	These functions manipulate the implementations internal thread
 +	table and are part of general code cleanup and modularisation.
 +	They replace ptw32_getthreadindex() which was removed.
 +
 +	* exit.c (pthread_exit): Changed to use the new code above.
 +
 +	* pthread.h: Add cancelability constants. Update comments.
 +
 +1998-07-22  Ben Elliston  <bje@cygnus.com>
 +
 +	* attr.c (pthread_setstacksize): Update test of attr argument.
 +	(pthread_getstacksize): Likewise.
 +	(pthread_setstackaddr): Likewise.
 +	(pthread_getstackaddr): Likewise.
 +	(pthread_attr_init): No need to allocate any storage.
 +	(pthread_attr_destroy): No need to free any storage.
 +
 +	* mutex.c (is_attr): Not likely to be needed; remove.
 +	(remove_attr): Likewise.
 +	(insert_attr): Likewise.
 +
 +	* implement.h (ptw32_mutexattr_t): Moved to a public definition
 +	in pthread.h.  There was little gain in hiding these details.
 +	(ptw32_condattr_t): Likewise.
 +	(ptw32_attr_t): Likewise.
 +
 +	* pthread.h (pthread_atfork): Add function prototype.
 +	(pthread_attr_t): Moved here from implement.h.
 +
 +	* fork.c (pthread_atfork): Preliminary implementation.
 +	(ptw32_fork): Likewise.
 +
 +Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* cleanup.c (ptw32_cleanup_push): Implement.
 +	(ptw32_cleanup_pop): Implement.
 +	(ptw32_do_cancellation): Implement.
 +	These are private to the implementation. The real cleanup functions
 +	are macros. See below.
 +
 +	* pthread.h (pthread_cleanup_push): Implement as a macro.
 +	(pthread_cleanup_pop): Implement as a macro.
 +	Because these are macros which start and end a block, the POSIX scoping
 +	requirement is observed. See the comment in the file.
 +
 +	* exit.c (pthread_exit): Refine the code.
 +
 +	* create.c (pthread_create): Code cleanup.
 +
 +	* implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
 +	up to multiple of DWORD.
 +	Add function prototypes.
 +
 +	* private.c (ptw32_getthreadindex): "*thread" should have been 
 +	"thread". Detect empty slot fail condition.
 +
 +1998-07-20  Ben Elliston  <bje@cygnus.com>
 +
 +	* misc.c (pthread_once): Implement.  Don't use a per-application
 +	flag and mutex--make `pthread_once_t' contain these elements in
 +	their structure.  The earlier version had incorrect semantics.
 +	
 +	* pthread.h (ptw32_once_flag): Add new variable.  Remove.
 +	(ptw32_once_lock): Add new mutex lock to ensure integrity of
 +	access to ptw32_once_flag.  Remove.
 +	(pthread_once): Add function prototype.
 +	(pthread_once_t): Define this type.
 +	
 +Mon Jul 20 02:31:05 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* private.c (ptw32_getthreadindex): Implement.
 +
 +	* pthread.h: Add application static data dependent on
 +	_PTHREADS_BUILD_DLL define. This is needed to avoid allocating
 +	non-sharable static data within the pthread DLL.
 +
 +	* implement.h: Add ptw32_cleanup_stack_t, ptw32_cleanup_node_t
 +	and PTW32_HASH_INDEX.
 +
 +	* exit.c (pthread_exit): Begin work on cleanup and de-allocate
 +	thread-private storage.
 +
 +	* create.c (pthread_create): Add thread to thread table.
 +	Keep a thread-private copy of the attributes with default values
 +	filled in when necessary. Same for the cleanup stack. Make 
 +	pthread_create C run-time library friendly by using _beginthreadex()
 +	instead of CreateThread(). Fix error returns.
 +
 +Sun Jul 19 16:26:23 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h: Rename pthreads_thread_count to ptw32_threads_count.
 +	Create ptw32_threads_thread_t struct to keep thread specific data.
 +
 +	* create.c: Rename pthreads_thread_count to ptw32_threads_count.
 +	(pthread_create): Handle errors from CreateThread().
 +
 +1998-07-19  Ben Elliston  <bje@cygnus.com>
 +
 +	* condvar.c (pthread_cond_wait): Generalise.  Moved from here ..
 +	(cond_wait): To here.
 +	(pthread_cond_timedwait): Implement; use generalised cond_wait().
 +
 +	* pthread.h (pthread_key_t): Define this type.
 +	(pthread_key_create): Add function prototype.
 +	(pthread_setspecific): Likewise.
 +	(pthread_getspecific): Likwise.
 +	(pthread_key_delete): Likewise.
 +
 +	* tsd.c (pthread_key_create): Implement.
 +	(pthread_setspecific): Likewise.
 +	(pthread_getspecific): Likewise.
 +	(pthread_key_delete): Likewise.
 +
 +	* mutex.c (pthread_mutex_trylock): Return ENOSYS if this function
 +	is called on a Win32 platform which is not Windows NT.
 +
 +1998-07-18  Ben Elliston  <bje@cygnus.com>
 +
 +	* condvar.c (pthread_condattr_init): Do not attempt to malloc any
 +	storage; none is needed now that condattr_t is an empty struct.
 +	(pthread_condattr_destory): Likewise; do not free storage.
 +	(pthread_condattr_setpshared): No longer supported; return ENOSYS.
 +	(pthread_condattr_getpshared): Likewise.
 +	(pthread_cond_init): Implement with help from Douglas Schmidt.
 +	Remember to initialise the cv's internal mutex.
 +	(pthread_cond_wait): Likewise.
 +	(pthread_cond_signal): Likewise.
 +	(pthread_cond_broadcast): Likewise.
 +	(pthread_cond_timedwait): Preliminary implementation, but I need
 +	to see some API documentation for `WaitForMultipleObject'.
 +	(pthread_destory): Implement.
 +
 +	* pthread.h (pthread_cond_init): Add function protoype.
 +	(pthread_cond_broadcast): Likewise.
 +	(pthread_cond_signal): Likewise.
 +	(pthread_cond_timedwait): Likewise.
 +	(pthread_cond_wait): Likewise.
 +	(pthread_cond_destroy): Likewise.
 +	(pthread_cond_t): Define this type.  Fix for u_int.  Do not assume
 +	that the mutex contained withing the pthread_cond_t structure will
 +	be a critical section.  Use our new POSIX type!
 +
 +	* implement.h (ptw32_condattr_t): Remove shared attribute.
 +
 +1998-07-17  Ben Elliston  <bje@cygnus.com>
 +
 +	* pthread.h (PTHREADS_PROCESS_PRIVATE): Remove.
 +	(PTHREAD_PROCESS_SHARED): Likewise.  No support for mutexes shared
 +	across processes for now.
 +	(pthread_mutex_t): Use a Win32 CRITICAL_SECTION type for better
 +	performance.
 +	
 +	* implement.h (ptw32_mutexattr_t): Remove shared attribute.
 +	
 +	* mutex.c (pthread_mutexattr_setpshared): This optional function
 +	is no longer supported, since we want to implement POSIX mutex
 +	variables using the much more efficient Win32 critical section
 +	primitives.  Critical section objects in Win32 cannot be shared
 +	between processes.
 +	(pthread_mutexattr_getpshared): Likewise.
 +	(pthread_mutexattr_init): No need to malloc any storage; the
 +	attributes structure is now empty.
 +	(pthread_mutexattr_destroy): This is now a nop.
 +	(pthread_mutex_init): Use InitializeCriticalSection().
 +	(pthread_mutex_destroy): Use DeleteCriticalSection().
 +	(pthread_mutex_lock): Use EnterCriticalSection().
 +	(pthread_mutex_trylock): Use TryEnterCriticalSection().  This is
 +	not supported by Windows 9x, but trylock is a hack anyway, IMHO.
 +	(pthread_mutex_unlock): Use LeaveCriticalSection().
 +
 +1998-07-14  Ben Elliston  <bje@cygnus.com>
 +
 +	* attr.c (pthread_attr_setstacksize): Implement.
 +	(pthread_attr_getstacksize): Likewise.
 +	(pthread_attr_setstackaddr): Likewise.
 +	(pthread_attr_getstackaddr): Likewise.
 +	(pthread_attr_init): Likewise.
 +	(pthread_attr_destroy): Likewise.
 +	
 +	* condvar.c (pthread_condattr_init): Add `_cond' to function name.
 +
 +	* mutex.c (pthread_mutex_lock): Add `_mutex' to function name.
 +	(pthread_mutex_trylock): Likewise.
 +	(pthread_mutex_unlock): Likewise.
 +
 +	* pthread.h (pthread_condattr_setpshared): Fix typo.
 +	(pthread_attr_init): Add function prototype.
 +	(pthread_attr_destroy): Likewise.
 +	(pthread_attr_setstacksize): Likewise.
 +	(pthread_attr_getstacksize): Likewise.
 +	(pthread_attr_setstackaddr): Likewise.
 +	(pthread_attr_getstackaddr): Likewise.
 +	
 +Mon Jul 13 01:09:55 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h: Wrap in #ifndef _IMPLEMENT_H
 +
 +	* create.c (pthread_create): Map stacksize attr to Win32.
 +
 +	* mutex.c: Include implement.h
 +
 +1998-07-13  Ben Elliston  <bje@cygnus.com>
 +
 +	* condvar.c (pthread_condattr_init): Implement.
 +	(pthread_condattr_destroy): Likewise.
 +	(pthread_condattr_setpshared): Likewise.
 +	(pthread_condattr_getpshared): Likewise.
 +	
 +	* implement.h (PTHREAD_THREADS_MAX): Remove trailing semicolon.
 +	(PTHREAD_STACK_MIN): Specify; needs confirming.
 +	(ptw32_attr_t): Define this type.
 +	(ptw32_condattr_t): Likewise.
 +
 +	* pthread.h (pthread_mutex_t): Define this type.
 +	(pthread_condattr_t): Likewise.
 +	(pthread_mutex_destroy): Add function prototype.
 +	(pthread_lock): Likewise.
 +	(pthread_trylock): Likewise.
 +	(pthread_unlock): Likewise.
 +	(pthread_condattr_init): Likewise.
 +	(pthread_condattr_destroy): Likewise.
 +	(pthread_condattr_setpshared): Likewise.
 +	(pthread_condattr_getpshared): Likewise.
 +
 +	* mutex.c (pthread_mutex_init): Implement.
 +	(pthread_mutex_destroy): Likewise.
 +	(pthread_lock): Likewise.
 +	(pthread_trylock): Likewise.
 +	(pthread_unlock): Likewise.
 +
 +1998-07-12  Ben Elliston  <bje@cygnus.com>
 +
 +	* implement.h (ptw32_mutexattr_t): Define this implementation
 +	internal type.  Application programmers only see a mutex attribute
 +	object as a void pointer.
 +
 +	* pthread.h (pthread_mutexattr_t): Define this type.
 +	(pthread_mutexattr_init): Add function prototype.
 +	(pthread_mutexattr_destroy): Likewise.
 +	(pthread_mutexattr_setpshared): Likewise.
 +	(pthread_mutexattr_getpshared): Likewise.
 +	(pthread_mutexattr_setprotocol): Likewise.
 +	(pthread_mutexattr_getprotocol): Likewise.
 +	(pthread_mutexattr_setprioceiling): Likewise.
 +	(pthread_mutexattr_getprioceiling): Likewise.
 +	(PTHREAD_PROCESS_PRIVATE): Define.
 +	(PTHREAD_PROCESS_SHARED): Define.
 +
 +	* mutex.c (pthread_mutexattr_init): Implement.
 +	(pthread_mutexattr_destroy): Implement.
 +	(pthread_mutexattr_setprotocol): Implement.
 +	(pthread_mutexattr_getprotocol): Likewise.
 +	(pthread_mutexattr_setprioceiling): Likewise.
 +	(pthread_mutexattr_getprioceiling): Likewise.
 +	(pthread_mutexattr_setpshared): Likewise.
 +	(pthread_mutexattr_getpshared): Likewise.
 +	(insert_attr): New function; very preliminary implementation!
 +	(is_attr): Likewise.
 +	(remove_attr): Likewise.
 +	
 +Sat Jul 11 14:48:54 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* implement.h: Preliminary implementation specific defines.
 +
 +	* create.c (pthread_create): Preliminary implementation.
 +
 +1998-07-11  Ben Elliston  <bje@cygnus.com>
 +
 +	* sync.c (pthread_join): Implement.
 +
 +	* misc.c (pthread_equal): Likewise.
 +	
 +	* pthread.h (pthread_join): Add function prototype.
 +	(pthread_equal): Likewise.
 +	
 +1998-07-10  Ben Elliston  <bje@cygnus.com>
 +
 +	* misc.c (pthread_self): Implement.
 +
 +	* exit.c (pthread_exit): Implement.
 +
 +	* pthread.h (pthread_exit): Add function prototype.
 +	(pthread_self): Likewise.
 +	(pthread_t): Define this type.
 +
 +1998-07-09  Ben Elliston  <bje@cygnus.com>
 +
 +	* create.c (pthread_create): A dummy stub right now.
 +
 +	* pthread.h (pthread_create): Add function prototype.
 +
 diff --git a/GNUmakefile b/GNUmakefile index a7d13b3..141a778 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -18,23 +18,28 @@  # MA 02111-1307, USA  # -GLANG	= c++ +#RM	= rm +#MV	= mv +#CP	= cp  RM	= erase  MV	= rename  CP	= copy  CC	= gcc +CXX	= g++  AR	= ar -LD	= gcc -mdll - -#OPT	= -g -O0  OPT	= -O3 +#OPT	= -O2 -DNDEBUG -finline-functions + +GC_CFLAGS	= -D__CLEANUP_C +GCE_CFLAGS	= -D__CLEANUP_CXX -x c++ -mthreads  ## Mingw32 -CFLAGS	= $(OPT) -x $(GLANG) -I. -mthreads -D_WIN32_WINNT=0x400 -DHAVE_CONFIG_H -DPTW32_BUILD -Wall +MAKE	= make +CFLAGS	= $(OPT) -I. -D_WIN32_WINNT=0x400 -DHAVE_CONFIG_H -DPTW32_BUILD -Wall  ## Cygwin G++  #CFLAGS	= $(OPT) -x $(GLANG) -fhandle-exceptions -D_WIN32_WINNT=0x400 -I. -DHAVE_CONFIG_H -DPTW32_BUILD -Wall @@ -45,15 +50,31 @@ OBJS	= attr.o cancel.o cleanup.o condvar.o create.o dll.o errno.o \  INCL	= implement.h semaphore.h pthread.h windows.h -DLL     = pthreadGCE.dll +GC_DLL 	= pthreadGC.dll +GCE_DLL = pthreadGCE.dll + +GC_LIB	= libpthreadGC.a +GCE_LIB = libpthreadGCE.a + + +all: +	@ echo Run one of the following command lines: +	@ echo make clean GCE   (to build the GNU C dll with C++ exception handling) +	@ echo make clean GC    (to build the GNU C dll with C cleanup code) -LIBS	= libpthreadw32.a +auto: +	@ $(MAKE) clean GCE +	@ $(MAKE) clean GC +GC: +		$(MAKE) CLEANUP_FLAGS="$(GC_CFLAGS)" $(GC_DLL) -all:	$(LIBS) +GCE: +		$(MAKE) CLEANUP_FLAGS="$(GCE_CFLAGS)" $(GCE_DLL) -$(LIBS): $(DLL) -	dlltool --def pthread.def --output-lib $@ --dllname $(DLL) +tests: +	@ cd tests +	@ $(MAKE) auto  %.pre: %.c  	$(CC) -E -o $@ $(CFLAGS) $^ @@ -61,22 +82,28 @@ $(LIBS): $(DLL)  %.s: %.c  	$(CC) -c $(CFLAGS) -Wa,-ahl $^ > $@ -.SUFFIXES: .dll +.SUFFIXES: .dll .c .o -$(DLL): $(OBJS) -	$(LD) -o $@ $^ -Wl,--base-file,$*.base -	dlltool --base-file=$*.base --def pthread.def --output-exp $*.exp --dllname $@ -	$(LD) -o $@ $^ -Wl,--base-file,$*.base,$*.exp -	dlltool --base-file=$*.base --def pthread.def --output-exp $*.exp --dllname $@ -	$(LD) -o $@ $^ -Wl,$*.exp +.c.o:;		 $(CC) -c -o $@ $(CFLAGS) $(CLEANUP_FLAGS) $< + + +$(GC_DLL): $(OBJS) +	$(CC) $(OPT) -shared -o $@ $^ +	dlltool -k --dllname $@ --output-lib $(GC_LIB) --def pthread.def + +$(GCE_DLL): $(OBJS) +	$(CXX) $(OPT) -mthreads -shared -o $@ $^ +	dlltool -k --dllname $@ --output-lib $(GCE_LIB) --def pthread.def  clean:  	-$(RM) *~  	-$(RM) *.o   	-$(RM) *.exe -	-$(RM) $(DLL:.dll=.base) -	-$(RM) $(DLL:.dll=.exp) -realclean: -	-$(RM) $(LIBS) -	-$(RM) $(DLL)  +realclean: clean +	-$(RM) $(GC_LIB) +	-$(RM) $(GCE_LIB) +	-$(RM) $(GC_DLL) +	-$(RM) $(GCE_DLL) + + @@ -11,12 +11,14 @@ DEVROOT=c:\pthreads\dll  DLLDEST=$(DEVROOT)
  LIBDEST=$(DEVROOT)
 -DLLS	= pthreadVCE.dll pthreadVSE.dll
 +DLLS	= pthreadVCE.dll pthreadVSE.dll pthreadVC.dll
  # C++ Exceptions
 -VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn
 +VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX
  #Structured Exceptions
 -VSEFLAGS	= 
 +VSEFLAGS	= /D__CLEANUP_SEH
 +#C cleanup code
 +VCFLAGS	= /D__CLEANUP_C
  CFLAGS	= /W3 /MT /nologo /Yd /Zi /I. /D_WIN32_WINNT=0x400 /DPTW32_BUILD
 @@ -43,8 +45,14 @@ OBJ=attr.obj \  all:
  	@ echo Run one of the following command lines:
 -	@ echo nmake clean VCE   (to build the dll with C++ exception handling)
 -	@ echo nmake clean VSE   (to build the dll with structured exception handling)
 +	@ echo nmake clean VCE   (to build the MSVC dll with C++ exception handling)
 +	@ echo nmake clean VSE   (to build the MSVC dll with structured exception handling)
 +	@ echo nmake clean VC    (to build the MSVC dll with C cleanup code)
 +
 +auto:
 +	@ nmake clean VCE
 +	@ nmake clean VSE
 +	@ nmake clean VC
  VCE:
  	@ nmake /nologo EHFLAGS="$(VCEFLAGS)" pthreadVCE.dll
 @@ -52,9 +60,12 @@ VCE:  VSE:
  	@ nmake /nologo EHFLAGS="$(VSEFLAGS)" pthreadVSE.dll
 +VC:
 +	@ nmake /nologo EHFLAGS="$(VCFLAGS)" pthreadVC.dll
 +
  realclean: clean
  	if exist *.dll del *.dll
 -	if exit *.lib del *.lib
 +	if exist *.lib del *.lib
  clean:
  	if exist *.obj del *.obj
 @@ -23,7 +23,10 @@   * MA 02111-1307, USA   */ -#include <memory.h> +/* ignore warning "unreferenced formal parameter" */ +#ifdef _MSC_VER +#pragma warning( disable : 4100 ) +#endif  #include "pthread.h"  #include "implement.h" @@ -494,3 +497,31 @@ pthread_attr_setdetachstate(pthread_attr_t *attr,    (*attr)->detachstate = detachstate;    return 0;  } + +int +pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +  if (contentionscope != PTHREAD_SCOPE_SYSTEM) +    { +      return ENOTSUP; +    } +  +  return 0; +#else +  return ENOSYS; +#endif +} +  +  +int +pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) +{ +#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING +  *contentionscope = PTHREAD_SCOPE_SYSTEM; +  return 0; +#else +  return ENOSYS; +#endif +} + @@ -27,6 +27,27 @@  #include "implement.h" +#if defined(_M_IX86) || defined(_X86_) +#define PROGCTR(Context)  ((Context).Eip) +#endif +  +#if defined(_MIPS_) +#define PROGCTR(Context)  ((Context).Fir) +#endif +  +#if defined(_ALPHA_) +#define PROGCTR(Context)  ((Context).Fir) +#endif +  +#if defined(_PPC_) +#define PROGCTR(Context)  ((Context).Iar) +#endif +  +#if !defined(PROGCTR) +#error Module contains CPU-specific code; modify and recompile. +#endif                                                                           + +  static void   ptw32_cancel_self(void)  { @@ -50,13 +71,11 @@ ptw32_cancel_thread(pthread_t thread)    if (WaitForSingleObject(threadH, 0) == WAIT_TIMEOUT)      { -#if defined(_M_IX86) || defined(_X86_)        CONTEXT context;        context.ContextFlags = CONTEXT_CONTROL;        GetThreadContext(threadH, &context); -      context.Eip = (DWORD) ptw32_cancel_self; +      PROGCTR(context) = (DWORD) ptw32_cancel_self;        SetThreadContext(threadH, &context); -#endif        ResumeThread(threadH);      } @@ -25,23 +25,18 @@   * MA 02111-1307, USA   */ -#if !defined(_MSC_VER) && !defined(__cplusplus) && defined(__GNUC__) - -#warning Compile __FILE__ as C++ or thread cancellation will not work properly. - -#endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ -  #include "pthread.h"  #include "implement.h" +  /* - * The functions pthread_pop_cleanup and pthread_push_cleanup + * The functions ptw32_pop_cleanup and ptw32_push_cleanup   * are implemented here for applications written in C with no   * SEH or C++ destructor support.    */  ptw32_cleanup_t * -pthread_pop_cleanup (int execute) +ptw32_pop_cleanup (int execute)       /*        * ------------------------------------------------------        * DOCPUBLIC @@ -76,63 +71,12 @@ pthread_pop_cleanup (int execute)        if (execute && (cleanup->routine != NULL))          { -#if defined(_MSC_VER) && !defined(__cplusplus) - -          __try -	    { -	      /* -	       * Run the caller's cleanup routine. -	       */ -	      (*cleanup->routine) (cleanup->arg); -	    } -          __except (EXCEPTION_EXECUTE_HANDLER) -	    { -	      /* -	       * A system unexpected exception had occurred -	       * running the user's cleanup routine. -	       * We get control back within this block. -	       */ -	    } -       -#else /* _MSC_VER && ! __cplusplus */ - -#ifdef __cplusplus - -	  try -	    { -	      /* -	       * Run the caller's cleanup routine. -	       */ -	      (*cleanup->routine) (cleanup->arg); -	    } -	  catch(...) -	    { -	      /* -	       * A system unexpected exception had occurred -	       * running the user's cleanup routine. -	       * We get control back within this block. -	       */ -	    } - -#else /* __cplusplus */ -       -	  /* -	   * Run the caller's cleanup routine and FIXME: hope for the best. -	   */  	  (*cleanup->routine) (cleanup->arg); -#endif /* __cplusplus && ! __cplusplus */ - -#endif /* _MSC_VER */ -          } -#if !defined(_MSC_VER) && !defined(__cplusplus) -        pthread_setspecific (ptw32_cleanupKey, (void *) cleanup->prev); -#endif /* !_MSC_VER && !__cplusplus */ -      }    return (cleanup); @@ -141,8 +85,8 @@ pthread_pop_cleanup (int execute)  void -pthread_push_cleanup (ptw32_cleanup_t * cleanup, -		      void (*routine) (void *), +ptw32_push_cleanup (ptw32_cleanup_t * cleanup, +		      ptw32_cleanup_callback_t routine,  		      void *arg)       /*        * ------------------------------------------------------ @@ -174,7 +118,7 @@ pthread_push_cleanup (ptw32_cleanup_t * cleanup,        *              b) when the thread acts on a cancellation request,        *              c) or when the thrad calls pthread_cleanup_pop with a nonzero        *                 'execute' argument -      *      NOTE: pthread_push_cleanup, pthread_pop_cleanup must be paired +      *      NOTE: pthread_push_cleanup, ptw32_pop_cleanup must be paired        *                in the same lexical scope.        *        * RESULTS @@ -187,14 +131,8 @@ pthread_push_cleanup (ptw32_cleanup_t * cleanup,    cleanup->routine = routine;    cleanup->arg = arg; -#if !defined(_MSC_VER) && !defined(__cplusplus) -    cleanup->prev = (ptw32_cleanup_t *) pthread_getspecific (ptw32_cleanupKey); -#endif /* !_MSC_VER && !__cplusplus */ -    pthread_setspecific (ptw32_cleanupKey, (void *) cleanup);  }                               /* ptw32_push_cleanup */ - - @@ -26,6 +26,7 @@  #include "pthread.h"  #include "implement.h" +#include <process.h>  int  pthread_create (pthread_t * tid, @@ -141,7 +142,7 @@ pthread_create (pthread_t * tid,      _beginthreadex (  		     (void *) NULL,	/* No security info             */  		     (unsigned) stackSize,	/* default stack size   */ -		     (unsigned (PT_STDCALL *) (void *)) ptw32_threadStart, +		     ptw32_threadStart,  		     parms,  		     (unsigned) CREATE_SUSPENDED,  		     (unsigned *) &(thread->thread)); @@ -161,7 +162,7 @@ pthread_create (pthread_t * tid,    thread->threadH = threadH = (HANDLE)      _beginthread ( -		   (void (PT_STDCALL *) (void *)) ptw32_hreadStart, +		   ptw32_threadStart,  		   (unsigned) stackSize,	/* default stack size   */  		   parms); @@ -23,7 +23,6 @@   * MA 02111-1307, USA   */ -#include <malloc.h>  #include "pthread.h"  #include "implement.h" @@ -44,13 +43,6 @@   * Dear c++: Please don't mangle this name. -thanks   */  extern "C" -{ -#endif /* __cplusplus */ - -  BOOL WINAPI DllMain( HINSTANCE, DWORD, LPVOID); - -#ifdef __cplusplus -}  #endif /* __cplusplus */  BOOL WINAPI @@ -24,7 +24,7 @@   * MA 02111-1307, USA   */ -#if (! defined(HAVE_ERRNO)) || (! defined( _REENTRANT ) && (! defined( _MT ) || ! defined( _MD ))) +#if (! defined(HAVE_ERRNO)) && (! defined(_REENTRANT)) && (! defined(_MT))  #include "pthread.h"  #include "implement.h" @@ -26,6 +26,7 @@  #include "pthread.h"  #include "implement.h" +#include <process.h>  void  pthread_exit (void *value_ptr) @@ -32,10 +32,9 @@ int ptw32_processInitialized = FALSE;  pthread_key_t ptw32_selfThreadKey = NULL;  pthread_key_t ptw32_cleanupKey = NULL; -/*  - * Function pointer to TryEnterCriticalSection if it exists; otherwise NULL  - */ -BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION) = NULL; +int ptw32_mutex_default_kind = PTHREAD_MUTEX_DEFAULT; + +int ptw32_concurrency = 0;  /*   * Global lock for testing internal state of PTHREAD_MUTEX_INITIALIZER diff --git a/implement.h b/implement.h index c6f535e..fa02444 100644 --- a/implement.h +++ b/implement.h @@ -27,14 +27,8 @@  #ifndef _IMPLEMENT_H  #define _IMPLEMENT_H -#ifdef __MINGW32__ -#define PT_STDCALL -#else -#ifdef __cplusplus -#define PT_STDCALL __stdcall -#else -#define PT_STDCALL __stdcall -#endif +#if defined(__MINGW32__) +#include <malloc.h>  #endif  /* changed include from <semaphore.h> to use local file during development */ @@ -85,6 +79,9 @@ struct pthread_t_ {    int cancelState;    int cancelType;    HANDLE cancelEvent; +#ifdef __CLEANUP_C +  jmp_buf start_mark; +#endif /* __CLEANUP_C */  #if HAVE_SIGSET_T    sigset_t sigmask;  #endif /* HAVE_SIGSET_T */ @@ -122,16 +119,18 @@ struct pthread_attr_t_ {  #define PTW32_OBJECT_INVALID   NULL  struct pthread_mutex_t_ { -  HANDLE mutex; -  CRITICAL_SECTION cs; -  int lockCount; +  LONG lock_idx; +  int recursive_count; +  int kind;    pthread_t ownerThread; +  HANDLE wait_sema; +  CRITICAL_SECTION try_lock_cs;  };  struct pthread_mutexattr_t_ {    int pshared; -  int forcecs; +  int kind;  }; @@ -173,23 +172,23 @@ struct pthread_condattr_t_ {    int pshared;  }; -#define RW_MAGIC    0x19283746 +#define PTW32_RWLOCK_MAGIC 0xfacade2  struct pthread_rwlock_t_ { -    pthread_mutex_t rw_lock;         /* basic lock on this struct */ -    pthread_cond_t  rw_condreaders;  /* for reader threads waiting */ -    pthread_cond_t  rw_condwriters;  /* for writer threads waiting */ -    int             rw_magic;        /* for error checking */ -    int             rw_nwaitreaders; /* the number waiting */ -    int             rw_nwaitwriters; /* the number waiting */ -    int             rw_refcount;     /* -1 if writer has the lock, -                                        else # readers holding the lock */ +  pthread_mutex_t   mtxExclusiveAccess; +  pthread_mutex_t   mtxSharedAccessCompleted; +  pthread_cond_t    cndSharedAccessCompleted; +  int               nSharedAccessCount; +  int               nExclusiveAccessCount; +  int               nCompletedSharedAccessCount; +  int               nMagic;  };  struct pthread_rwlockattr_t_ { -  int pshared; +  int               pshared;  }; +  struct ThreadKeyAssoc {    /*     * Purpose: @@ -249,7 +248,7 @@ struct ThreadKeyAssoc {  }; -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH  /*   * --------------------------------------------------------------   * MAKE_SOFTWARE_EXCEPTION @@ -292,25 +291,31 @@ struct ThreadKeyAssoc {  #define PTW32_SERVICES_FACILITY		0xBAD  #define PTW32_SERVICES_ERROR	       	0xDEED -#endif /* _MSC_VER */ +#endif /* __CLEANUP_SEH */  /*   * Services available through EXCEPTION_PTW32_SERVICES   * and also used [as parameters to ptw32_throw()] as   * generic exception selectors.   */ -#define PTW32_EPS_CANCEL       0 -#define PTW32_EPS_EXIT         1 +#define PTW32_EPS_EXIT        		(1) +#define PTW32_EPS_CANCEL       		(2) + +#define PTW32_MUTEX_LOCK_IDX_INIT	(-1)  /* Declared in global.c */  extern int ptw32_processInitialized;  extern pthread_key_t ptw32_selfThreadKey;  extern pthread_key_t ptw32_cleanupKey; + +extern int ptw32_mutex_default_kind; + +extern int ptw32_concurrency; +  extern CRITICAL_SECTION ptw32_mutex_test_init_lock;  extern CRITICAL_SECTION ptw32_cond_test_init_lock;  extern CRITICAL_SECTION ptw32_rwlock_test_init_lock; -extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION);  /* Declared in misc.c */ @@ -339,16 +344,16 @@ void ptw32_processTerminate (void);  void ptw32_threadDestroy (pthread_t tid); -void ptw32_cleanupStack (void); +void ptw32_pop_cleanup_all (int execute);  pthread_t ptw32_new (void);  #if ! defined (__MINGW32__) || defined (__MSVCRT__) -unsigned PT_STDCALL +unsigned __stdcall  #else  void  #endif -ptw32_threadStart (ThreadParms * threadParms); +ptw32_threadStart (void * vthreadParms);  void ptw32_callUserDestroyRoutines (pthread_t thread); @@ -142,36 +142,9 @@ pthread_self (void)        * ------------------------------------------------------        */  { -  pthread_t self = NULL; -  DWORD lastErr; +  pthread_t self; -  /* -   * Need to ensure there always is a self. -   * -   * The following call to pthread_getspecific uses TlsGetValue. -   * Win32 functions that return indications of failure call SetLastError when -   * they fail. They generally do not call SetLastError when they succeed. The -   * TlsGetValue function is an exception to this general rule. The TlsGetValue -   * function calls SetLastError to clear a thread's last error when it -   * succeeds. -   * -   * We restore the last error if TlsGetValue succeeds. -   */ -  lastErr = GetLastError();    self = (pthread_t) pthread_getspecific (ptw32_selfThreadKey); -  if (GetLastError() == NO_ERROR) -    { -      SetLastError(lastErr); -    } -  else -    { -      /* -       * What else can we do? GetLastError will tell the -       * the caller more but this is not supposed to -       * happen. -       */ -      return(NULL); -    }    if (self == NULL)      { @@ -265,6 +238,28 @@ pthread_equal (pthread_t t1, pthread_t t2)  }				/* pthread_equal */ +int +pthread_setconcurrency(int level) +{ +  if (level < 0) +    { +      return EINVAL; +    } +  else +    { +      ptw32_concurrency = level; +      return 0; +    } +} +  +  +int +pthread_getconcurrency(void) +{ +  return ptw32_concurrency; +}                                                                                + +  static int  ptw32_cancelable_wait (HANDLE waitHandle, DWORD timeout)       /* @@ -23,9 +23,6 @@   * MA 02111-1307, USA   */ -/* errno.h or a replacement file is included by pthread.h */ -//#include <errno.h> -  #include "pthread.h"  #include "implement.h" @@ -104,10 +101,6 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)        goto FAIL0;      } -  mx->mutex = 0; -  mx->lockCount = 0; -  mx->ownerThread = NULL; -    if (attr != NULL        && *attr != NULL        && (*attr)->pshared == PTHREAD_PROCESS_SHARED @@ -125,61 +118,27 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)  #error ERROR [__FILE__, line __LINE__]: Process shared mutexes are not supported yet. -      mx->mutex = CreateMutex(NULL, FALSE, "FIXME FIXME FIXME"); - -      if (mx->mutex == 0) -	{ -	  result = EAGAIN; -	}  #else        result = ENOSYS; +      goto FAIL0;  #endif /* _POSIX_THREAD_PROCESS_SHARED */ +      } -  else + +  mx->lock_idx = PTW32_MUTEX_LOCK_IDX_INIT; +  mx->recursive_count = 0; +  mx->kind = attr == NULL || *attr == NULL ? ptw32_mutex_default_kind : (*attr)->kind; +  mx->ownerThread = NULL; +  InitializeCriticalSection( &mx->try_lock_cs ); +  mx->wait_sema = CreateSemaphore( NULL, 0, 1, NULL ); + +  if( NULL == mx->wait_sema )      { -      if (ptw32_try_enter_critical_section != NULL -	  || (attr != NULL -	      && *attr != NULL -	      && (*attr)->forcecs == 1) -	  ) -	{ -	  /*  -	   * Create a critical section.  -	   */ -	  InitializeCriticalSection(&mx->cs); - -	  /* -	   * Check that it works ok - since InitializeCriticalSection doesn't -	   * return success or failure. -	   */ -	  if ((*ptw32_try_enter_critical_section)(&mx->cs)) -	    { -	      LeaveCriticalSection(&mx->cs); -	    } -	  else -	    { -	      DeleteCriticalSection(&mx->cs); -	      result = EAGAIN; -	    } -	} -      else -	{ -	  /* -	   * Create a mutex that can only be used within the -	   * current process -	   */ -	  mx->mutex = CreateMutex (NULL, -				   FALSE, -				   NULL); - -	  if (mx->mutex == 0) -	    { -	      result = EAGAIN; -	    } -	} +      DeleteCriticalSection( &mx->try_lock_cs ); +      result = EAGAIN;      }    if (result != 0 && mx != NULL) @@ -213,8 +172,11 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)      {        mx = *mutex; -      if ((result = pthread_mutex_trylock(&mx)) == 0) +      result = pthread_mutex_trylock(&mx); + +      if (result == 0 || pthread_equal( mx->ownerThread, pthread_self() ) )          { +            /*             * FIXME!!!             * The mutex isn't held by another thread but we could still @@ -224,20 +186,12 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)             */            *mutex = NULL; -          pthread_mutex_unlock(&mx); - -          if (mx->mutex == 0) -            { -              DeleteCriticalSection(&mx->cs); -            } -          else -            { -              result = (CloseHandle (mx->mutex) ? 0 : EINVAL); -            } +          result = pthread_mutex_unlock(&mx);            if (result == 0)              { -              mx->mutex = 0; +              DeleteCriticalSection( &mx->try_lock_cs ); +              CloseHandle( mx->wait_sema );                free(mx);              }            else @@ -321,6 +275,9 @@ pthread_mutexattr_init (pthread_mutexattr_t * attr)        result = ENOMEM;      } +  ma->pshared = PTHREAD_PROCESS_PRIVATE; +  ma->kind = ptw32_mutex_default_kind; +    *attr = ma;    return (result); @@ -360,7 +317,6 @@ pthread_mutexattr_destroy (pthread_mutexattr_t * attr)    if (attr == NULL || *attr == NULL)      {        result = EINVAL; -      }    else      { @@ -506,6 +462,7 @@ pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,          {            result = 0;          } +        (*attr)->pshared = pshared;      }    else @@ -519,11 +476,137 @@ pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,  int +pthread_mutexattr_settype (pthread_mutexattr_t * attr, +						   int kind) +     /* +      * ------------------------------------------------------ +      * +      * DOCPUBLIC +      * The pthread_mutexattr_settype() and +      * pthread_mutexattr_gettype() functions  respectively set and +      * get the mutex type  attribute. This attribute is set in  the +      * type parameter to these functions. +      * +      * PARAMETERS +      *      attr +      *              pointer to an instance of pthread_mutexattr_t +      * +      *      type +      *              must be one of: +      * +      *                      PTHREAD_MUTEX_DEFAULT +      * +      *                      PTHREAD_MUTEX_NORMAL +      * +      *                      PTHREAD_MUTEX_ERRORCHECK +      * +      *                      PTHREAD_MUTEX_RECURSIVE +      * +      * DESCRIPTION +      * The pthread_mutexattr_settype() and +      * pthread_mutexattr_gettype() functions  respectively set and +      * get the mutex type  attribute. This attribute is set in  the +      * type  parameter to these functions. The default value of the +      * type  attribute is  PTHREAD_MUTEX_DEFAULT. +      *  +      * The type of mutex is contained in the type  attribute of the +      * mutex attributes. Valid mutex types include: +      * +      * PTHREAD_MUTEX_NORMAL +      *          This type of mutex does  not  detect  deadlock.  A +      *          thread  attempting  to  relock  this mutex without +      *          first unlocking it will  deadlock.  Attempting  to +      *          unlock  a  mutex  locked  by  a  different  thread +      *          results  in  undefined  behavior.  Attempting   to +      *          unlock  an  unlocked  mutex  results  in undefined +      *          behavior. +      *  +      * PTHREAD_MUTEX_ERRORCHECK +      *          This type of  mutex  provides  error  checking.  A +      *          thread  attempting  to  relock  this mutex without +      *          first unlocking it will return with  an  error.  A +      *          thread  attempting to unlock a mutex which another +      *          thread has locked will return  with  an  error.  A +      *          thread attempting to unlock an unlocked mutex will +      *          return with an error. +      * +      * PTHREAD_MUTEX_DEFAULT +      *          Same as PTHREAD_MUTEX_NORMAL. +      *  +      * PTHREAD_MUTEX_RECURSIVE +      *          A thread attempting to relock this  mutex  without +      *          first  unlocking  it  will  succeed in locking the +      *          mutex. The relocking deadlock which can occur with +      *          mutexes of type  PTHREAD_MUTEX_NORMAL cannot occur +      *          with this type of mutex. Multiple  locks  of  this +      *          mutex  require  the  same  number  of  unlocks  to +      *          release  the  mutex  before  another  thread   can +      *          acquire the mutex. A thread attempting to unlock a +      *          mutex which another thread has locked will  return +      *          with  an  error. A thread attempting to  unlock an +      *          unlocked mutex will return  with  an  error.  This +      *          type  of mutex is only supported for mutexes whose +      *          process        shared         attribute         is +      *          PTHREAD_PROCESS_PRIVATE. +      * +      * RESULTS +      *              0               successfully set attribute, +      *              EINVAL          'attr' or 'type' is invalid, +      * +      * ------------------------------------------------------ +      */ +{ +  int result = 0; + +  if ((attr != NULL && *attr != NULL)) +    { +      switch (kind) +        { +        case PTHREAD_MUTEX_FAST_NP: +        case PTHREAD_MUTEX_RECURSIVE_NP: +        case PTHREAD_MUTEX_ERRORCHECK_NP: +          (*attr)->kind = kind; +          break; +        default: +          result = EINVAL; +          break; +        } +    } +  else +    { +      result = EINVAL; +    } +   +  return (result); +}                               /* pthread_mutexattr_settype */ + + +int +pthread_mutexattr_gettype (pthread_mutexattr_t * attr, +                           int *kind) +{ +  int result = 0; + +  if (attr != NULL && *attr != NULL && kind != NULL) +    { +      *kind = (*attr)->kind; +    } +  else +    { +      result = EINVAL; +    } + +  return (result); +} + + +int  pthread_mutex_lock(pthread_mutex_t *mutex)  {    int result = 0;    pthread_mutex_t mx; +    if (mutex == NULL || *mutex == NULL)      {        return EINVAL; @@ -542,25 +625,33 @@ pthread_mutex_lock(pthread_mutex_t *mutex)    mx = *mutex; -  if (result == 0) +  if( 0 == InterlockedIncrement( &mx->lock_idx ) )      { -      if (mx->mutex == 0) -	{ -	  EnterCriticalSection(&mx->cs); -	} -      else -	{ -	  result = (WaitForSingleObject(mx->mutex, INFINITE)  -		    == WAIT_OBJECT_0) -	    ? 0 -	    : EINVAL; -	} +      mx->recursive_count = 1; +      mx->ownerThread = pthread_self();      } - -  if (result == 0) +  else      { -      mx->ownerThread = pthread_self(); -      mx->lockCount++; +      if( mx->kind != PTHREAD_MUTEX_FAST_NP && +          pthread_equal( mx->ownerThread, pthread_self() ) ) +	{ +          mx->lock_idx--; + +          if( mx->kind == PTHREAD_MUTEX_RECURSIVE_NP ) +            { +              mx->recursive_count++; +            } +          else +            { +              result = EDEADLK; +            } +        } +      else +        { +          WaitForSingleObject( mx->wait_sema, INFINITE ); +          mx->recursive_count = 1; +          mx->ownerThread = pthread_self(); +        }      }    return(result); @@ -586,38 +677,22 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)     */    if (mx != (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)      { -      pthread_t self = pthread_self(); - -      if (pthread_equal(mx->ownerThread, self)) +      if (pthread_equal(mx->ownerThread, pthread_self()))  	{ -	  int oldCount = mx->lockCount; -	  pthread_t oldOwner = mx->ownerThread; - -	  if (mx->lockCount > 0) -	    { -	      mx->lockCount--; -	    } - -	  if (mx->lockCount == 0) +          if( mx->kind != PTHREAD_MUTEX_RECURSIVE_NP || +              0 == --mx->recursive_count )  	    {  	      mx->ownerThread = NULL; -	    } -	  if (mx->mutex == 0) -	    { -	      LeaveCriticalSection(&mx->cs); -	    } -	  else -	    { -	      if (!ReleaseMutex(mx->mutex)) +              EnterCriticalSection( &mx->try_lock_cs ); + +              if( InterlockedDecrement( &mx->lock_idx ) >= 0 )  		{ -		  result = EINVAL; -		  /* -		   * Put things back the way they were. -		   */ -		  mx->lockCount = oldCount; -		  mx->ownerThread = oldOwner; +                  /* Someone is waiting on that mutex */ +                  ReleaseSemaphore( mx->wait_sema, 1, NULL );  		} + +              LeaveCriticalSection( &mx->try_lock_cs );  	    }  	}        else @@ -659,32 +734,28 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)    if (result == 0)      { -      if (mx->mutex == 0) +      /* Try to lock only if mutex seems available */ +      if( PTW32_MUTEX_LOCK_IDX_INIT == mx->lock_idx )  	{ -	  if ((*ptw32_try_enter_critical_section)(&mx->cs) != TRUE) -	    { -	      result = EBUSY; -	    } -	} -      else -	{ -	  DWORD status; +          EnterCriticalSection( &mx->try_lock_cs ); -	  status = WaitForSingleObject (mx->mutex, 0); - -	  if (status != WAIT_OBJECT_0) +          if( 0 == InterlockedIncrement( &mx->lock_idx ) )  	    { -	      result = ((status == WAIT_TIMEOUT) -			? EBUSY -			: EINVAL); +              mx->recursive_count = 1; +              mx->ownerThread = pthread_self();  	    } -	} -    } +          else +            { +              mx->lock_idx--; +              result = EBUSY; +            } -  if (result == 0) -    { -      mx->ownerThread = pthread_self(); -      mx->lockCount++; +          LeaveCriticalSection( &mx->try_lock_cs ); +        } +      else +        { +          result = EBUSY; +        }      }    return(result); diff --git a/nonportable.c b/nonportable.c index 49548dd..e6b6995 100644 --- a/nonportable.c +++ b/nonportable.c @@ -27,27 +27,85 @@  #include "implement.h"  /* - * pthread_mutexattr_setforcecs_np() + * pthread_mutexattr_setkind_np() + */ +int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind) +{ +  return pthread_mutexattr_settype( attr, kind ); +} + +/* + * pthread_mutexattr_getkind_np() + */ +int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind) +{ +  return pthread_mutexattr_gettype( attr, kind ); +} + + +/* + * pthread_mutex_setdefaultkind_np -- + * + * Sets the default type to be given to all + * POSIX mutexes initialised after the function + * is called. Any of the following type values + * can be made the default type: + * + *   PTHREAD_MUTEX_NORMAL + *   PTHREAD_MUTEX_ERRORCHECK + *   PTHREAD_MUTEX_RECURSIVE + *   PTHREAD_MUTEX_DEFAULT + * + * Any mutex initialised with kind PTHREAD_MUTEX_DEFAULT + * will be set to the mapped type instead. Previously + * initialised mutexes are not changed.   * - * Allows an application to force the library to use - * critical sections rather than win32 mutexes as - * the basis for any mutexes that use "attr". + * When set to PTHREAD_MUTEX_DEFAULT (the initial + * value), mutexes will behave as for the + * PTHREAD_MUTEX_RECURSIVE kind.   * - * Values for "forcecs" are defined in pthread.h   */  int -pthread_mutexattr_setforcecs_np(pthread_mutexattr_t *attr, -				int forcecs) +pthread_mutex_setdefaultkind_np (int kind )  { -  if (attr == NULL || *attr == NULL) +  int result = 0; + +  switch (kind)      { -      /* This is disallowed. */ -      return EINVAL; +	case PTHREAD_MUTEX_FAST_NP: +	case PTHREAD_MUTEX_RECURSIVE_NP: +	case PTHREAD_MUTEX_ERRORCHECK_NP: +      ptw32_mutex_default_kind = kind; +      break; +    default: +      result = EINVAL;      } -  (*attr)->forcecs = forcecs; +  return result; +} + +/* + * pthread_mutex_getdefaultkind_np -- + * + * Return the default kind for all mutexes + * + */ +int +pthread_mutex_getdefaultkind_np (int *kind) +{ +  int result = 0; + +  if (kind != NULL) +    { +      *kind = ptw32_mutex_default_kind; +    } -  return 0; +  else +    { +      result = EINVAL; +    } + +  return result;  }  /* @@ -141,75 +199,13 @@ pthread_delay_np (struct timespec * interval)  } -/* - * Handle to kernel32.dll  - */ -static HINSTANCE ptw32_h_kernel32; - -  BOOL  pthread_win32_process_attach_np ()  {    BOOL result = TRUE; -  /* -   * We use this to double-check that TryEnterCriticalSection works. -   */ -  CRITICAL_SECTION cs; -    result = ptw32_processInitialize (); -  /* -   * Load KERNEL32 and try to get address of TryEnterCriticalSection -   */ -  ptw32_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); -  ptw32_try_enter_critical_section = (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION)) - -#if defined(NEED_UNICODE_CONSTS) -  GetProcAddress(ptw32_h_kernel32, -                 (const TCHAR *)TEXT("TryEnterCriticalSection")); -#else -  GetProcAddress(ptw32_h_kernel32, -                 (LPCSTR) "TryEnterCriticalSection"); -#endif - -  if (ptw32_try_enter_critical_section != NULL) -    { -      InitializeCriticalSection(&cs); -      if ((*ptw32_try_enter_critical_section)(&cs)) -        { -          LeaveCriticalSection(&cs); -        } -      else -        { -          /* -           * Not really supported (Win98?). -           */ -          ptw32_try_enter_critical_section = NULL; -        } -      DeleteCriticalSection(&cs); -    } - -  if (ptw32_try_enter_critical_section == NULL) -    { -      /* -       * If TryEnterCriticalSection is not being used, then free -       * the kernel32.dll handle now, rather than leaving it until -       * DLL_PROCESS_DETACH. -       * -       * Note: this is not a pedantic exercise in freeing unused -       * resources!  It is a work-around for a bug in Windows 95 -       * (see microsoft knowledge base article, Q187684) which -       * does Bad Things when FreeLibrary is called within -       * the DLL_PROCESS_DETACH code, in certain situations. -       * Since w95 just happens to be a platform which does not -       * provide TryEnterCriticalSection, the bug will be -       * effortlessly avoided. -       */ -      (void) FreeLibrary(ptw32_h_kernel32); -      ptw32_h_kernel32 = 0; -    } -    return result;  } @@ -235,11 +231,6 @@ pthread_win32_process_detach_np ()         * The DLL is being unmapped into the process's address space         */        ptw32_processTerminate (); - -      if (ptw32_h_kernel32) -        { -           (void) FreeLibrary(ptw32_h_kernel32); -        }      }    return TRUE; @@ -24,12 +24,7 @@   * MA 02111-1307, USA   */ -#if !defined(_MSC_VER) && !defined(__cplusplus) && defined(__GNUC__) - -#warning Compile __FILE__ as C++ or thread cancellation will not work properly. - -#endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ - +#include <process.h>  #ifndef NEED_FTIME  #include <sys/timeb.h>  #endif @@ -154,7 +149,7 @@ ptw32_processTerminate (void)  }				/* processTerminate */ -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH  static DWORD  ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) @@ -194,7 +189,7 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei)      }  } -#elif defined(__cplusplus) +#elif defined(__CLEANUP_CXX)  #if defined(_MSC_VER)  #include <eh.h> @@ -230,20 +225,25 @@ ptw32_terminate ()  #endif /* _MSC_VER */  #if ! defined (__MINGW32__) || defined (__MSVCRT__) -unsigned PT_STDCALL +unsigned __stdcall  #else  void  #endif -ptw32_threadStart (ThreadParms * threadParms) +ptw32_threadStart (void * vthreadParms)  { +  ThreadParms *threadParms = (ThreadParms *) vthreadParms;    pthread_t self;    void *(*start) (void *);    void *arg; -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH    DWORD ei[] = {0,0,0};  #endif +#ifdef __CLEANUP_C +  int setjmp_rc; +#endif +    void * status = (void *) 0;    self = threadParms->tid; @@ -270,7 +270,7 @@ ptw32_threadStart (ThreadParms * threadParms)    pthread_setspecific (ptw32_selfThreadKey, self); -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH    __try    { @@ -295,9 +295,39 @@ ptw32_threadStart (ThreadParms * threadParms)         }    } -#else /* _MSC_VER && !__cplusplus */ +#else /* __CLEANUP_SEH */ -#ifdef __cplusplus +#ifdef __CLEANUP_C + +  setjmp_rc = setjmp( self->start_mark ); + +  if( 0 == setjmp_rc ) { + +	  /* +	   * Run the caller's routine; +	   */ +	  status = self->exitStatus = (*start) (arg); +  } + +  else { + +     switch (setjmp_rc) +       { +        case PTW32_EPS_CANCEL: +          status = PTHREAD_CANCELED; +          break; +        case PTW32_EPS_EXIT: +          status = self->exitStatus; +          break; +        default: +          status = PTHREAD_CANCELED; +          break; +       } +  } + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX    ptw32_oldTerminate = set_terminate(&ptw32_terminate); @@ -328,7 +358,30 @@ ptw32_threadStart (ThreadParms * threadParms)          *           * ptw32_terminate() will be called if there is no user supplied function.          */ -       (void) terminate(); + +       //Original invocation: +       //(void) terminate(); + + +       //New invocation: +       //  a) get pointer to the termination function +#if defined(_MSC_VER) +       terminate_function term_func = set_terminate(0); +#else +       terminate_handler term_func = set_terminate(0); +#endif + +       set_terminate(term_func); + +       //  b) call the termination function (if any) +       if (term_func != 0) { +           term_func(); +       } + +       //  c) if there was no termination function or the termination function did +       //     not exit thread/process, (we got this far), propagate the exception on! +       //     (should be caught by the second level try/catch block below) +       throw;       }    }    catch (ptw32_exception_cancel &) @@ -365,17 +418,14 @@ ptw32_threadStart (ThreadParms * threadParms)    (void) set_terminate(ptw32_oldTerminate); -#else /* __cplusplus */ +#else -  /* -   * Run the caller's routine; no cancelation or other exceptions will -   * be honoured. -   */ -  status = self->exitStatus = (*start) (arg); +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. -#endif /* __cplusplus */ +#endif /* __CLEANUP_CXX */ +#endif /* __CLEANUP_C */ +#endif /* __CLEANUP_SEH */ -#endif /* _MSC_VER */    (void) pthread_mutex_destroy(&self->cancelLock); @@ -637,19 +687,6 @@ ptw32_callUserDestroyRoutines (pthread_t thread)  		  if (value != NULL && k->destructor != NULL)  		    { -#if defined(_MSC_VER) && !defined(__cplusplus) - -			/* -			 * Run the caller's cleanup routine. -			 * -			 * If an exception occurs we let the system handle it -			 * as an unhandled exception. Since we are leaving the -			 * thread we should not get any internal pthreads -			 * exceptions. -			 */ -			(*(k->destructor)) (value); - -#else  /* _MSC_VER && !__cplusplus */  #ifdef __cplusplus  		      try @@ -681,7 +718,6 @@ ptw32_callUserDestroyRoutines (pthread_t thread)  			(*(k->destructor)) (value);  #endif /* __cplusplus */ -#endif /* _MSC_VER */  		    }  		} @@ -895,7 +931,7 @@ ptw32_sem_timedwait (sem_t * sem, const struct timespec * abstime)  DWORD  ptw32_get_exception_services_code(void)  { -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH    return EXCEPTION_PTW32_SERVICES; @@ -910,10 +946,13 @@ ptw32_get_exception_services_code(void)  void  ptw32_throw(DWORD exception)  { -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_C +  pthread_t self = pthread_self(); +#endif -  DWORD exceptionInformation[3]; +#ifdef __CLEANUP_SEH +  DWORD exceptionInformation[3];  #endif    if (exception != PTW32_EPS_CANCEL && @@ -923,7 +962,8 @@ ptw32_throw(DWORD exception)        exit(1);      } -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH +    exceptionInformation[0] = (DWORD) (exception);    exceptionInformation[1] = (DWORD) (0); @@ -935,9 +975,17 @@ ptw32_throw(DWORD exception)  		  3,  		  exceptionInformation); -#else /* _MSC_VER && ! __cplusplus */ +#else /* __CLEANUP_SEH */ + +#ifdef __CLEANUP_C -# ifdef __cplusplus +  ptw32_pop_cleanup_all( 1 ); + +  longjmp( self->start_mark, exception ); + +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX    switch (exception)      { @@ -949,9 +997,22 @@ ptw32_throw(DWORD exception)        break;      } -# endif /* __cplusplus */ +#else -#endif /* _MSC_VER && ! __cplusplus */ +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */    /* Never reached */  } + +void +ptw32_pop_cleanup_all(int execute) +{ +	while( NULL != ptw32_pop_cleanup(execute) ) { +	} +} diff --git a/pthread.def b/pthread.def index 9371ce9..623dc17 100644 --- a/pthread.def +++ b/pthread.def @@ -1,5 +1,5 @@  ; pthread.def
 -; Last updated: $Date: 2000/12/28 05:32:07 $
 +; Last updated: $Date: 2001/05/31 02:01:47 $
  ; Currently unimplemented functions are commented out.
 @@ -13,7 +13,7 @@ pthread_attr_getdetachstate  ;pthread_attr_getinheritsched
  pthread_attr_getschedparam
  ;pthread_attr_getschedpolicy
 -;pthread_attr_getscope
 +pthread_attr_getscope
  pthread_attr_getstackaddr
  pthread_attr_getstacksize
  pthread_attr_init
 @@ -21,12 +21,12 @@ pthread_attr_setdetachstate  ;pthread_attr_setinheritsched
  pthread_attr_setschedparam
  ;pthread_attr_setschedpolicy
 -;pthread_attr_setscope
 +pthread_attr_setscope
  pthread_attr_setstackaddr
  pthread_attr_setstacksize
  pthread_cancel
  ;
 -; These are implemented as macros
 +; These two are implemented as macros
  ;
  ;pthread_cleanup_pop
  ;pthread_cleanup_push
 @@ -45,6 +45,7 @@ pthread_create  pthread_detach
  pthread_equal
  pthread_exit
 +pthread_getconcurrency
  pthread_getschedparam
  pthread_getspecific
  pthread_join
 @@ -55,10 +56,12 @@ pthread_mutexattr_destroy  ;pthread_mutexattr_getprioceiling
  ;pthread_mutexattr_getprotocol
  pthread_mutexattr_getpshared
 +pthread_mutexattr_gettype
  pthread_mutexattr_init
  ;pthread_mutexattr_setprioceiling
  ;pthread_mutexattr_setprotocol
  pthread_mutexattr_setpshared
 +pthread_mutexattr_settype
  pthread_mutexattr_destroy
  pthread_mutex_init
  pthread_mutex_destroy
 @@ -69,6 +72,7 @@ pthread_once  pthread_self
  pthread_setcancelstate
  pthread_setcanceltype
 +pthread_setconcurrency
  pthread_setschedparam
  pthread_setspecific
  ;pthread_sigmask
 @@ -101,7 +105,6 @@ pthread_rwlock_unlock  ;
  ; Non-portable but useful
  ;
 -pthread_mutexattr_setforcecs_np
  pthread_getw32threadhandle_np
  pthread_delay_np
  pthreadCancelableWait
 @@ -114,8 +117,8 @@ pthread_win32_thread_detach_np  ;
  ; Needed if !defined(_MSC_VER) && !defined(__cplusplus)
  ;
 -pthread_push_cleanup
 -pthread_pop_cleanup
 +ptw32_push_cleanup
 +ptw32_pop_cleanup
  ;
  ; Not for use directly. Needed by macros in pthread.h
  ; to return internal SEH code.
 @@ -34,176 +34,61 @@   *   *              POSIX 1003.1c-1995      (POSIX.1c)   * - * Authors: - *      Contributors are listed in the file "MAINTAINERS". - * - * The following functions are implemented: - *      --------------------------- - *      PThreads - *      --------------------------- - *      pthread_attr_init - *      pthread_attr_destroy - *      pthread_attr_getdetachstate - *      pthread_attr_getstackaddr - *      pthread_attr_getstacksize - *      pthread_attr_setdetachstate      - *      pthread_attr_setstackaddr - *      pthread_attr_setstacksize - * - *      pthread_create - *      pthread_detach - *      pthread_equal - *      pthread_exit - *      pthread_join - *      pthread_self - *      sched_yield - * - *      pthread_cancel - *      pthread_cleanup_pop - *      pthread_cleanup_push - *      pthread_setcancelstate - *      pthread_setcanceltype - *      pthread_testcancel - * - *      --------------------------- - *      Thread Specific Data - *      --------------------------- - *      pthread_key_create - *      pthread_key_delete - *      pthread_setspecific - *      pthread_getspecific - * - *      --------------------------- - *      Mutexes - *      --------------------------- - *      pthread_mutexattr_init - *      pthread_mutexattr_destroy - *      pthread_mutexattr_getpshared - *      pthread_mutexattr_setpshared - * - *      pthread_mutex_init - *      pthread_mutex_destroy - *      pthread_mutex_lock - *      pthread_mutex_trylock - *      pthread_mutex_unlock - * - *      --------------------------- - *      Condition Variables - *      --------------------------- - *      pthread_condattr_init - *      pthread_condattr_destroy - *      pthread_condattr_getpshared - *      pthread_condattr_setpshared - * - *      pthread_cond_init - *      pthread_cond_destroy - *      pthread_cond_wait - *      pthread_cond_timedwait - *      pthread_cond_signal - *      pthread_cond_broadcast - * - *      --------------------------- - *      Protected Methods - *      --------------------------- - *      pthreadCancelableWait - * - *      --------------------------- - *      RealTime Scheduling: - *      --------------------------- - *      pthread_attr_getschedparam - *      pthread_attr_setschedparam - *      pthread_getschedparam - *      pthread_setschedparam - *      sched_get_priority_max - *      sched_get_priority_min - * - *      --------------------------- - *      Signals: - *      --------------------------- - *      pthread_sigmask - * - *      --------------------------- - *      Read/Write Locks: - *      --------------------------- - *      pthread_rwlock_init - *      pthread_rwlock_destroy - *      pthread_rwlock_tryrdlock - *      pthread_rwlock_trywrlock - *      pthread_rwlock_rdlock - *      pthread_rwlock_rwlock - *      pthread_rwlock_unlock - * - * Limitations - * =========== - *      The following functions are not implemented: - * - *      --------------------------- - *      RealTime Scheduling: - *      --------------------------- - *      pthread_attr_getinheritsched - *      pthread_attr_getschedpolicy - *      pthread_attr_getscope - *      pthread_attr_setinheritsched - *      pthread_attr_setschedpolicy - *      pthread_attr_setscope - *      pthread_mutex_getprioceiling - *      pthread_mutex_setprioceiling - *      pthread_mutex_attr_getprioceiling - *      pthread_mutex_attr_getprotocol - *      pthread_mutex_attr_setprioceiling - *      pthread_mutex_attr_setprotocol - * - *      --------------------------- - *      Fork Handlers: - *      --------------------------- - *      pthread_atfork - * - *      --------------------------- - *      Stdio: - *      --------------------------- - *      flockfile - *      ftrylockfile - *      funlockfile - *      getc_unlocked - *      getchar_unlocked - *      putc_unlocked - *      putchar_unlocked - * - *      --------------------------- - *      Thread-Safe C Runtime Library: - *      --------------------------- - *      readdir_r - *      getgrgid_r - *      getgrnam_r - *      getpwuid_r - *      getpwnam_r - * - *      --------------------------- - *      Signals: - *      --------------------------- - *      pthread_kill - *      sigtimedwait - *      sigwait - *      sigwaitinfo + *	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.   * + * Authors: + *	There have been many contributors to this library. + *	The initial implementation was contributed by + *	John Bossom, and several others have provided major + *	sections or revisions of parts of the implementation. + *	Often significant effort has been contributed to + *	find and fix important bugs and other problems to + *	improve the reliability of the library, which sometimes + *	is not reflected in the amount of code which changed as + *	result. + *	As much as possible, the contributors are acknowledged + *	in the ChangeLog file in the source code distribution + *	where their changes are noted in detail. + * + *      Contributors are listed in the MAINTAINERS file. + * + *	As usual, all bouquets go to the contributors, and all + *	brickbats go to the project maintainer. + * + * Maintainer: + *	The code base for this project is coordinated and + *	eventually pre-tested, packaged, and made available by + * + *		Ross Johnson <rpj@ise.canberra.edu.au> + * + * QA Testers: + *	Ultimately, the library is tested in the real world by + *	a host of competent and demanding scientists and + *	engineers who report bugs and/or provide solutions + *	which are then fixed or incorporated into subsequent + *	versions of the library. Each time a bug is fixed, a + *	test case is written to prove the fix and ensure + *	that later changes to the code don't reintroduce the + *	same error. The number of test cases is slowly growing + *	and therefore so is the code reliability. + * + * Compliance: + *	See the file ANNOUNCE for the list of implemented + *	and not-implemented routines and defined options. + *	Of course, these are all defined is this file as well. + * + * Web site: + *	The source code and other information about this library + *	are available from + * + *		http://sources.redhat.com/pthreads-win32/   *   * -------------------------------------------------------------   */ -#ifdef _MSC_VER -/* - * Disable following warnings when including Windows headers - * - * warning C4115: named type definition in parentheses - * warning C4116: unnamed type definition in parentheses - * warning C4127: conditional expression is constant - * warning C4201: nonstandard extension used : nameless struct/union - * warning C4214: nonstandard extension used : bit field types other than int - * warning C4514: unreferenced inline function has been removed - */ -#pragma warning( disable : 4115 4116 4127 4201 4214 4514) -#endif -  /*   * -----------------   * autoconf switches @@ -226,7 +111,7 @@  #include <signal.h>  #endif /* HAVE_SIGNAL_H */ -#include <malloc.h> +#include <setjmp.h>  #ifndef HAVE_STRUCT_TIMESPEC  struct timespec { @@ -247,8 +132,6 @@ struct timespec {  #define SIG_SETMASK 2  #endif /* SIG_SETMASK */ -#include <process.h> -  /*   * note: ETIMEDOUT is correctly defined in winsock.h   */ @@ -267,28 +150,6 @@ struct timespec {  #define ETIMEDOUT 10060     /* This is the value in winsock.h. */  #endif -#ifdef __MINGW32__ -#define PT_STDCALL -#else -#ifdef __cplusplus -#define PT_STDCALL __stdcall -#else -#define PT_STDCALL __stdcall -#endif -#endif - -#ifdef _MSC_VER -/* - * Re-enable all but 4127, 4514 - */ -#pragma warning( default : 4115 4116 4201 4214) -#endif - -#if !defined( TRUE ) -#define TRUE	!FALSE -#define FALSE	0 -#endif /* !TRUE */ -  #ifdef __cplusplus  extern "C"  { @@ -495,12 +356,6 @@ typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t;  #define PTHREAD_PROCESS_SHARED		1  /* - * pthread_mutexattr_setforcecs_np - */ -#define PTHREAD_MUTEX_AUTO_CS_NP        0 -#define PTHREAD_MUTEX_FORCE_CS_NP       1 - -/*   * ====================   * ====================   * Cancelation @@ -533,6 +388,17 @@ struct pthread_once_t_  #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) +enum +{ +  PTHREAD_MUTEX_FAST_NP, +  PTHREAD_MUTEX_RECURSIVE_NP, +  PTHREAD_MUTEX_ERRORCHECK_NP, +  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, +  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, +  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, +  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; +  /*   * ==================== @@ -581,18 +447,36 @@ struct sched_param {   * C++ and C built versions will not.   */ +/*  + * define defaults for cleanup code + */ +#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 + +#endif + +#if defined( __CLEANUP_SEH ) && defined(__GNUC__) +#error ERROR [__FILE__, line __LINE__]: GNUC does not support SEH. +#endif +  typedef struct ptw32_cleanup_t ptw32_cleanup_t; +typedef void (__cdecl *ptw32_cleanup_callback_t)(void *);  struct ptw32_cleanup_t  { -  void (*routine) (void *); +  ptw32_cleanup_callback_t routine;    void *arg; -#if !defined(_MSC_VER) && !defined(__cplusplus) -  ptw32_leanup_t *prev; -#endif /* !_MSC_VER && ! __cplusplus */ +  struct ptw32_cleanup_t *prev;  }; -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH  	/*  	 * WIN32 SEH version of cancel cleanup.  	 */ @@ -601,7 +485,7 @@ struct ptw32_cleanup_t  	{ \  	    ptw32_cleanup_t	_cleanup; \  	    \ -            _cleanup.routine	= (_rout); \ +        _cleanup.routine	= (ptw32_cleanup_callback_t)(_rout); \  	    _cleanup.arg	= (_arg); \  	    __try \  	      { \ @@ -617,9 +501,9 @@ struct ptw32_cleanup_t  		} \  	} -#else /* _MSC_VER && ! __cplusplus */ +#else /* __CLEANUP_SEH */ -#ifndef __cplusplus +#ifdef __CLEANUP_C  	/*  	 * C implementation of PThreads cancel cleanup @@ -629,13 +513,15 @@ struct ptw32_cleanup_t  	{ \  	    ptw32_cleanup_t	_cleanup; \              \ -	    pthread_push_cleanup( &_cleanup, (_rout), (_arg) ); \ +	    ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \  #define pthread_cleanup_pop( _execute ) \ -	    (void) pthread_pop_cleanup( _execute ); \ +	    (void) ptw32_pop_cleanup( _execute ); \  	} -#else /* !__cplusplus */ +#else /* __CLEANUP_C */ + +#ifdef __CLEANUP_CXX  	/*  	 * C++ version of cancel cleanup. @@ -655,7 +541,7 @@ struct ptw32_cleanup_t  	   *      of how the code exits the scope  	   *      (i.e. such as by an exception)  	   */ -	  void            (PT_STDCALL *cleanUpRout)( void * ); +      ptw32_cleanup_callback_t cleanUpRout;  	  void    *       obj;  	  int             executeIt; @@ -671,7 +557,7 @@ struct ptw32_cleanup_t  	    }  	  PThreadCleanup( -			 void            (PT_STDCALL *routine)( void * ), +             ptw32_cleanup_callback_t routine,  			 void    *       arg ) :  	    cleanUpRout( routine ),  	    obj( arg ), @@ -704,16 +590,22 @@ struct ptw32_cleanup_t  	 */  #define pthread_cleanup_push( _rout, _arg ) \          { \ -	    PThreadCleanup  cleanup((void (PT_STDCALL *)(void *))(_rout), \ +	    PThreadCleanup  cleanup((ptw32_cleanup_callback_t)(_rout), \  				    (void *) (_arg) );  #define pthread_cleanup_pop( _execute ) \  	    cleanup.execute( _execute ); \  	} -#endif /* !__cplusplus) */ +#else -#endif /* _MSC_VER && ! __cplusplus */ +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */  /*   * =============== @@ -748,6 +640,18 @@ int pthread_attr_setstackaddr (pthread_attr_t * attr,  int pthread_attr_setstacksize (pthread_attr_t * attr,  			       size_t stacksize); +int pthread_attr_getschedparam (const pthread_attr_t *attr, +                                struct sched_param *param); +  +int pthread_attr_setschedparam (pthread_attr_t *attr, +                                const struct sched_param *param); + +int pthread_attr_setscope (pthread_attr_t *, +                           int); +  +int pthread_attr_getscope (const pthread_attr_t *, +                           int *); +  /*   * PThread Functions   */ @@ -781,9 +685,9 @@ void pthread_testcancel (void);  int pthread_once (pthread_once_t * once_control,  		  void (*init_routine) (void)); -ptw32_cleanup_t *pthread_pop_cleanup (int execute); +ptw32_cleanup_t *ptw32_pop_cleanup (int execute); -void pthread_push_cleanup (ptw32_cleanup_t * cleanup, +void ptw32_push_cleanup (ptw32_cleanup_t * cleanup,  			   void (*routine) (void *),  			   void *arg); @@ -815,6 +719,9 @@ int pthread_mutexattr_getpshared (const pthread_mutexattr_t  int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,  				  int pshared); +int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +int pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); +  /*   * Mutex Functions   */ @@ -872,11 +779,9 @@ int pthread_getschedparam (pthread_t thread,  			   int *policy,  			   struct sched_param *param); -int pthread_attr_getschedparam (const pthread_attr_t *attr, -				struct sched_param *param); - -int pthread_attr_setschedparam (pthread_attr_t *attr, -				const struct sched_param *param); +int pthread_setconcurrency (int); +  +int pthread_getconcurrency (void);  /*   * Read-Write Lock Functions @@ -901,12 +806,19 @@ int pthread_rwlock_unlock(pthread_rwlock_t *lock);   * Non-portable functions   */ -/* Possibly supported by other POSIX threads implimentations */ -int pthread_delay_np (struct timespec * interval); +int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, int kind); +int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, int *kind); -/* Pthread Win32 specific */ -int pthread_mutexattr_setforcecs_np(pthread_mutexattr_t *attr, -				    int forcecs); +/* + * Remaps the default mutex kind to any of the + * other possible types. Returns the previous type. + */ +int pthread_mutex_setdefaultkind_np(int kind); +int pthread_mutex_getdefaultkind_np(int *kind); + + +/* Possibly supported by other POSIX threads implementations */ +int pthread_delay_np (struct timespec * interval);  HANDLE pthread_getw32threadhandle_np(pthread_t thread); @@ -942,7 +854,7 @@ int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);   * Thread-Safe C Runtime Library Mappings.   */  #if 1 -#if (! defined(NEED_ERRNO)) || (! defined( _REENTRANT ) && (! defined( _MT ) || ! defined( _MD ))) +#if (! defined(HAVE_ERRNO)) && (! defined(_REENTRANT)) && (! defined(_MT))  int * _errno( void );  #endif  #else @@ -986,7 +898,7 @@ int * _errno( void );  	  (_result) )  #define rand_r( _seed ) \ -	rand() +	( _seed == _seed? rand() : rand() )  #ifdef __cplusplus @@ -1008,7 +920,7 @@ DWORD ptw32_get_exception_services_code(void);  #ifndef PTW32_BUILD -#if defined(_MSC_VER) && !defined(__cplusplus) +#ifdef __CLEANUP_SEH  /*   * Redefine the SEH __except keyword to ensure that applications @@ -1018,7 +930,7 @@ DWORD ptw32_get_exception_services_code(void);          __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \  		 ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) -#endif /* _MSC_VER && ! __cplusplus */ +#endif /* __CLEANUP_SEH */  #ifdef __cplusplus @@ -24,6 +24,7 @@   */  #include <errno.h> +#include <limits.h>  #include "pthread.h"  #include "implement.h" @@ -80,120 +81,140 @@ ptw32_rwlock_check_need_init(pthread_rwlock_t *rwlock)    LeaveCriticalSection(&ptw32_rwlock_test_init_lock); -  return(result); +  return result;  }  int  pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)  { -    int result = 0; -    pthread_rwlock_t rw; +    int result; +    pthread_rwlock_t rwl = 0;      if (rwlock == NULL)        {          return EINVAL;        } -    rw = (pthread_rwlock_t) calloc(1, sizeof(*rw)); +    if (attr != NULL && *attr != NULL) +      { +        result = EINVAL; /* Not supported */ +        goto DONE; +      } + +    rwl = (pthread_rwlock_t) calloc(1, sizeof(*rwl)); -    if (rw == NULL) +    if (rwl == NULL)        {          result = ENOMEM; -        goto FAIL0; +        goto DONE;        } -    if (attr != NULL -        && *attr != NULL) +    rwl->nSharedAccessCount = 0; +    rwl->nExclusiveAccessCount = 0; +    rwl->nCompletedSharedAccessCount = 0; + +    result = pthread_mutex_init(&rwl->mtxExclusiveAccess, NULL); +    if (result != 0)        { -        result = EINVAL; /* Not supported */          goto FAIL0;        } -    if ((result = pthread_mutex_init(&(rw->rw_lock), NULL)) != 0) +    result = pthread_mutex_init(&rwl->mtxSharedAccessCompleted, NULL); +    if (result != 0)        {          goto FAIL1;        } -    if ((result = pthread_cond_init(&(rw->rw_condreaders), NULL)) != 0) +    result = pthread_cond_init(&rwl->cndSharedAccessCompleted, NULL); +    if (result != 0)        {          goto FAIL2;        } -    if ((result = pthread_cond_init(&(rw->rw_condwriters), NULL)) != 0) -      { -        goto FAIL3; -      } - -    rw->rw_nwaitreaders = 0; -    rw->rw_nwaitwriters = 0; -    rw->rw_refcount = 0; -    rw->rw_magic = RW_MAGIC; +    rwl->nMagic = PTW32_RWLOCK_MAGIC;      result = 0; -    goto FAIL0; - -FAIL3: -    (void) pthread_cond_destroy(&(rw->rw_condreaders)); +    goto DONE;  FAIL2: -    (void) pthread_mutex_destroy(&(rw->rw_lock)); +    (void) pthread_mutex_destroy(&(rwl->mtxSharedAccessCompleted));  FAIL1: +    (void) pthread_mutex_destroy(&(rwl->mtxExclusiveAccess)); +  FAIL0: -    *rwlock = rw; +    (void) free(rwl); +    rwl = NULL; + +DONE: +    *rwlock = rwl; -    return(result); +    return result;  }  int  pthread_rwlock_destroy(pthread_rwlock_t *rwlock)  { -    pthread_rwlock_t rw; -    int result = 0; +    pthread_rwlock_t rwl; +    int result = 0, result1 = 0, result2 = 0;      if (rwlock == NULL || *rwlock == NULL)        { -        return(EINVAL); +        return EINVAL;        }      if (*rwlock != (pthread_rwlock_t) PTW32_OBJECT_AUTO_INIT)        { -        rw = *rwlock; +        rwl = *rwlock; -        if (pthread_mutex_lock(&(rw->rw_lock)) != 0) +        if (rwl->nMagic != PTW32_RWLOCK_MAGIC)            { -            return(EINVAL); +            return EINVAL;            } -        if (rw->rw_magic != RW_MAGIC) +        if ((result = pthread_mutex_lock(&(rwl->mtxExclusiveAccess))) != 0)            { -            (void) pthread_mutex_unlock(&(rw->rw_lock)); -            return(EINVAL); +            return result;            } -        if (rw->rw_refcount != 0 -            || rw->rw_nwaitreaders != 0 -            || rw->rw_nwaitwriters != 0) +        if ((result = pthread_mutex_lock(&(rwl->mtxSharedAccessCompleted))) != 0)            { -            (void) pthread_mutex_unlock(&(rw->rw_lock)); -            result = EBUSY; +            (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +            return result;            } -        else -          { -            /* -             * Need to NULL this before we start freeing up -             * and destroying it's components. -             */ -            *rwlock = NULL; -            rw->rw_magic = 0; -            (void) pthread_mutex_unlock(&(rw->rw_lock)); - -            (void) pthread_cond_destroy(&(rw->rw_condreaders)); -            (void) pthread_cond_destroy(&(rw->rw_condwriters)); -            (void) pthread_mutex_destroy(&(rw->rw_lock)); -            free(rw); -           } +        /* +         * Check whether any threads own/wait for the lock (wait for ex.access); +         * report "BUSY" if so. +         */ +        if (rwl->nExclusiveAccessCount > 0 +            || rwl->nSharedAccessCount > rwl->nCompletedSharedAccessCount) +          { +            result = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted)); +            result1 = pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +            result2 = EBUSY; +          } +        else  +          { +            rwl->nMagic = 0; + +            if ((result = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted))) != 0) +              { +                pthread_mutex_unlock(&rwl->mtxExclusiveAccess); +                return result; +              } + +            if ((result = pthread_mutex_unlock(&(rwl->mtxExclusiveAccess))) != 0) +              { +                return result; +              } + +            *rwlock = NULL; /* Invalidate rwlock before anything else */ +            result = pthread_cond_destroy(&(rwl->cndSharedAccessCompleted)); +            result1 = pthread_mutex_destroy(&(rwl->mtxSharedAccessCompleted)); +            result2 = pthread_mutex_destroy(&(rwl->mtxExclusiveAccess)); +            (void) free(rwl); +          }        }      else        { @@ -227,28 +248,18 @@ pthread_rwlock_destroy(pthread_rwlock_t *rwlock)          LeaveCriticalSection(&ptw32_rwlock_test_init_lock);        } -    return(result); -} - -static void -_rwlock_cancelrdwait(void * arg) -{ -    pthread_rwlock_t rw; - -    rw = (pthread_rwlock_t) arg; -    rw->rw_nwaitreaders--; -    pthread_mutex_unlock(&(rw->rw_lock)); +    return ((result != 0) ? result : ((result1 != 0) ? result1 : result2));  }  int  pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)  { -    int result = 0; -    pthread_rwlock_t rw; +    int result; +    pthread_rwlock_t rwl;      if (rwlock == NULL || *rwlock == NULL)        { -        return(EINVAL); +        return EINVAL;        }      /* @@ -263,70 +274,64 @@ pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)          if (result != 0 && result != EBUSY)            { -            return(result); +            return result;            }        } -    rw = *rwlock; +    rwl = *rwlock; -    if ((result = pthread_mutex_lock(&(rw->rw_lock))) != 0) +    if (rwl->nMagic != PTW32_RWLOCK_MAGIC)        { -        return(result); +        return EINVAL;        } -    if (rw->rw_magic != RW_MAGIC) +    if ((result = pthread_mutex_lock(&(rwl->mtxExclusiveAccess))) != 0)        { -        result = EINVAL; -        goto FAIL1; +        return result;        } -    /* -     * Give preference to waiting writers -     */ -    while (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0) +    if (++rwl->nSharedAccessCount == INT_MAX)        { -        rw->rw_nwaitreaders++; -        pthread_cleanup_push(_rwlock_cancelrdwait, rw); -        result = pthread_cond_wait(&(rw->rw_condreaders), &(rw->rw_lock)); -        pthread_cleanup_pop(0); -        rw->rw_nwaitreaders--; - -        if (result != 0) +        if ((result = pthread_mutex_lock(&(rwl->mtxSharedAccessCompleted))) != 0)            { -            break; +            (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +            return result;            } -      } -    if (result == 0) -      { -        rw->rw_refcount++; /* another reader has a read lock */ -      } +        rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; +        rwl->nCompletedSharedAccessCount = 0; -FAIL1: -    (void) pthread_mutex_unlock(&(rw->rw_lock)); +        if ((result = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted))) != 0) +          { +            (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +            return result; +          } +      } -    return(result); +    return (pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)));  }  static void -_rwlock_cancelwrwait(void * arg) +ptw32_rwlock_cancelwrwait(void * arg)  { -    pthread_rwlock_t rw; +    pthread_rwlock_t rwl = (pthread_rwlock_t) arg; -    rw = (pthread_rwlock_t) arg; -    rw->rw_nwaitwriters--; -    (void) pthread_mutex_unlock(&(rw->rw_lock)); +    rwl->nSharedAccessCount = -rwl->nCompletedSharedAccessCount; +    rwl->nCompletedSharedAccessCount = 0; + +    (void) pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted)); +    (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess));  }  int  pthread_rwlock_wrlock(pthread_rwlock_t * rwlock)  {      int result; -    pthread_rwlock_t rw; +    pthread_rwlock_t rwl;      if (rwlock == NULL || *rwlock == NULL)        { -        return(EINVAL); +        return EINVAL;        }      /* @@ -341,51 +346,71 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock)          if (result != 0 && result != EBUSY)            { -            return(result); +            return result;            }        } -    rw = *rwlock; +    rwl = *rwlock; -    if (rw->rw_magic != RW_MAGIC) +    if (rwl->nMagic != PTW32_RWLOCK_MAGIC)        { -        return(EINVAL); +        return EINVAL; +      } + +    if ((result = pthread_mutex_lock(&(rwl->mtxExclusiveAccess))) != 0) +      { +        return result;        } -    if ((result = pthread_mutex_lock(&(rw->rw_lock))) != 0) +    if ((result = pthread_mutex_lock(&(rwl->mtxSharedAccessCompleted))) != 0)        { -        return(result); +        (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +        return result;        } -    while (rw->rw_refcount != 0) +    if (rwl->nExclusiveAccessCount == 0)         { -        rw->rw_nwaitwriters++; -        pthread_cleanup_push(_rwlock_cancelwrwait, rw); -        result = pthread_cond_wait(&(rw->rw_condwriters), &(rw->rw_lock)); -        pthread_cleanup_pop(0); -        rw->rw_nwaitwriters--; +        if (rwl->nCompletedSharedAccessCount > 0)  +          { +            rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; +            rwl->nCompletedSharedAccessCount = 0; +          } -        if (result != 0) +        if (rwl->nSharedAccessCount > 0)             { -            break; +            rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; + +            pthread_cleanup_push(ptw32_rwlock_cancelwrwait, (void*)rwl); + +            do  +              { +                result = pthread_cond_wait(&(rwl->cndSharedAccessCompleted),  +                                           &(rwl->mtxSharedAccessCompleted)); +              } +            while (result == 0 && rwl->nCompletedSharedAccessCount < 0); + +            pthread_cleanup_pop ((result != 0) ? 1 : 0); + +            if (result == 0) +              { +                rwl->nSharedAccessCount = 0; +              }            }        }      if (result == 0)        { -        rw->rw_refcount = -1; +        rwl->nExclusiveAccessCount++;        } -    (void) pthread_mutex_unlock(&(rw->rw_lock)); - -    return(result); +    return result;  }  int  pthread_rwlock_unlock(pthread_rwlock_t * rwlock)  { -    int result = 0; -    pthread_rwlock_t rw; +    int result, result1; +    pthread_rwlock_t rwl;      if (rwlock == NULL || *rwlock == NULL)        { @@ -397,67 +422,51 @@ pthread_rwlock_unlock(pthread_rwlock_t * rwlock)          /*           * Assume any race condition here is harmless.           */ -        return(0); +        return 0;        } -    rw = *rwlock; - -    if ((result = pthread_mutex_lock(&(rw->rw_lock))) != 0) -      { -        return(result); -      } +    rwl = *rwlock; -    if (rw->rw_magic != RW_MAGIC) +    if (rwl->nMagic != PTW32_RWLOCK_MAGIC)        { -        result = EINVAL; -        goto FAIL1; +        return EINVAL;        } -    if (rw->rw_refcount > 0) -      { -        rw->rw_refcount--;             /* releasing a reader */ -      } -    else if (rw->rw_refcount == -1) +    if (rwl->nExclusiveAccessCount == 0)         { -        rw->rw_refcount = 0;           /* releasing a writer */ -      } -    else  -      { -        return(EINVAL); -      } - -    result = 0; +        if ((result = pthread_mutex_lock(&(rwl->mtxSharedAccessCompleted))) != 0) +          { +            return result; +          } -    /* -     * Give preference to waiting writers over waiting readers -     */ -    if (rw->rw_nwaitwriters > 0) -      { -        if (rw->rw_refcount == 0) +        if (++rwl->nCompletedSharedAccessCount == 0)            { -            result = pthread_cond_signal(&(rw->rw_condwriters)); +            result = pthread_cond_signal(&(rwl->cndSharedAccessCompleted));            } + +        result1 = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted));        } -    else if (rw->rw_nwaitreaders > 0) +    else         { -         result = pthread_cond_broadcast(&(rw->rw_condreaders)); -      } +        rwl->nExclusiveAccessCount--; -FAIL1: -    (void) pthread_mutex_unlock(&(rw->rw_lock)); +        result = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted)); +        result1 = pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); -    return(result); -} +      } +    return ((result != 0) ? result : result1); +} +  int  pthread_rwlock_tryrdlock(pthread_rwlock_t * rwlock)  { -    int result = 0; -    pthread_rwlock_t rw; +    int result; +    pthread_rwlock_t rwl;      if (rwlock == NULL || *rwlock == NULL)        { -        return(EINVAL); +        return EINVAL;        }      /* @@ -472,47 +481,52 @@ pthread_rwlock_tryrdlock(pthread_rwlock_t * rwlock)          if (result != 0 && result != EBUSY)            { -            return(result); +            return result;            }        } -    rw = *rwlock; +    rwl = *rwlock; -    if ((result = pthread_mutex_lock(&(rw->rw_lock))) != 0) +    if (rwl->nMagic != PTW32_RWLOCK_MAGIC)        { -        return(result); +        return EINVAL;        } -    if (rw->rw_magic != RW_MAGIC) +    if ((result = pthread_mutex_trylock(&(rwl->mtxExclusiveAccess))) != 0)        { -        result = EINVAL; -        goto FAIL1; +        return result;        } -    if (rw->rw_refcount == -1 || rw->rw_nwaitwriters > 0) -      { -        result = EBUSY;    /* held by a writer or waiting writers */ -      } -    else +    if (++rwl->nSharedAccessCount == INT_MAX)         { -        rw->rw_refcount++; /* increment count of reader locks */ -      } +        if ((result = pthread_mutex_lock(&(rwl->mtxSharedAccessCompleted))) != 0) +          { +            (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +            return result; +          } -FAIL1: -    (void) pthread_mutex_unlock(&(rw->rw_lock)); +        rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; +        rwl->nCompletedSharedAccessCount = 0; -    return(result); +        if ((result = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted))) != 0) +          { +            (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +            return result; +          } +      } + +    return (pthread_mutex_unlock(&rwl->mtxExclusiveAccess));  }  int  pthread_rwlock_trywrlock(pthread_rwlock_t * rwlock)  { -    int result = 0; -    pthread_rwlock_t rw; +    int result, result1; +    pthread_rwlock_t rwl;      if (rwlock == NULL || *rwlock == NULL)        { -        return(EINVAL); +        return EINVAL;        }      /* @@ -527,34 +541,58 @@ pthread_rwlock_trywrlock(pthread_rwlock_t * rwlock)          if (result != 0 && result != EBUSY)            { -            return(result); +            return result;            }        } -    rw = *rwlock; +    rwl = *rwlock; -    if ((result = pthread_mutex_lock(&(rw->rw_lock))) != 0) +    if (rwl->nMagic != PTW32_RWLOCK_MAGIC)        { -        return(result); +        return EINVAL;        } -    if (rw->rw_magic != RW_MAGIC) +    if ((result = pthread_mutex_trylock(&(rwl->mtxExclusiveAccess))) != 0)        { -        result = EINVAL; -        goto FAIL1; +        return result;        } -    if (rw->rw_refcount != 0) +    if ((result = pthread_mutex_trylock(&(rwl->mtxSharedAccessCompleted))) != 0)        { -        result = EBUSY;       /* held by either writer or reader(s) */ +        result1 = pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +        return ((result1 != 0) ? result1 : result);        } -    else + +    if (rwl->nExclusiveAccessCount == 0)         { -        rw->rw_refcount = -1; /* available, indicate a writer has it */ -      } +        if (rwl->nCompletedSharedAccessCount > 0)  +          { +            rwl->nSharedAccessCount -= rwl->nCompletedSharedAccessCount; +            rwl->nCompletedSharedAccessCount = 0; +          } -FAIL1: -    (void) pthread_mutex_unlock(&(rw->rw_lock)); +        if (rwl->nSharedAccessCount > 0)  +          { +            if ((result = pthread_mutex_unlock(&(rwl->mtxSharedAccessCompleted))) != 0) +              { +                (void) pthread_mutex_unlock(&(rwl->mtxExclusiveAccess)); +                return result; +              } + +            if ((result = pthread_mutex_unlock(&(rwl->mtxExclusiveAccess))) == 0) +              { +                result = EBUSY; +              } +          } +        else +          { +            rwl->nExclusiveAccessCount = 1; +          } +      } +    else  +      { +        result = EBUSY; +      } -    return(result); +    return result;  } @@ -28,31 +28,6 @@  #ifndef _SCHED_H  #define _SCHED_H -#ifdef _MSC_VER -/* - * Disable following warnings when including Windows headers - * - * warning C4115: named type definition in parentheses - * warning C4116: unnamed type definition in parentheses - * warning C4127: conditional expression is constant - * warning C4201: nonstandard extension used : nameless struct/union - * warning C4214: nonstandard extension used : bit field types other than int - * warning C4514: unreferenced inline function has been removed - */ -#pragma warning( disable : 4115 4116 4127 4201 4214 4514) -#endif - -#include <windows.h> -//#include <process.h> -//#include <errno.h> - -#ifdef _MSC_VER -/* - * Re-enable all but 4127, 4514 - */ -#pragma warning( default : 4115 4116 4201 4214) -#endif -  #ifdef __cplusplus  extern "C"  { diff --git a/semaphore.c b/semaphore.c index b388887..15441e8 100644 --- a/semaphore.c +++ b/semaphore.c @@ -42,10 +42,10 @@   * MA 02111-1307, USA   */ -#include <windows.h> -//#include <process.h> -//#include <sys/timeb.h> -#include <string.h> +/* ignore warning "unreferenced formal parameter" */ +#ifdef _MSC_VER +#pragma warning( disable : 4100 ) +#endif  #include "pthread.h"  #include "semaphore.h" diff --git a/tests/ChangeLog b/tests/ChangeLog index 92fca1b..b1b3881 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,458 +1,493 @@ -2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is -	removed for "clean" target. -	* Makefile: Add mutex4 test. - -	* exception3.c: Remove SEH code; automatically pass the test -	under SEH (which is an N/A environment). - -	* mutex4.c: New test. - -	* eyal1.c (do_work_unit): Add a dummy "if" to force the -	optimiser to retain code; reduce thread work loads. - -	* condvar8.c (main): Add an additional "assert" for debugging; -	increase pthread_cond_signal timeout. - -2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* eyal1.c: Increase thread work loads. -	* exception2.c: New test. -	* exception3.c: New test. -	* Makefile: Add new tests exception2.c and exception3.c. -	* GNUmakefile: Likewise. - -2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cleanup3.c: Remove unused variable. -	* cleanup2.c: Likewise. -	* exception1.c: Throw an exception rather than use -	a deliberate zero divide so that catch(...) will -	handle it under Mingw32. Mingw32 now builds the -	library correctly to pass all tests - see Thomas -	Pfaff's detailed instructions re needed changes -	to Mingw32 in the Pthreads-Win32 FAQ. - -2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cancel5.c: New; tests calling pthread_cancel() -	from the main thread without first creating a -	POSIX thread struct for the non-POSIX main thread -	- this forces pthread_cancel() to create one via -	pthread_self(). -	* Makefile (cancel5): Add new test. -	* GNUmakefile (cancel5): Likewise. - -2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* create2.c: New; Test that pthread_t contains -	the W32 HANDLE before it calls the thread routine -	proper. - -2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* condvar3.c: Minor change to eliminate compiler -	warning. - -	* condvar4.c: ditto. - -	* condvar5.c: ditto. - -	* condvar6.c: ditto. - -	* condvar7.c: ditto. - -	* condvar8.c: ditto. - -	* condvar9.c: ditto. - -	* exit1.c: Function needed return statement. - -	* cleanup1.c: Remove unnecessary printf arg. - -	* cleanup2.c: Fix cast. - -	* rwlock6.c: Fix casts. - -	* exception1.c (PtW32CatchAll): Had the wrong name; -	fix casts. - -	* cancel3.c: Remove unused waitLock variable. - -	* GNUmakefile: Change library/dll naming; add new tests; -	general minor changes. - -	* Makefile: Change library/dll naming; add targets for -	testing each of the two VC++ EH scheme versions; -	default target now issues help message; compile warnings -	now interpreted as errors to stop the make; add new -	tests; restructure to remove prerequisites needed -	otherwise. - -	* README: Updated. - - -2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* eyal1.c (main): Change implicit cast to explicit -	cast when passing "print_server" function pointer; -	G++ no longer allows implicit func parameter casts. - -	* cleanup1.c: Remove unused "waitLock". -	(main): Fix implicit parameter cast. - -	* cancel2.c (main): Fix implicit parameter cast. - -	* cancel4.c (main): Fix implicit parameter cast. - -	* cancel3.c (main): Fix implicit parameter cast. - -	* GNUmakefile: Renamed from Makefile; Add missing -	cancel1 and cancel2 test targets. - -	* Makefile: Converted for use with MS nmake. - -2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* ccl.bat: Add /nologo to remove extraneous output. - -	* exception1.c (exceptionedThread): Init 'dummy'; -	put expression into if condition to prevent optimising away; -	remove unused variable. - -	* cancel4.c (mythread): Cast return value to avoid warnings. - -	* cancel2.c (mythread): Missing #endif. - -	* condvar9.c (mythread): Cast return value to avoid warnings. - -	* condvar8.c (mythread): Cast return value to avoid warnings. - -	* condvar7.c (mythread): Cast return value to avoid warnings. - -	* cleanup3.c (mythread): Cast return value to avoid warnings. - -	* cleanup2.c (mythread): Cast return value to avoid warnings. - -	* cleanup1.c (mythread): Cast return value to avoid warnings. - -	* condvar5.c (mythread): Cast return value to avoid warnings. - -	* condvar3.c (mythread): Cast return value to avoid warnings. - -	* condvar6.c (mythread): Cast return value to avoid warnings. - -	* condvar4.c (mythread): Cast return value to avoid warnings. - -2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cancel2.c: Use PtW32CatchAll macro if defined. - -	* exception1.c: Use PtW32CatchAll macro if defined. - -2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* tsd1.c: Fix typecasts of &result [g++ is now very fussy]. -	 -	* test.h (assert): Return 0's explicitly to allay -	g++ errors. -	 -	* join2.c: Add explicit typecasts. -	 -	* join1.c: Add explicit typecasts. -	 -	* join0.c: Add explicit typecasts. -	 -	* eyal1.c: Add explicit typecasts. -	 -	* count1.c (main): Add type cast to remove g++ parse warning -	[gcc-2.95.2 seems to have tightened up on this]. - -	* Makefile (GLANG): Use c++ explicitly. -	Remove MSVC sections (was commented out). -	Add target to generate cpp output. - -2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* runtest.bat: modified to work under W98. -	 -	* runall.bat: Add new tests; modified to work under W98. -	It was ok under NT. - -	* Makefile: Add new tests. - -	* exception1.c: New; Test passing exceptions back to the -	application and retaining library internal exceptions. - -	* join0.c: New; Test a single join. - -2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cleanup1.c: New; Test cleanup handler executes (when thread is -	canceled). - -	* cleanup2.c: New; Test cleanup handler executes (when thread is -	not canceled). - -	* cleanup3.c: New; Test cleanup handler does not execute -	(when thread is not canceled). - -2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* cancel4.c: New; Test cancelation does not occur in deferred -	cancelation threads with no cancelation points. - -	* cancel3.c: New; Test asynchronous cancelation. - -	* context1.c: New; Test context switching method for async -	cancelation. - -1999-11-23  Ross Johnson  <rpj@special.ise.canberra.edu.au> - -	* test.h: Add header includes; include local header versions rather -	than system versions; rearrange the assert macro defines. - -1999-11-07  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* loadfree.c: New. Test loading and freeing the library (DLL). - -1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* cancel1.c: New. Test pthread_setcancelstate and -	pthread_setcanceltype functions. -	* eyal1.c (waste_time): Change calculation to avoid FP exception -	on Aplhas -	- Rich Peters <rpeters@micro-magic.com> - -Oct 14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar7.c: New. Test broadcast after waiting thread is canceled. -	* condvar8.c: New. Test multiple broadcasts. -	* condvar9.c: New. Test multiple broadcasts with thread -	cancelation. -	 -Sep 16 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* rwlock6.c: New test. - -Sep 15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* rwlock1.c: New test. -	* rwlock2.c: New test. -	* rwlock3.c: New test. -	* rwlock4.c: New test. -	* rwlock5.c: New test. - -Aug 22 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* runall.bat (join2): Add test. - -Aug 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* join2.c: New test. - -Wed Aug 12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* Makefile (LIBS): Add -L. - -Mon May 31 10:25:01 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* Makefile (GLANG): Add GCC language option. - -Sat May 29 23:29:04 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* runall.bat (condvar5): Add new test. - -	* runall.bat (condvar6): Add new test. - -	* Makefile (condvar5) : Add new test. -	 -	* Makefile (condvar6) : Add new test. -	 -	* condvar5.c: New test for pthread_cond_broadcast(). - -	* condvar6.c: New test for pthread_cond_broadcast(). - -Sun Apr  4 12:04:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tsd1.c (mythread): Change Sleep(0) to sched_yield(). -	(sched.h): Include. - -	* condvar3.c (mythread): Remove redundant Sleep(). - -	* runtest.bat: Re-organised to make more informative. - -Fri Mar 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* *.bat: redirect unwanted output to nul: - -	* runall.bat: new. - -	* cancel1.c: new. Not part of suite yet. -	 -Mon Mar 15 00:17:55 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* mutex1.c: only test mutex init and destroy; add assertions. - -	* count1.c: raise number of spawned threads to 60 (appears to -	be the limit under Win98). - -Sun Mar 14 21:31:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* test.h (assert): add assertion trace option. -	Use: -	"#define ASSERT_TRACE 1" to turn it on, -	"#define ASSERT_TRACE 0" to turn it off (default). - -	* condvar3.c (main): add more assertions. - -	* condvar4.c (main): add more assertions. - -	* condvar1.c (main): add more assertions. - -Fri Mar 12 08:34:15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* condvar4.c (cvthing): switch the order of the INITIALIZERs. - -	* eyal1.c (main): Fix trylock loop; was not waiting for thread to lock -	the "started" mutex. - -Wed Mar 10 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tryentercs.c: Apply typo patch from bje. - -	* tryentercs2.c: Ditto. - -Sun Mar  7 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* Makefile (condvar3, condvar4): Add tests. - -	* condvar4.c (General): Reduce to simple test case; prerequisite -	is condvar3.c; add description. - -	* condvar3.c (General): Reduce to simple test case; prerequisite -	is condvar2.c; add description. - -	* condvar2.c (General): Reduce to simple test case; prerequisite -	is condvar1.c; add description. - -	* condvar1.c (General): Reduce to simple test case; add -	description. - -	* Template.c (Comments): Add generic test detail. - -1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au> - -        * Template.c: Revamp. - -        * condvar1.c: Add. - -        * condvar2.c: Add. - -        * Makefile: Add condvar1 condvar2 tests. - -        * exit1.c, exit2.c, exit3.c: Cosmetic changes. - -1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au> - -	* Makefile: Some refinement. - -	* *.c: More exhaustive checking through assertions; clean up; -	add some more tests. - -	* Makefile: Now actually runs the tests. - -	* tests.h: Define our own assert macro. The Mingw32 -	version pops up a dialog but we want to run non-interactively. - -	* equal1.c: use assert a little more directly so that it -	prints the actual call statement. - -	* exit1.c: Modify to return 0 on success, 1 on failure. - -1999-02-22  Ross Johnson  <rpj@ise.canberra.edu.au> - -	* self2.c: Bring up to date. - -	* self3.c: Ditto. - -1999-02-21  Ben Elliston  <bje@cygnus.com> - -	* README: Update. - -	* Makefile: New file. Run all tests automatically. Primitive tests -	are run first; more complex tests are run last. - -	* count1.c: New test. Validate the thread count. - -	* exit2.c: Perform a simpler test. -	 -	* exit3.c: New test. Replaces exit2.c, since exit2.c needs to -	perform simpler checking first. - -	* create1.c: Update to use the new testsuite exiting convention. -	 -	* equal1.c: Likewise. - -	* mutex1.c: Likewise. - -	* mutex2.c: Likewise. - -	* once1.c: Likewise. - -	* self2.c: Likewise. - -	* self3.c: Likewise. - -	* tsd1.c: Likewise. - -1999-02-20  Ross Johnson  <rpj@ise.canberra.edu.au> - -	* mutex2.c: Test static mutex initialisation. - -	* test.h: New. Declares a table mapping error numbers to -	error names. - -1999-01-17  Ross Johnson  <rpj@ise.canberra.edu.au> - -	* runtest: New script to build and run a test in the tests directory. - -Wed Dec 30 11:22:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tsd1.c: Re-written. See comments at start of file. -	* Template.c: New. Contains skeleton code and comment template -	intended to fully document the test. - -Fri Oct 16 17:59:49 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* tsd1.c (destroy_key): Add function. Change diagnostics. - -Thu Oct 15 17:42:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au> - -	* tsd1.c (mythread): Fix some casts and add some message -	output. Fix inverted conditional. - -Mon Oct 12 02:12:29 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au> - -	* tsd1.c: New. Test TSD using 1 key and 2 threads. - -1998-09-13  Ben Elliston  <bje@cygnus.com> - -	* eyal1.c: New file; contributed by Eyal Lebedinsky -	<eyal@eyal.emu.id.au>. - -1998-09-12  Ben Elliston  <bje@cygnus.com> - -	* exit2.c (func): Return a value. -	(main): Call the right thread entry function. - -1998-07-22  Ben Elliston  <bje@cygnus.com> - -	* exit2.c (main): Fix size of pthread_t array. - -1998-07-10  Ben Elliston  <bje@cygnus.com> - -	* exit2.c: New file; test pthread_exit() harder. - -	* exit1.c: New file; test pthread_exit(). +2001-05-30  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* mutex1n.c: New test.
 +	* mutex1e.c: New test.
 +	* mutex1r.c: New test.
 +	* mutex4.c: Now locks and unlocks a mutex.
 +	* mutex5.c: New test.
 +	* mutex6.c: New test.
 +	* mutex6n.c: New test.
 +	* mutex6e.c: New test.
 +	* mutex6r.c: New test.
 +	* Makefile: Added new tests; reorganised.
 +	* GNUmakefile: Likewise.
 +	* rwlock6.c: Fix to properly prove read-while-write locking
 +	and single writer locking.
 +
 +2001-05-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* Makefile: Reorganisation.
 +	* GNUmakefile: Likewise.
 +	- Thomas Pfaff <tpfaff@gmx.net>
 +
 +	* exception1.c: Add stdio.h include to define fprintf and stderr
 +	in non-exception C version of main().
 +	* exception2.c: Likewise.
 +	* exception3.c: Likewise.
 +
 +	* Makefile (rwlock7): Add new test.
 +	* GNUmakefile (rwlock7): Add new test.
 +	* rwlock7.c: New test.
 +	* rwlock6.c: Changed to test that writer has priority.
 +
 +	* eyal1.c (main): Unlock each mutex_start lock before destroying
 +	it.
 +
 +2000-12-29  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* GNUmakefile: Add mutex4 test; ensure libpthreadw32.a is
 +	removed for "clean" target.
 +	* Makefile: Add mutex4 test.
 +
 +	* exception3.c: Remove SEH code; automatically pass the test
 +	under SEH (which is an N/A environment).
 +
 +	* mutex4.c: New test.
 +
 +	* eyal1.c (do_work_unit): Add a dummy "if" to force the
 +	optimiser to retain code; reduce thread work loads.
 +
 +	* condvar8.c (main): Add an additional "assert" for debugging;
 +	increase pthread_cond_signal timeout.
 +
 +2000-12-28  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* eyal1.c: Increase thread work loads.
 +	* exception2.c: New test.
 +	* exception3.c: New test.
 +	* Makefile: Add new tests exception2.c and exception3.c.
 +	* GNUmakefile: Likewise.
 +
 +2000-12-11  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cleanup3.c: Remove unused variable.
 +	* cleanup2.c: Likewise.
 +	* exception1.c: Throw an exception rather than use
 +	a deliberate zero divide so that catch(...) will
 +	handle it under Mingw32. Mingw32 now builds the
 +	library correctly to pass all tests - see Thomas
 +	Pfaff's detailed instructions re needed changes
 +	to Mingw32 in the Pthreads-Win32 FAQ.
 +
 +2000-09-08  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cancel5.c: New; tests calling pthread_cancel()
 +	from the main thread without first creating a
 +	POSIX thread struct for the non-POSIX main thread
 +	- this forces pthread_cancel() to create one via
 +	pthread_self().
 +	* Makefile (cancel5): Add new test.
 +	* GNUmakefile (cancel5): Likewise.
 +
 +2000-08-17  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* create2.c: New; Test that pthread_t contains
 +	the W32 HANDLE before it calls the thread routine
 +	proper.
 +
 +2000-08-13  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* condvar3.c: Minor change to eliminate compiler
 +	warning.
 +
 +	* condvar4.c: ditto.
 +
 +	* condvar5.c: ditto.
 +
 +	* condvar6.c: ditto.
 +
 +	* condvar7.c: ditto.
 +
 +	* condvar8.c: ditto.
 +
 +	* condvar9.c: ditto.
 +
 +	* exit1.c: Function needed return statement.
 +
 +	* cleanup1.c: Remove unnecessary printf arg.
 +
 +	* cleanup2.c: Fix cast.
 +
 +	* rwlock6.c: Fix casts.
 +
 +	* exception1.c (PtW32CatchAll): Had the wrong name;
 +	fix casts.
 +
 +	* cancel3.c: Remove unused waitLock variable.
 +
 +	* GNUmakefile: Change library/dll naming; add new tests;
 +	general minor changes.
 +
 +	* Makefile: Change library/dll naming; add targets for
 +	testing each of the two VC++ EH scheme versions;
 +	default target now issues help message; compile warnings
 +	now interpreted as errors to stop the make; add new
 +	tests; restructure to remove prerequisites needed
 +	otherwise.
 +
 +	* README: Updated.
 +
 +
 +2000-08-10  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* eyal1.c (main): Change implicit cast to explicit
 +	cast when passing "print_server" function pointer;
 +	G++ no longer allows implicit func parameter casts.
 +
 +	* cleanup1.c: Remove unused "waitLock".
 +	(main): Fix implicit parameter cast.
 +
 +	* cancel2.c (main): Fix implicit parameter cast.
 +
 +	* cancel4.c (main): Fix implicit parameter cast.
 +
 +	* cancel3.c (main): Fix implicit parameter cast.
 +
 +	* GNUmakefile: Renamed from Makefile; Add missing
 +	cancel1 and cancel2 test targets.
 +
 +	* Makefile: Converted for use with MS nmake.
 +
 +2000-08-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* ccl.bat: Add /nologo to remove extraneous output.
 +
 +	* exception1.c (exceptionedThread): Init 'dummy';
 +	put expression into if condition to prevent optimising away;
 +	remove unused variable.
 +
 +	* cancel4.c (mythread): Cast return value to avoid warnings.
 +
 +	* cancel2.c (mythread): Missing #endif.
 +
 +	* condvar9.c (mythread): Cast return value to avoid warnings.
 +
 +	* condvar8.c (mythread): Cast return value to avoid warnings.
 +
 +	* condvar7.c (mythread): Cast return value to avoid warnings.
 +
 +	* cleanup3.c (mythread): Cast return value to avoid warnings.
 +
 +	* cleanup2.c (mythread): Cast return value to avoid warnings.
 +
 +	* cleanup1.c (mythread): Cast return value to avoid warnings.
 +
 +	* condvar5.c (mythread): Cast return value to avoid warnings.
 +
 +	* condvar3.c (mythread): Cast return value to avoid warnings.
 +
 +	* condvar6.c (mythread): Cast return value to avoid warnings.
 +
 +	* condvar4.c (mythread): Cast return value to avoid warnings.
 +
 +2000-08-05  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cancel2.c: Use PtW32CatchAll macro if defined.
 +
 +	* exception1.c: Use PtW32CatchAll macro if defined.
 +
 +2000-08-02  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* tsd1.c: Fix typecasts of &result [g++ is now very fussy].
 +	
 +	* test.h (assert): Return 0's explicitly to allay
 +	g++ errors.
 +	
 +	* join2.c: Add explicit typecasts.
 +	
 +	* join1.c: Add explicit typecasts.
 +	
 +	* join0.c: Add explicit typecasts.
 +	
 +	* eyal1.c: Add explicit typecasts.
 +	
 +	* count1.c (main): Add type cast to remove g++ parse warning
 +	[gcc-2.95.2 seems to have tightened up on this].
 +
 +	* Makefile (GLANG): Use c++ explicitly.
 +	Remove MSVC sections (was commented out).
 +	Add target to generate cpp output.
 +
 +2000-07-25  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* runtest.bat: modified to work under W98.
 +	
 +	* runall.bat: Add new tests; modified to work under W98.
 +	It was ok under NT.
 +
 +	* Makefile: Add new tests.
 +
 +	* exception1.c: New; Test passing exceptions back to the
 +	application and retaining library internal exceptions.
 +
 +	* join0.c: New; Test a single join.
 +
 +2000-01-06  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cleanup1.c: New; Test cleanup handler executes (when thread is
 +	canceled).
 +
 +	* cleanup2.c: New; Test cleanup handler executes (when thread is
 +	not canceled).
 +
 +	* cleanup3.c: New; Test cleanup handler does not execute
 +	(when thread is not canceled).
 +
 +2000-01-04  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* cancel4.c: New; Test cancelation does not occur in deferred
 +	cancelation threads with no cancelation points.
 +
 +	* cancel3.c: New; Test asynchronous cancelation.
 +
 +	* context1.c: New; Test context switching method for async
 +	cancelation.
 +
 +1999-11-23  Ross Johnson  <rpj@special.ise.canberra.edu.au>
 +
 +	* test.h: Add header includes; include local header versions rather
 +	than system versions; rearrange the assert macro defines.
 +
 +1999-11-07  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* loadfree.c: New. Test loading and freeing the library (DLL).
 +
 +1999-10-30  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* cancel1.c: New. Test pthread_setcancelstate and
 +	pthread_setcanceltype functions.
 +	* eyal1.c (waste_time): Change calculation to avoid FP exception
 +	on Aplhas
 +	- Rich Peters <rpeters@micro-magic.com>
 +
 +Oct 14 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar7.c: New. Test broadcast after waiting thread is canceled.
 +	* condvar8.c: New. Test multiple broadcasts.
 +	* condvar9.c: New. Test multiple broadcasts with thread
 +	cancelation.
 +	
 +Sep 16 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* rwlock6.c: New test.
 +
 +Sep 15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* rwlock1.c: New test.
 +	* rwlock2.c: New test.
 +	* rwlock3.c: New test.
 +	* rwlock4.c: New test.
 +	* rwlock5.c: New test.
 +
 +Aug 22 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* runall.bat (join2): Add test.
 +
 +Aug 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* join2.c: New test.
 +
 +Wed Aug 12 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* Makefile (LIBS): Add -L.
 +
 +Mon May 31 10:25:01 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* Makefile (GLANG): Add GCC language option.
 +
 +Sat May 29 23:29:04 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* runall.bat (condvar5): Add new test.
 +
 +	* runall.bat (condvar6): Add new test.
 +
 +	* Makefile (condvar5) : Add new test.
 +	
 +	* Makefile (condvar6) : Add new test.
 +	
 +	* condvar5.c: New test for pthread_cond_broadcast().
 +
 +	* condvar6.c: New test for pthread_cond_broadcast().
 +
 +Sun Apr  4 12:04:28 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tsd1.c (mythread): Change Sleep(0) to sched_yield().
 +	(sched.h): Include.
 +
 +	* condvar3.c (mythread): Remove redundant Sleep().
 +
 +	* runtest.bat: Re-organised to make more informative.
 +
 +Fri Mar 19 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* *.bat: redirect unwanted output to nul:
 +
 +	* runall.bat: new.
 +
 +	* cancel1.c: new. Not part of suite yet.
 +	
 +Mon Mar 15 00:17:55 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* mutex1.c: only test mutex init and destroy; add assertions.
 +
 +	* count1.c: raise number of spawned threads to 60 (appears to
 +	be the limit under Win98).
 +
 +Sun Mar 14 21:31:02 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* test.h (assert): add assertion trace option.
 +	Use:
 +	"#define ASSERT_TRACE 1" to turn it on,
 +	"#define ASSERT_TRACE 0" to turn it off (default).
 +
 +	* condvar3.c (main): add more assertions.
 +
 +	* condvar4.c (main): add more assertions.
 +
 +	* condvar1.c (main): add more assertions.
 +
 +Fri Mar 12 08:34:15 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* condvar4.c (cvthing): switch the order of the INITIALIZERs.
 +
 +	* eyal1.c (main): Fix trylock loop; was not waiting for thread to lock
 +	the "started" mutex.
 +
 +Wed Mar 10 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tryentercs.c: Apply typo patch from bje.
 +
 +	* tryentercs2.c: Ditto.
 +
 +Sun Mar  7 10:41:52 1999  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* Makefile (condvar3, condvar4): Add tests.
 +
 +	* condvar4.c (General): Reduce to simple test case; prerequisite
 +	is condvar3.c; add description.
 +
 +	* condvar3.c (General): Reduce to simple test case; prerequisite
 +	is condvar2.c; add description.
 +
 +	* condvar2.c (General): Reduce to simple test case; prerequisite
 +	is condvar1.c; add description.
 +
 +	* condvar1.c (General): Reduce to simple test case; add
 +	description.
 +
 +	* Template.c (Comments): Add generic test detail.
 +
 +1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +        * Template.c: Revamp.
 +
 +        * condvar1.c: Add.
 +
 +        * condvar2.c: Add.
 +
 +        * Makefile: Add condvar1 condvar2 tests.
 +
 +        * exit1.c, exit2.c, exit3.c: Cosmetic changes.
 +
 +1999-02-23  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +	* Makefile: Some refinement.
 +
 +	* *.c: More exhaustive checking through assertions; clean up;
 +	add some more tests.
 +
 +	* Makefile: Now actually runs the tests.
 +
 +	* tests.h: Define our own assert macro. The Mingw32
 +	version pops up a dialog but we want to run non-interactively.
 +
 +	* equal1.c: use assert a little more directly so that it
 +	prints the actual call statement.
 +
 +	* exit1.c: Modify to return 0 on success, 1 on failure.
 +
 +1999-02-22  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +	* self2.c: Bring up to date.
 +
 +	* self3.c: Ditto.
 +
 +1999-02-21  Ben Elliston  <bje@cygnus.com>
 +
 +	* README: Update.
 +
 +	* Makefile: New file. Run all tests automatically. Primitive tests
 +	are run first; more complex tests are run last.
 +
 +	* count1.c: New test. Validate the thread count.
 +
 +	* exit2.c: Perform a simpler test.
 +	
 +	* exit3.c: New test. Replaces exit2.c, since exit2.c needs to
 +	perform simpler checking first.
 +
 +	* create1.c: Update to use the new testsuite exiting convention.
 +	
 +	* equal1.c: Likewise.
 +
 +	* mutex1.c: Likewise.
 +
 +	* mutex2.c: Likewise.
 +
 +	* once1.c: Likewise.
 +
 +	* self2.c: Likewise.
 +
 +	* self3.c: Likewise.
 +
 +	* tsd1.c: Likewise.
 +
 +1999-02-20  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +	* mutex2.c: Test static mutex initialisation.
 +
 +	* test.h: New. Declares a table mapping error numbers to
 +	error names.
 +
 +1999-01-17  Ross Johnson  <rpj@ise.canberra.edu.au>
 +
 +	* runtest: New script to build and run a test in the tests directory.
 +
 +Wed Dec 30 11:22:44 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tsd1.c: Re-written. See comments at start of file.
 +	* Template.c: New. Contains skeleton code and comment template
 +	intended to fully document the test.
 +
 +Fri Oct 16 17:59:49 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* tsd1.c (destroy_key): Add function. Change diagnostics.
 +
 +Thu Oct 15 17:42:37 1998  Ross Johnson  <rpj@swan.canberra.edu.au>
 +
 +	* tsd1.c (mythread): Fix some casts and add some message
 +	output. Fix inverted conditional.
 +
 +Mon Oct 12 02:12:29 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
 +
 +	* tsd1.c: New. Test TSD using 1 key and 2 threads.
 +
 +1998-09-13  Ben Elliston  <bje@cygnus.com>
 +
 +	* eyal1.c: New file; contributed by Eyal Lebedinsky
 +	<eyal@eyal.emu.id.au>.
 +
 +1998-09-12  Ben Elliston  <bje@cygnus.com>
 +
 +	* exit2.c (func): Return a value.
 +	(main): Call the right thread entry function.
 +
 +1998-07-22  Ben Elliston  <bje@cygnus.com>
 +
 +	* exit2.c (main): Fix size of pthread_t array.
 +
 +1998-07-10  Ben Elliston  <bje@cygnus.com>
 +
 +	* exit2.c: New file; test pthread_exit() harder.
 +
 +	* exit1.c: New file; test pthread_exit().
 diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 33de3ac..d38f982 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -2,27 +2,33 @@  # If all of the .pass files can be created, the test suite has passed. +#CP	= cp +#MV	= mv +#RM	= rm  CP	= copy  MV	= rename  RM	= erase  MKDIR	= mkdir  TOUCH	= echo Passed >  ECHO	= @echo +MAKE	= make  #  # Mingw32  #  GLANG   = c++  CC	= gcc +XXCFLAGS	=   #CFLAGS	= -g -O0 -mthreads -UNDEBUG -Wall -x $(GLANG) -CFLAGS	= -O3 -mthreads -UNDEBUG -Wall -x $(GLANG) +#CFLAGS	= -O3 -mthreads -UNDEBUG -Wall -x $(GLANG) +CFLAGS	= -g -O0 -UNDEBUG -Wall $(XXCFLAGS)  BUILD_DIR	= ..  INCLUDES	= -I. -LIBS	= -L. -lpthreadw32 +GCX	= DUMMY  HDR	= pthread.h semaphore.h sched.h -LIB	= libpthreadw32.a -DLL	= pthreadGCE.dll +LIB	= libpthread$(GCX).a +DLL	= pthread$(GCX).dll  COPYFILES	= $(HDR) $(LIB) $(DLL) @@ -30,45 +36,51 @@ COPYFILES	= $(HDR) $(LIB) $(DLL)  # stop.  TESTS	= loadfree \ -	  mutex1 condvar1 condvar2 exit1 create1 equal1 \ +	  self1 mutex5 mutex1 mutex1e mutex1n mutex1r condvar1 condvar2 exit1 create1 equal1 \  	  exit2 exit3 \ -	  join0 join1 join2 mutex2 mutex3 mutex4 \ -	  count1 once1 tsd1 self1 self2 cancel1 cancel2 eyal1 \ +	  join0 join1 join2 mutex2 mutex3 mutex4 mutex6 mutex6n mutex6e mutex6r \ +	  count1 once1 tsd1 self2 cancel1 cancel2 eyal1 \  	  condvar3 condvar4 condvar5 condvar6 condvar7 condvar8 condvar9 \  	  errno1 \ -	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 \ +	  rwlock1 rwlock2 rwlock3 rwlock4 rwlock5 rwlock6 rwlock7 \  	  context1 cancel3 cancel4 cancel5 \  	  cleanup0 cleanup1 cleanup2 cleanup3 \  	  exception1 exception2 exception3  PASSES	= $(TESTS:%=%.pass) -all:	$(PASSES) +default: +	@ $(ECHO) Run one of the following command lines: +	@ $(ECHO) nmake clean GCE   (to test using GNU C dll with C++ exception handling) +	@ $(ECHO) nmake clean GC    (to test using GNU C dll with C cleanup code) + +auto: +	@ $(MAKE) clean GCE +	@ $(MAKE) clean GC + +GC: +	$(MAKE) GCX=GC XXCFLAGS="-x c" all-GC + +GCE: +	$(MAKE) GCX=GCE XXCFLAGS="-mthreads -x c++" all-GCE + +all-GC: $(PASSES) +	@ $(ECHO) ALL TESTS PASSED! Congratulations! + +all-GCE: $(PASSES)  	@ $(ECHO) ALL TESTS PASSED! Congratulations! -loadfree.pass: pthread.dll -mutex1.pass: -mutex2.pass: -exit1.pass: -condvar1.pass: -self1.pass: -condvar2.pass: condvar1.pass -create1.pass: mutex2.pass  cancel1.pass: create1.pass  cancel2.pass: cancel1.pass -mutex3.pass: create1.pass -mutex4.pass: mutex3.pass -equal1.pass: create1.pass -exit2.pass: create1.pass -exit3.pass: create1.pass -join0.pass: create1.pass -join1.pass: create1.pass -join2.pass: create1.pass -count1.pass: join1.pass -once1.pass: create1.pass -tsd1.pass: join1.pass -self2.pass: create1.pass -eyal1.pass: tsd1.pass +cancel3.pass: context1.pass +cancel4.pass: cancel3.pass +cancel5.pass: cancel3.pass +cleanup0.pass: cancel5.pass +cleanup1.pass: cleanup0.pass +cleanup2.pass: cleanup1.pass +cleanup3.pass: cleanup2.pass +condvar1.pass: +condvar2.pass: condvar1.pass  condvar3.pass: create1.pass  condvar4.pass: create1.pass  condvar5.pass: condvar4.pass @@ -76,33 +88,53 @@ condvar6.pass: condvar5.pass  condvar7.pass: condvar6.pass cleanup1.pass  condvar8.pass: condvar7.pass  condvar9.pass: condvar8.pass +context1.pass: cancel2.pass +count1.pass: join1.pass +create1.pass: mutex2.pass +equal1.pass: create1.pass  errno1.pass: mutex3.pass +exception1.pass: cancel4.pass +exception2.pass: exception1.pass +exception3.pass: exception2.pass +exit1.pass: +exit2.pass: create1.pass +exit3.pass: create1.pass +eyal1.pass: tsd1.pass +join0.pass: create1.pass +join1.pass: create1.pass +join2.pass: create1.pass +loadfree.pass: pthread.dll +mutex1.pass: self1.pass +mutex1n.pass: mutex1.pass +mutex1e.pass: mutex1.pass +mutex1r.pass: mutex1.pass +mutex2.pass: mutex1.pass +mutex3.pass: create1.pass +mutex4.pass: mutex3.pass +mutex5.pass: +once1.pass: create1.pass  rwlock1.pass: condvar6.pass  rwlock2.pass: rwlock1.pass  rwlock3.pass: rwlock2.pass  rwlock4.pass: rwlock3.pass  rwlock5.pass: rwlock4.pass  rwlock6.pass: rwlock5.pass -context1.pass: cancel2.pass -cancel3.pass: context1.pass -cancel4.pass: cancel3.pass -cancel5.pass: cancel3.pass -cleanup0.pass: cancel5.pass -cleanup1.pass: cleanup0.pass -cleanup2.pass: cleanup1.pass -cleanup3.pass: cleanup2.pass -exception1.pass: cancel4.pass -exception2.pass: exception1.pass -exception3.pass: exception2.pass +rwlock7.pass: rwlock6.pass +self1.pass: +self2.pass: create1.pass +tsd1.pass: join1.pass  #%.pass: %.exe $(HDR)  %.pass: %.exe $(LIB) $(DLL) $(HDR) +	@ $(ECHO) Running $*  	$*  	@ $(ECHO) Passed  	@ $(TOUCH) $@  %.exe: %.c -	@ $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) $(LIBS) +	@ $(ECHO) Compiling $@ +	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) -L. -lpthread$(GCX) +	@ $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) -L. -lpthread$(GCX)  %.pre: %.c  	@ $(CC) -E $(CFLAGS) -o $@ $^ $(INCLUDES) @@ -123,10 +155,9 @@ clean:  	- $(RM) pthread.h  	- $(RM) semaphore.h  	- $(RM) sched.h -	- $(RM) libpthreadw32.a +	- $(RM) *.a  	- $(RM) *.e  	- $(RM) *.obj  	- $(RM) *.pdb  	- $(RM) *.exe  	- $(RM) *.pass - diff --git a/tests/Makefile b/tests/Makefile index 281cd50..5915d54 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -11,13 +11,17 @@ ECHO	= @echo  CPHDR	= pthread.h semaphore.h sched.h
  # C++ Exceptions
 -VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn
 +VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX
  VCELIB	= pthreadVCE.lib
  VCEDLL	= pthreadVCE.dll
  # Structured Exceptions
 -VSEFLAGS	=
 +VSEFLAGS	= /D__CLEANUP_SEH
  VSELIB	= pthreadVSE.lib
  VSEDLL	= pthreadVSE.dll
 +#C cleanup code
 +VCFLAGS	= /D__CLEANUP_C
 +VCLIB	= pthreadVC.lib
 +VCDLL	= pthreadVC.dll
  CFLAGS= /W3 /WX /MT /nologo /Yd /Zi -D_WIN32_WINNT=0x400
  LFLAGS= /INCREMENTAL:NO
 @@ -33,30 +37,36 @@ EHFLAGS	=  # stop.
  PASSES= loadfree.pass \
 -	  mutex1.pass  mutex2.pass  mutex3.pass mutex4.pass \
 +	  self1.pass mutex5.pass  \
 +	  mutex1.pass  mutex1n.pass  mutex1e.pass  mutex1r.pass  mutex2.pass  mutex3.pass  \
  	  condvar1.pass  condvar2.pass  \
  	  exit1.pass  create1.pass  equal1.pass  \
  	  exit2.pass  exit3.pass  \
  	  join0.pass  join1.pass  join2.pass  \
 +	  mutex4.pass  mutex6.pass  mutex6n.pass  mutex6e.pass  mutex6r.pass  \
  	  count1.pass  once1.pass  tsd1.pass  \
 -	  self1.pass  self2.pass  \
 +	  self2.pass  \
  	  cancel1.pass  cancel2.pass  \
  	  eyal1.pass  \
  	  condvar3.pass  condvar4.pass  condvar5.pass  condvar6.pass  \
  	  condvar7.pass  condvar8.pass  condvar9.pass  \
  	  errno1.pass  \
 -	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  rwlock5.pass  rwlock6.pass  \
 +	  rwlock1.pass  rwlock2.pass  rwlock3.pass  rwlock4.pass  rwlock5.pass  rwlock6.pass  rwlock7.pass  \
  	  context1.pass  \
  	  cancel3.pass  cancel4.pass  cancel5.pass  \
  	  cleanup0.pass  cleanup1.pass  cleanup2.pass  cleanup3.pass  \
 -	  exception1.pass  exception2.pass exception3.pass
 +	  exception1.pass  exception2.pass  exception3.pass
  all:
  	@ $(ECHO) Run one of the following command lines:
 -	@ $(ECHO) nmake clean VCE   (to test using dll with C++ exception handling)
 -	@ $(ECHO) nmake clean VSE   (to test using dll with structured exception handling)
 +	@ $(ECHO) nmake clean VCE   (to test using MSVC dll with C++ exception handling)
 +	@ $(ECHO) nmake clean VSE   (to test using MSVC dll with structured exception handling)
 +	@ $(ECHO) nmake clean VC    (to test using MSVC dll with C cleanup code)
 -auto: clean VCE clean VSE
 +auto:
 +	@ nmake clean VCE
 +	@ nmake clean VSE
 +	@ nmake clean VC
  tests: $(CPLIB) $(CPDLL) $(CPHDR) $(PASSES)
  	@ $(ECHO) ALL TESTS PASSED! Congratulations!
 @@ -73,6 +83,9 @@ VCE:  VSE:	
  	@ nmake TEST="$@" CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" tests
 +VC:
 +	@ nmake TEST="$@" CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" tests
 +
  .c.exe:
  	@ $(ECHO) Compiling $@
  	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB)
 @@ -101,29 +114,17 @@ clean:  	- $(RM) *.exe
  	- $(RM) *.pass
 -loadfree.pass: pthread.dll
 -mutex1.pass:
 -mutex2.pass:
 -exit1.pass:
 -condvar1.pass:
 -self1.pass:
 -condvar2.pass: condvar1.pass
 -create1.pass: mutex2.pass
  cancel1.pass: create1.pass
  cancel2.pass: cancel1.pass
 -mutex3.pass: create1.pass
 -mutex4.pass: mutex3.pass
 -equal1.pass: create1.pass
 -exit2.pass: create1.pass
 -exit3.pass: create1.pass
 -join0.pass: create1.pass
 -join1.pass: create1.pass
 -join2.pass: create1.pass
 -count1.pass: join1.pass
 -once1.pass: create1.pass
 -tsd1.pass: join1.pass
 -self2.pass: create1.pass
 -eyal1.pass: tsd1.pass
 +cancel3.pass: context1.pass
 +cancel4.pass: cancel3.pass
 +cancel5.pass: cancel3.pass
 +cleanup0.pass: cancel5.pass
 +cleanup1.pass: cleanup0.pass
 +cleanup2.pass: cleanup1.pass
 +cleanup3.pass: cleanup2.pass
 +condvar1.pass:
 +condvar2.pass: condvar1.pass
  condvar3.pass: create1.pass
  condvar4.pass: create1.pass
  condvar5.pass: condvar4.pass
 @@ -131,21 +132,40 @@ condvar6.pass: condvar5.pass  condvar7.pass: condvar6.pass cleanup1.pass
  condvar8.pass: condvar7.pass
  condvar9.pass: condvar8.pass
 +context1.pass: cancel2.pass
 +count1.pass: join1.pass
 +create1.pass: mutex2.pass
 +equal1.pass: create1.pass
  errno1.pass: mutex3.pass
 +exception1.pass: cancel4.pass
 +exception2.pass: exception1.pass
 +exception3.pass: exception2.pass
 +exit1.pass:
 +exit2.pass: create1.pass
 +exit3.pass: create1.pass
 +eyal1.pass: tsd1.pass
 +join0.pass: create1.pass
 +join1.pass: create1.pass
 +join2.pass: create1.pass
 +loadfree.pass: pthread.dll
 +mutex1.pass: self1.pass
 +mutex1n.pass: mutex1.pass
 +mutex1e.pass: mutex1.pass
 +mutex1r.pass: mutex1.pass
 +mutex2.pass: mutex1.pass
 +mutex3.pass: create1.pass
 +mutex4.pass: mutex3.pass
 +mutex5.pass:
 +once1.pass: create1.pass
  rwlock1.pass: condvar6.pass
  rwlock2.pass: rwlock1.pass
  rwlock3.pass: rwlock2.pass
  rwlock4.pass: rwlock3.pass
  rwlock5.pass: rwlock4.pass
  rwlock6.pass: rwlock5.pass
 -context1.pass: cancel2.pass
 -cancel3.pass: context1.pass
 -cancel4.pass: cancel3.pass
 -cancel5.pass: cancel3.pass
 -cleanup0.pass: cancel5.pass
 -cleanup1.pass: cleanup0.pass
 -cleanup2.pass: cleanup1.pass
 -cleanup3.pass: cleanup2.pass
 -exception1.pass: cancel4.pass
 -exception2.pass: exception1.pass
 -exception3.pass: exception2.pass
 +rwlock7.pass: rwlock6.pass
 +self1.pass:
 +self2.pass: create1.pass
 +tsd1.pass: join1.pass
 +
 +
 diff --git a/tests/condvar7.c b/tests/condvar7.c index 23e2441..afac300 100644 --- a/tests/condvar7.c +++ b/tests/condvar7.c @@ -134,7 +134,7 @@ main()    abstime.tv_sec = currSysTime.time;    abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm; -  abstime.tv_sec += 5; +  abstime.tv_sec += 10;    assert((t[0] = pthread_self()) != NULL); @@ -156,7 +156,7 @@ main()    /*     * Give threads time to start.     */ -  Sleep(2000); +  Sleep(1000);    assert(pthread_mutex_lock(&cvthing.lock) == 0); @@ -218,5 +218,3 @@ main()     */    return 0;  } - - diff --git a/tests/exception1.c b/tests/exception1.c index 1452d1a..60038cd 100644 --- a/tests/exception1.c +++ b/tests/exception1.c @@ -219,6 +219,8 @@ main()  #else /* defined(_MSC_VER) || defined(__cplusplus) */
 +#include <stdio.h>
 +
  int
  main()
  {
 diff --git a/tests/exception2.c b/tests/exception2.c index da3d3b4..d49e866 100644 --- a/tests/exception2.c +++ b/tests/exception2.c @@ -40,13 +40,17 @@   */ +#if defined(_MSC_VER) || defined(__cplusplus) +  #if defined(_MSC_VER) && defined(__cplusplus)  #include <eh.h>  #else  #include <new.h>  #endif -#if defined(_MSC_VER) || defined(__cplusplus) +#ifdef __GNUC__ +#include <stdlib.h> +#endif  #include "test.h" @@ -110,6 +114,8 @@ main(int argc, char argv[])  #else /* defined(_MSC_VER) || defined(__cplusplus) */ +#include <stdio.h> +  int  main()  { diff --git a/tests/exception3.c b/tests/exception3.c index 66f4173..216dc27 100644 --- a/tests/exception3.c +++ b/tests/exception3.c @@ -112,6 +112,8 @@ main()  #else /* defined(__cplusplus) */ +#include <stdio.h> +  int  main()  { diff --git a/tests/eyal1.c b/tests/eyal1.c index 6954c3b..17ab6fe 100644 --- a/tests/eyal1.c +++ b/tests/eyal1.c @@ -315,6 +315,8 @@ main (int argc, char *argv[])        else  	printf ("failed %d\n", tcs[i].stat); +      assert(pthread_mutex_unlock(&tcs[i].mutex_start) == 0); +        assert(pthread_mutex_destroy (&tcs[i].mutex_start) == 0);        assert(pthread_mutex_destroy (&tcs[i].mutex_started) == 0);        assert(pthread_mutex_destroy (&tcs[i].mutex_end) == 0); diff --git a/tests/mutex1.c b/tests/mutex1.c index c997963..b7f6b6f 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -24,6 +24,10 @@ main()    assert(mutex != NULL); +  assert(pthread_mutex_lock(&mutex) == 0); + +  assert(pthread_mutex_unlock(&mutex) == 0); +    assert(pthread_mutex_destroy(&mutex) == 0);    assert(mutex == NULL); diff --git a/tests/rwlock6.c b/tests/rwlock6.c index 7daccd7..3f53520 100644 --- a/tests/rwlock6.c +++ b/tests/rwlock6.c @@ -1,30 +1,30 @@ -/*  +/*   * rwlock6.c   *   * Check that writer locks have priority.   *   * Depends on API functions:  - *	pthread_rwlock_rdlock() - *	pthread_rwlock_wrlock() - *	pthread_rwlock_unlock() + *      pthread_rwlock_rdlock() + *      pthread_rwlock_wrlock() + *      pthread_rwlock_unlock()   */  #include "test.h" -  +  static pthread_rwlock_t rwlock1 = PTHREAD_RWLOCK_INITIALIZER; -static int bankAccount; +static int bankAccount = 0;  void * wrfunc(void * arg)  {    assert(pthread_rwlock_wrlock(&rwlock1) == 0); -  Sleep(1000); +  Sleep(2000);    bankAccount += 10;    assert(pthread_rwlock_unlock(&rwlock1) == 0); -  return((void *) bankAccount);  +  return ((void *) bankAccount);  } -  +  void * rdfunc(void * arg)  {    int ba = 0; @@ -34,9 +34,9 @@ void * rdfunc(void * arg)    assert(pthread_rwlock_unlock(&rwlock1) == 0);    ba += 10; -  return((void *) ba);  +  return ((void *) ba);  } -  +  int  main()  { @@ -47,11 +47,13 @@ main()    int wr2Result = 0;    int rdResult = 0; +  bankAccount = 0; +    assert(pthread_create(&wrt1, NULL, wrfunc, NULL) == 0); -  Sleep(200); -  assert(pthread_create(&rdt, NULL, rdfunc, NULL) == 0); -  Sleep(200); -  assert(pthread_create(&wrt2, NULL, wrfunc, NULL) == 0); +  Sleep(500); +  assert(pthread_create(&wrt2, NULL, rdfunc, NULL) == 0); +  Sleep(500); +  assert(pthread_create(&rdt, NULL, wrfunc, NULL) == 0);    assert(pthread_join(wrt1, (void **) &wr1Result) == 0);    assert(pthread_join(wrt2, (void **) &wr2Result) == 0); @@ -59,7 +61,7 @@ main()    assert(wr1Result == 10);    assert(wr2Result == 20); -  assert(rdResult == 30); +  assert(rdResult == 20);    return 0;  } @@ -322,6 +322,12 @@ pthread_getspecific (pthread_key_t key)        * ------------------------------------------------------        */  { -  return (TlsGetValue (key->key)); +  int lasterror = GetLastError(); + +  void *ptr = TlsGetValue (key->key); + +  SetLastError( lasterror ); + +  return ptr;  }  | 
