1 /* This is an implementation of the threads API of POSIX 1003.1-2001.
2  *
3  * --------------------------------------------------------------------------
4  *
5  *      Pthreads-win32 - POSIX Threads Library for Win32
6  *      Copyright(C) 1998 John E. Bossom
7  *      Copyright(C) 1999,2003 Pthreads-win32 contributors
8  *
9  *      Contact Email: rpj@callisto.canberra.edu.au
10  *
11  *      The current list of contributors is contained
12  *      in the file CONTRIBUTORS included with the source
13  *      code distribution. The list can also be seen at the
14  *      following World Wide Web location:
15  *      http://sources.redhat.com/pthreads-win32/contributors.html
16  *
17  *      This library is free software; you can redistribute it and/or
18  *      modify it under the terms of the GNU Lesser General Public
19  *      License as published by the Free Software Foundation; either
20  *      version 2 of the License, or (at your option) any later version.
21  *
22  *      This library is distributed in the hope that it will be useful,
23  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  *      Lesser General Public License for more details.
26  *
27  *      You should have received a copy of the GNU Lesser General Public
28  *      License along with this library in the file COPYING.LIB;
29  *      if not, write to the Free Software Foundation, Inc.,
30  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
31  */
32 
33 #if !defined( PTHREAD_H )
34 #define PTHREAD_H
35 
36 #undef PTW32_LEVEL
37 
38 #if defined(_POSIX_SOURCE)
39 #define PTW32_LEVEL 0
40 /* Early POSIX */
41 #endif
42 
43 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
44 #undef PTW32_LEVEL
45 #define PTW32_LEVEL 1
46 /* Include 1b, 1c and 1d */
47 #endif
48 
49 #if defined(INCLUDE_NP)
50 #undef PTW32_LEVEL
51 #define PTW32_LEVEL 2
52 /* Include Non-Portable extensions */
53 #endif
54 
55 #define PTW32_LEVEL_MAX 3
56 
57 #if !defined(PTW32_LEVEL)
58 #define PTW32_LEVEL PTW32_LEVEL_MAX
59 /* Include everything */
60 #endif
61 
62 #ifdef _UWIN
63 #   define HAVE_STRUCT_TIMESPEC 1
64 #   define HAVE_SIGNAL_H	1
65 #   undef HAVE_CONFIG_H
66 #   pragma comment(lib, "pthread")
67 #endif
68 
69 /*
70  * -------------------------------------------------------------
71  *
72  *
73  * Module: pthread.h
74  *
75  * Purpose:
76  *	Provides an implementation of PThreads based upon the
77  *	standard:
78  *
79  *		POSIX 1003.1-2001
80  *  and
81  *    The Single Unix Specification version 3
82  *
83  *    (these two are equivalent)
84  *
85  *	in order to enhance code portability between Windows,
86  *  various commercial Unix implementations, and Linux.
87  *
88  *	See the ANNOUNCE file for a full list of conforming
89  *	routines and defined constants, and a list of missing
90  *	routines and constants not defined in this implementation.
91  *
92  * Authors:
93  *	There have been many contributors to this library.
94  *	The initial implementation was contributed by
95  *	John Bossom, and several others have provided major
96  *	sections or revisions of parts of the implementation.
97  *	Often significant effort has been contributed to
98  *	find and fix important bugs and other problems to
99  *	improve the reliability of the library, which sometimes
100  *	is not reflected in the amount of code which changed as
101  *	result.
102  *	As much as possible, the contributors are acknowledged
103  *	in the ChangeLog file in the source code distribution
104  *	where their changes are noted in detail.
105  *
106  *	Contributors are listed in the CONTRIBUTORS file.
107  *
108  *	As usual, all bouquets go to the contributors, and all
109  *	brickbats go to the project maintainer.
110  *
111  * Maintainer:
112  *	The code base for this project is coordinated and
113  *	eventually pre-tested, packaged, and made available by
114  *
115  *		Ross Johnson <rpj@ise.canberra.edu.au>
116  *
117  * QA Testers:
118  *	Ultimately, the library is tested in the real world by
119  *	a host of competent and demanding scientists and
120  *	engineers who report bugs and/or provide solutions
121  *	which are then fixed or incorporated into subsequent
122  *	versions of the library. Each time a bug is fixed, a
123  *	test case is written to prove the fix and ensure
124  *	that later changes to the code don't reintroduce the
125  *	same error. The number of test cases is slowly growing
126  *	and therefore so is the code reliability.
127  *
128  * Compliance:
129  *	See the file ANNOUNCE for the list of implemented
130  *	and not-implemented routines and defined options.
131  *	Of course, these are all defined is this file as well.
132  *
133  * Web site:
134  *	The source code and other information about this library
135  *	are available from
136  *
137  *		http://sources.redhat.com/pthreads-win32/
138  *
139  * -------------------------------------------------------------
140  */
141 
142 /* Try to avoid including windows.h */
143 #if defined(__MINGW32__) && defined(__cplusplus)
144 /*
145  * FIXME: The pthreadGCE.dll build gets linker unresolved errors
146  * on pthread_key_create() unless windows.h is included here.
147  * It appears to have something to do with an argument type mismatch.
148  * Looking at tsd.o with 'nm' shows this line:
149  * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
150  * instead of
151  * 00000000 T _pthread_key_create
152  */
153 #define PTW32_INCLUDE_WINDOWS_H
154 #endif
155 
156 #ifdef PTW32_INCLUDE_WINDOWS_H
157 #include <windows.h>
158 #endif
159 
160 /*
161  * -----------------
162  * autoconf switches
163  * -----------------
164  */
165 
166 #if HAVE_CONFIG_H
167 #include "config.h"
168 #endif /* HAVE_CONFIG_H */
169 
170 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
171 
172 /* Try to avoid including windows.h */
173 #if defined(__MINGW32__) && defined(__cplusplus)
174 /*
175  * FIXME: The pthreadGCE.dll build gets linker unresolved errors
176  * on pthread_key_create() unless windows.h is included here.
177  * It appears to have something to do with an argument type mismatch.
178  * Looking at tsd.o with 'nm' shows this line:
179  * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
180  * instead of
181  * 00000000 T _pthread_key_create
182  */
183 #define PTW32_INCLUDE_WINDOWS_H
184 #endif
185 
186 #ifdef PTW32_INCLUDE_WINDOWS_H
187 #include <windows.h>
188 #endif
189 
190 #ifndef NEED_FTIME
191 #include <time.h>
192 #else /* NEED_FTIME */
193 /* use native WIN32 time API */
194 #endif /* NEED_FTIME */
195 
196 #if HAVE_SIGNAL_H
197 #include <signal.h>
198 #endif /* HAVE_SIGNAL_H */
199 
200 #include <setjmp.h>
201 #include <limits.h>
202 
203 /*
204  * Boolean values to make us independent of system includes.
205  */
206 enum {
207   PTW32_FALSE = 0,
208   PTW32_TRUE = (! PTW32_FALSE)
209 };
210 
211 /*
212  * This is a duplicate of what is in the autoconf config.h,
213  * which is only used when building the pthread-win32 libraries.
214  */
215 
216 #ifndef PTW32_CONFIG_H
217 #  if defined(WINCE)
218 #    define NEED_ERRNO
219 #    define NEED_SEM
220 #  endif
221 #  if defined(_UWIN) || defined(__MINGW32__)
222 #    define HAVE_MODE_T
223 #  endif
224 #endif
225 
226 /*
227  *
228  */
229 
230 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
231 #ifdef NEED_ERRNO
232 #include "need_errno.h"
233 #else
234 #include <errno.h>
235 #endif
236 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
237 
238 /*
239  * Several systems don't define ENOTSUP. If not, we use
240  * the same value as Solaris.
241  */
242 #ifndef ENOTSUP
243 #  define ENOTSUP 48
244 #endif
245 
246 #ifndef ETIMEDOUT
247 #  define ETIMEDOUT 10060     /* This is the value in winsock.h. */
248 #endif
249 
250 #include <sched.h>
251 
252 /*
253  * To avoid including windows.h we define only those things that we
254  * actually need from it. I don't like the potential incompatibility that
255  * this creates with future versions of windows.
256  */
257 #ifndef PTW32_INCLUDE_WINDOWS_H
258 #ifndef HANDLE
259 # define PTW32__HANDLE_DEF
260 # define HANDLE void *
261 #endif
262 #ifndef DWORD
263 # define PTW32__DWORD_DEF
264 # define DWORD unsigned long
265 #endif
266 #endif
267 
268 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
269 
270 #ifndef HAVE_STRUCT_TIMESPEC
271 struct timespec {
272 	long tv_sec;
273 	long tv_nsec;
274 };
275 #endif /* HAVE_STRUCT_TIMESPEC */
276 
277 #ifndef SIG_BLOCK
278 #define SIG_BLOCK 0
279 #endif /* SIG_BLOCK */
280 
281 #ifndef SIG_UNBLOCK
282 #define SIG_UNBLOCK 1
283 #endif /* SIG_UNBLOCK */
284 
285 #ifndef SIG_SETMASK
286 #define SIG_SETMASK 2
287 #endif /* SIG_SETMASK */
288 
289 #ifdef __cplusplus
290 extern "C"
291 {
292 #endif				/* __cplusplus */
293 
294 /*
295  * -------------------------------------------------------------
296  *
297  * POSIX 1003.1-2001 Options
298  * =========================
299  *
300  * _POSIX_THREADS (set)
301  *			If set, you can use threads
302  *
303  * _POSIX_THREAD_ATTR_STACKSIZE (set)
304  *			If set, you can control the size of a thread's
305  *			stack
306  *				pthread_attr_getstacksize
307  *				pthread_attr_setstacksize
308  *
309  * _POSIX_THREAD_ATTR_STACKADDR (not set)
310  *			If set, you can allocate and control a thread's
311  *			stack. If not supported, the following functions
312  *			will return ENOSYS, indicating they are not
313  *			supported:
314  *				pthread_attr_getstackaddr
315  *				pthread_attr_setstackaddr
316  *
317  * _POSIX_THREAD_PRIORITY_SCHEDULING (set)
318  *			If set, you can use realtime scheduling.
319  *			Indicates the availability of:
320  *				pthread_attr_getinheritsched
321  *				pthread_attr_getschedparam
322  *				pthread_attr_getschedpolicy
323  *				pthread_attr_getscope
324  *				pthread_attr_setinheritsched
325  *				pthread_attr_setschedparam
326  *				pthread_attr_setschedpolicy
327  *				pthread_attr_setscope
328  *				pthread_getschedparam
329  *				pthread_setschedparam
330  *				sched_get_priority_max
331  *				sched_get_priority_min
332  *				sched_rr_set_interval
333  *
334  * _POSIX_THREAD_PRIO_INHERIT (not set)
335  *			If set, you can create priority inheritance
336  *			mutexes.
337  *				pthread_mutexattr_getprotocol +
338  *				pthread_mutexattr_setprotocol +
339  *
340  * _POSIX_THREAD_PRIO_PROTECT (not set)
341  *			If set, you can create priority ceiling mutexes
342  *			Indicates the availability of:
343  *				pthread_mutex_getprioceiling
344  *				pthread_mutex_setprioceiling
345  *				pthread_mutexattr_getprioceiling
346  *				pthread_mutexattr_getprotocol	  +
347  *				pthread_mutexattr_setprioceiling
348  *				pthread_mutexattr_setprotocol	  +
349  *
350  * _POSIX_THREAD_PROCESS_SHARED (not set)
351  *			If set, you can create mutexes and condition
352  *			variables that can be shared with another
353  *			process.If set, indicates the availability
354  *			of:
355  *				pthread_mutexattr_getpshared
356  *				pthread_mutexattr_setpshared
357  *				pthread_condattr_getpshared
358  *				pthread_condattr_setpshared
359  *
360  * _POSIX_THREAD_SAFE_FUNCTIONS (set)
361  *			If set you can use the special *_r library
362  *			functions that provide thread-safe behaviour
363  *
364  * _POSIX_READER_WRITER_LOCKS (set)
365  *			If set, you can use read/write locks
366  *
367  * _POSIX_SPIN_LOCKS (set)
368  *			If set, you can use spin locks
369  *
370  * _POSIX_BARRIERS (set)
371  *			If set, you can use barriers
372  *
373  *	+ These functions provide both 'inherit' and/or
374  *	  'protect' protocol, based upon these macro
375  *	  settings.
376  *
377  * POSIX 1003.1-2001 Limits
378  * ===========================
379  *
380  * PTHREAD_DESTRUCTOR_ITERATIONS
381  *			Maximum number of attempts to destroy
382  *			a thread's thread-specific data on
383  *			termination (must be at least 4)
384  *
385  * PTHREAD_KEYS_MAX
386  *			Maximum number of thread-specific data keys
387  *			available per process (must be at least 128)
388  *
389  * PTHREAD_STACK_MIN
390  *			Minimum supported stack size for a thread
391  *
392  * PTHREAD_THREADS_MAX
393  *			Maximum number of threads supported per
394  *			process (must be at least 64).
395  *
396  * _POSIX_SEM_NSEMS_MAX
397  *	The maximum number of semaphores a process can have.
398  *	(only defined if not already defined)
399  *
400  * _POSIX_SEM_VALUE_MAX
401  *	The maximum value a semaphore can have.
402  *	(only defined if not already defined)
403  *
404  * -------------------------------------------------------------
405  */
406 
407 /*
408  * POSIX Options
409  */
410 #ifndef _POSIX_THREADS
411 #define _POSIX_THREADS
412 #endif
413 
414 #ifndef _POSIX_READER_WRITER_LOCKS
415 #define _POSIX_READER_WRITER_LOCKS
416 #endif
417 
418 #ifndef _POSIX_SPIN_LOCKS
419 #define _POSIX_SPIN_LOCKS
420 #endif
421 
422 #ifndef _POSIX_BARRIERS
423 #define _POSIX_BARRIERS
424 #endif
425 
426 #define _POSIX_THREAD_SAFE_FUNCTIONS
427 #define _POSIX_THREAD_ATTR_STACKSIZE
428 #define _POSIX_THREAD_PRIORITY_SCHEDULING
429 
430 #if defined( KLUDGE )
431 /*
432  * The following are not supported
433  */
434 #define _POSIX_THREAD_ATTR_STACKADDR
435 #define _POSIX_THREAD_PRIO_INHERIT
436 #define _POSIX_THREAD_PRIO_PROTECT
437 #define _POSIX_THREAD_PROCESS_SHARED
438 
439 #endif				/* KLUDGE */
440 
441 /*
442  * POSIX Limits
443  *
444  *	PTHREAD_DESTRUCTOR_ITERATIONS
445  *		Standard states this must be at least
446  *		4.
447  *
448  *	PTHREAD_KEYS_MAX
449  *		WIN32 permits only 64 TLS keys per process.
450  *		This limitation could be worked around by
451  *		simply simulating keys.
452  *
453  *	PTHREADS_STACK_MIN
454  *		POSIX specifies 0 which is also the value WIN32
455  *		interprets as allowing the system to
456  *		set the size to that of the main thread. The
457  *		maximum stack size in Win32 is 1Meg. WIN32
458  *		allocates more stack as required up to the 1Meg
459  *		limit.
460  *
461  *	PTHREAD_THREADS_MAX
462  *		Not documented by WIN32. Wrote a test program
463  *		that kept creating threads until it failed
464  *		revealed this approximate number (Windows NT).
465  *		This number is somewhat less for Windows 9x
466  *		and is effectively less than 64. Perhaps this
467  *		constant should be set at DLL load time.
468  *
469  */
470 #define PTHREAD_DESTRUCTOR_ITERATIONS			       4
471 #define PTHREAD_KEYS_MAX			64
472 #define PTHREAD_STACK_MIN			 0
473 #define PTHREAD_THREADS_MAX		      2019
474 #ifndef _POSIX_SEM_NSEMS_MAX
475 /* Not used and only an arbitrary value. */
476 #  define _POSIX_SEM_NSEMS_MAX		      1024
477 #endif
478 #ifndef _POSIX_SEM_VALUE_MAX
479 #  define _POSIX_SEM_VALUE_MAX	       (INT_MAX/2)
480 #endif
481 
482 #if __GNUC__ && ! defined (__declspec)
483 # error Please upgrade your GNU compiler to one that supports __declspec.
484 #endif
485 
486 /*
487  * When building the DLL code, you should define PTW32_BUILD so that
488  * the variables/functions are exported correctly. When using the DLL,
489  * do NOT define PTW32_BUILD, and then the variables/functions will
490  * be imported correctly.
491  */
492 #ifdef _DLL
493 #  ifdef PTW32_BUILD
494 #    define PTW32_DLLPORT __declspec (dllexport)
495 #  else
496 #    define PTW32_DLLPORT __declspec (dllimport)
497 #  endif
498 #endif
499 
500 #if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
501 #   include	<sys/types.h>
502 #else
503 typedef struct pthread_t_ *pthread_t;
504 typedef struct pthread_attr_t_ *pthread_attr_t;
505 typedef struct pthread_once_t_ pthread_once_t;
506 typedef struct pthread_key_t_ *pthread_key_t;
507 typedef struct pthread_mutex_t_ *pthread_mutex_t;
508 typedef struct pthread_mutexattr_t_ *pthread_mutexattr_t;
509 typedef struct pthread_cond_t_ *pthread_cond_t;
510 typedef struct pthread_condattr_t_ *pthread_condattr_t;
511 #endif
512 typedef struct pthread_rwlock_t_ *pthread_rwlock_t;
513 typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t;
514 typedef struct pthread_spinlock_t_ *pthread_spinlock_t;
515 typedef struct pthread_barrier_t_ *pthread_barrier_t;
516 typedef struct pthread_barrierattr_t_ *pthread_barrierattr_t;
517 
518 /*
519  * ====================
520  * ====================
521  * POSIX Threads
522  * ====================
523  * ====================
524  */
525 
526 enum {
527 /*
528  * pthread_attr_{get,set}detachstate
529  */
530   PTHREAD_CREATE_JOINABLE	= 0,  /* Default */
531   PTHREAD_CREATE_DETACHED	= 1,
532 
533 /*
534  * pthread_attr_{get,set}inheritsched
535  */
536   PTHREAD_INHERIT_SCHED 	= 0,
537   PTHREAD_EXPLICIT_SCHED	= 1,  /* Default */
538 
539 /*
540  * pthread_{get,set}scope
541  */
542   PTHREAD_SCOPE_PROCESS 	= 0,
543   PTHREAD_SCOPE_SYSTEM		= 1,  /* Default */
544 
545 /*
546  * pthread_setcancelstate paramters
547  */
548   PTHREAD_CANCEL_ENABLE 	= 0,  /* Default */
549   PTHREAD_CANCEL_DISABLE	= 1,
550 
551 /*
552  * pthread_setcanceltype parameters
553  */
554   PTHREAD_CANCEL_ASYNCHRONOUS	= 0,
555   PTHREAD_CANCEL_DEFERRED	= 1,  /* Default */
556 
557 /*
558  * pthread_mutexattr_{get,set}pshared
559  * pthread_condattr_{get,set}pshared
560  */
561   PTHREAD_PROCESS_PRIVATE	= 0,
562   PTHREAD_PROCESS_SHARED	= 1,
563 
564 /*
565  * pthread_barrier_wait
566  */
567   PTHREAD_BARRIER_SERIAL_THREAD = -1
568 };
569 
570 /*
571  * ====================
572  * ====================
573  * Cancelation
574  * ====================
575  * ====================
576  */
577 #define PTHREAD_CANCELED       ((void *) -1)
578 
579 
580 /*
581  * ====================
582  * ====================
583  * Once Key
584  * ====================
585  * ====================
586  */
587 #define PTHREAD_ONCE_INIT	{ PTW32_FALSE, -1 }
588 
589 struct pthread_once_t_
590 {
591   int done;		    /* indicates if user function executed  */
592   long started; 	    /* First thread to increment this value */
593 			    /* to zero executes the user function   */
594 };
595 
596 
597 /*
598  * ====================
599  * ====================
600  * Object initialisers
601  * ====================
602  * ====================
603  */
604 #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
605 
606 #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
607 
608 #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
609 
610 #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
611 
612 
613 /*
614  * Mutex types.
615  */
616 enum
617 {
618   /* Compatibility with LinuxThreads */
619   PTHREAD_MUTEX_FAST_NP,
620   PTHREAD_MUTEX_RECURSIVE_NP,
621   PTHREAD_MUTEX_ERRORCHECK_NP,
622   PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
623   PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
624   /* For compatibility with POSIX */
625   PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
626   PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
627   PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
628   PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
629 };
630 
631 
632 /* There are three implementations of cancel cleanup.
633  * Note that pthread.h is included in both application
634  * compilation units and also internally for the library.
635  * The code here and within the library aims to work
636  * for all reasonable combinations of environments.
637  *
638  * The three implementations are:
639  *
640  *   WIN32 SEH
641  *   C
642  *   C++
643  *
644  * Please note that exiting a push/pop block via
645  * "return", "exit", "break", or "continue" will
646  * lead to different behaviour amongst applications
647  * depending upon whether the library was built
648  * using SEH, C++, or C. For example, a library built
649  * with SEH will call the cleanup routine, while both
650  * C++ and C built versions will not.
651  */
652 
653 /*
654  * Define defaults for cleanup code.
655  * Note: Unless the build explicitly defines one of the following, then
656  * we default to standard C style cleanup. This style uses setjmp/longjmp
657  * in the cancelation and thread exit implementations and therefore won't
658  * do stack unwinding if linked to applications that have it (e.g.
659  * C++ apps). This is currently consistent with most/all commercial Unix
660  * POSIX threads implementations.
661  */
662 #if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
663 # define __CLEANUP_C
664 #endif
665 
666 #if defined( __CLEANUP_SEH ) && defined(__GNUC__)
667 #error ERROR [__FILE__, line __LINE__]: GNUC does not support SEH.
668 #endif
669 
670 typedef struct ptw32_cleanup_t ptw32_cleanup_t;
671 typedef void (__cdecl *ptw32_cleanup_callback_t)(void *);
672 
673 struct ptw32_cleanup_t
674 {
675   ptw32_cleanup_callback_t routine;
676   void *arg;
677   struct ptw32_cleanup_t *prev;
678 };
679 
680 #ifdef __CLEANUP_SEH
681 	/*
682 	 * WIN32 SEH version of cancel cleanup.
683 	 */
684 
685 #define pthread_cleanup_push( _rout, _arg ) \
686 	{ \
687 	    ptw32_cleanup_t	_cleanup; \
688 	    \
689 	_cleanup.routine	= (ptw32_cleanup_callback_t)(_rout); \
690 	    _cleanup.arg	= (_arg); \
691 	    __try \
692 	      { \
693 
694 #define pthread_cleanup_pop( _execute ) \
695 	      } \
696 	    __finally \
697 		{ \
698 		    if( _execute || AbnormalTermination()) \
699 		      { \
700 			  (*(_cleanup.routine))( _cleanup.arg ); \
701 		      } \
702 		} \
703 	}
704 
705 #else /* __CLEANUP_SEH */
706 
707 #ifdef __CLEANUP_C
708 
709 	/*
710 	 * C implementation of PThreads cancel cleanup
711 	 */
712 
713 #define pthread_cleanup_push( _rout, _arg ) \
714 	{ \
715 	    ptw32_cleanup_t	_cleanup; \
716 	    \
717 	    ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
718 
719 #define pthread_cleanup_pop( _execute ) \
720 	    (void) ptw32_pop_cleanup( _execute ); \
721 	}
722 
723 #else /* __CLEANUP_C */
724 
725 #ifdef __CLEANUP_CXX
726 
727 	/*
728 	 * C++ version of cancel cleanup.
729 	 * - John E. Bossom.
730 	 */
731 
732 	class PThreadCleanup {
733 	  /*
734 	   * PThreadCleanup
735 	   *
736 	   * Purpose
737 	   *	  This class is a C++ helper class that is
738 	   *	  used to implement pthread_cleanup_push/
739 	   *	  pthread_cleanup_pop.
740 	   *	  The destructor of this class automatically
741 	   *	  pops the pushed cleanup routine regardless
742 	   *	  of how the code exits the scope
743 	   *	  (i.e. such as by an exception)
744 	   */
745       ptw32_cleanup_callback_t cleanUpRout;
746 	  void	  *	  obj;
747 	  int		  executeIt;
748 
749 	public:
PThreadCleanup()750 	  PThreadCleanup() :
751 	    cleanUpRout( 0 ),
752 	    obj( 0 ),
753 	    executeIt( 0 )
754 	    /*
755 	     * No cleanup performed
756 	     */
757 	    {
758 	    }
759 
PThreadCleanup(ptw32_cleanup_callback_t routine,void * arg)760 	  PThreadCleanup(
761 	     ptw32_cleanup_callback_t routine,
762 			 void	 *	 arg ) :
763 	    cleanUpRout( routine ),
764 	    obj( arg ),
765 	    executeIt( 1 )
766 	    /*
767 	     * Registers a cleanup routine for 'arg'
768 	     */
769 	    {
770 	    }
771 
~PThreadCleanup()772 	  ~PThreadCleanup()
773 	    {
774 	      if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
775 		{
776 		  (void) (*cleanUpRout)( obj );
777 		}
778 	    }
779 
execute(int exec)780 	  void execute( int exec )
781 	    {
782 	      executeIt = exec;
783 	    }
784 	};
785 
786 	/*
787 	 * C++ implementation of PThreads cancel cleanup;
788 	 * This implementation takes advantage of a helper
789 	 * class who's destructor automatically calls the
790 	 * cleanup routine if we exit our scope weirdly
791 	 */
792 #define pthread_cleanup_push( _rout, _arg ) \
793 	{ \
794 	    PThreadCleanup  cleanup((ptw32_cleanup_callback_t)(_rout), \
795 				    (void *) (_arg) );
796 
797 #define pthread_cleanup_pop( _execute ) \
798 	    cleanup.execute( _execute ); \
799 	}
800 
801 #else
802 
803 #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
804 
805 #endif /* __CLEANUP_CXX */
806 
807 #endif /* __CLEANUP_C */
808 
809 #endif /* __CLEANUP_SEH */
810 
811 /*
812  * ===============
813  * ===============
814  * Methods
815  * ===============
816  * ===============
817  */
818 
819 /*
820  * PThread Attribute Functions
821  */
822 PTW32_DLLPORT int pthread_attr_init (pthread_attr_t * attr);
823 
824 PTW32_DLLPORT int pthread_attr_destroy (pthread_attr_t * attr);
825 
826 PTW32_DLLPORT int pthread_attr_getdetachstate (const pthread_attr_t * attr,
827 					 int *detachstate);
828 
829 PTW32_DLLPORT int pthread_attr_getstackaddr (const pthread_attr_t * attr,
830 				       void **stackaddr);
831 
832 PTW32_DLLPORT int pthread_attr_getstacksize (const pthread_attr_t * attr,
833 				       size_t * stacksize);
834 
835 PTW32_DLLPORT int pthread_attr_setdetachstate (pthread_attr_t * attr,
836 					 int detachstate);
837 
838 PTW32_DLLPORT int pthread_attr_setstackaddr (pthread_attr_t * attr,
839 				       void *stackaddr);
840 
841 PTW32_DLLPORT int pthread_attr_setstacksize (pthread_attr_t * attr,
842 				       size_t stacksize);
843 
844 PTW32_DLLPORT int pthread_attr_getschedparam (const pthread_attr_t *attr,
845 					struct sched_param *param);
846 
847 PTW32_DLLPORT int pthread_attr_setschedparam (pthread_attr_t *attr,
848 					const struct sched_param *param);
849 
850 PTW32_DLLPORT int pthread_attr_setschedpolicy (pthread_attr_t *,
851 					 int);
852 
853 PTW32_DLLPORT int pthread_attr_getschedpolicy (pthread_attr_t *,
854 					 int *);
855 
856 PTW32_DLLPORT int pthread_attr_setinheritsched(pthread_attr_t * attr,
857 					 int inheritsched);
858 
859 PTW32_DLLPORT int pthread_attr_getinheritsched(pthread_attr_t * attr,
860 					 int * inheritsched);
861 
862 PTW32_DLLPORT int pthread_attr_setscope (pthread_attr_t *,
863 				   int);
864 
865 PTW32_DLLPORT int pthread_attr_getscope (const pthread_attr_t *,
866 				   int *);
867 
868 /*
869  * PThread Functions
870  */
871 PTW32_DLLPORT int pthread_create (pthread_t * tid,
872 			    const pthread_attr_t * attr,
873 			    void *(*start) (void *),
874 			    void *arg);
875 
876 PTW32_DLLPORT int pthread_detach (pthread_t tid);
877 
878 PTW32_DLLPORT int pthread_equal (pthread_t t1,
879 			   pthread_t t2);
880 
881 PTW32_DLLPORT void pthread_exit (void *value_ptr);
882 
883 PTW32_DLLPORT int pthread_join (pthread_t thread,
884 			  void **value_ptr);
885 
886 PTW32_DLLPORT pthread_t pthread_self (void);
887 
888 PTW32_DLLPORT int pthread_cancel (pthread_t thread);
889 
890 PTW32_DLLPORT int pthread_setcancelstate (int state,
891 				    int *oldstate);
892 
893 PTW32_DLLPORT int pthread_setcanceltype (int type,
894 				   int *oldtype);
895 
896 PTW32_DLLPORT void pthread_testcancel (void);
897 
898 PTW32_DLLPORT int pthread_once (pthread_once_t * once_control,
899 			  void (*init_routine) (void));
900 
901 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
902 PTW32_DLLPORT ptw32_cleanup_t *ptw32_pop_cleanup (int execute);
903 
904 PTW32_DLLPORT void ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
905 				 void (*routine) (void *),
906 				 void *arg);
907 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
908 
909 /*
910  * Thread Specific Data Functions
911  */
912 PTW32_DLLPORT int pthread_key_create (pthread_key_t * key,
913 				void (*destructor) (void *));
914 
915 PTW32_DLLPORT int pthread_key_delete (pthread_key_t key);
916 
917 PTW32_DLLPORT int pthread_setspecific (pthread_key_t key,
918 				 const void *value);
919 
920 PTW32_DLLPORT void *pthread_getspecific (pthread_key_t key);
921 
922 
923 /*
924  * Mutex Attribute Functions
925  */
926 PTW32_DLLPORT int pthread_mutexattr_init (pthread_mutexattr_t * attr);
927 
928 PTW32_DLLPORT int pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
929 
930 PTW32_DLLPORT int pthread_mutexattr_getpshared (const pthread_mutexattr_t
931 					  * attr,
932 					  int *pshared);
933 
934 PTW32_DLLPORT int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
935 					  int pshared);
936 
937 PTW32_DLLPORT int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
938 PTW32_DLLPORT int pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
939 
940 /*
941  * Barrier Attribute Functions
942  */
943 PTW32_DLLPORT int pthread_barrierattr_init (pthread_barrierattr_t * attr);
944 
945 PTW32_DLLPORT int pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
946 
947 PTW32_DLLPORT int pthread_barrierattr_getpshared (const pthread_barrierattr_t
948 					    * attr,
949 					    int *pshared);
950 
951 PTW32_DLLPORT int pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
952 					    int pshared);
953 
954 /*
955  * Mutex Functions
956  */
957 PTW32_DLLPORT int pthread_mutex_init (pthread_mutex_t * mutex,
958 				const pthread_mutexattr_t * attr);
959 
960 PTW32_DLLPORT int pthread_mutex_destroy (pthread_mutex_t * mutex);
961 
962 PTW32_DLLPORT int pthread_mutex_lock (pthread_mutex_t * mutex);
963 
964 PTW32_DLLPORT int pthread_mutex_timedlock(pthread_mutex_t *mutex,
965 				    const struct timespec *abstime);
966 
967 PTW32_DLLPORT int pthread_mutex_trylock (pthread_mutex_t * mutex);
968 
969 PTW32_DLLPORT int pthread_mutex_unlock (pthread_mutex_t * mutex);
970 
971 /*
972  * Spinlock Functions
973  */
974 PTW32_DLLPORT int pthread_spin_init (pthread_spinlock_t * lock, int pshared);
975 
976 PTW32_DLLPORT int pthread_spin_destroy (pthread_spinlock_t * lock);
977 
978 PTW32_DLLPORT int pthread_spin_lock (pthread_spinlock_t * lock);
979 
980 PTW32_DLLPORT int pthread_spin_trylock (pthread_spinlock_t * lock);
981 
982 PTW32_DLLPORT int pthread_spin_unlock (pthread_spinlock_t * lock);
983 
984 /*
985  * Barrier Functions
986  */
987 PTW32_DLLPORT int pthread_barrier_init (pthread_barrier_t * barrier,
988 				  const pthread_barrierattr_t * attr,
989 				  unsigned int count);
990 
991 PTW32_DLLPORT int pthread_barrier_destroy (pthread_barrier_t * barrier);
992 
993 PTW32_DLLPORT int pthread_barrier_wait (pthread_barrier_t * barrier);
994 
995 /*
996  * Condition Variable Attribute Functions
997  */
998 PTW32_DLLPORT int pthread_condattr_init (pthread_condattr_t * attr);
999 
1000 PTW32_DLLPORT int pthread_condattr_destroy (pthread_condattr_t * attr);
1001 
1002 PTW32_DLLPORT int pthread_condattr_getpshared (const pthread_condattr_t * attr,
1003 					 int *pshared);
1004 
1005 PTW32_DLLPORT int pthread_condattr_setpshared (pthread_condattr_t * attr,
1006 					 int pshared);
1007 
1008 /*
1009  * Condition Variable Functions
1010  */
1011 PTW32_DLLPORT int pthread_cond_init (pthread_cond_t * cond,
1012 			       const pthread_condattr_t * attr);
1013 
1014 PTW32_DLLPORT int pthread_cond_destroy (pthread_cond_t * cond);
1015 
1016 PTW32_DLLPORT int pthread_cond_wait (pthread_cond_t * cond,
1017 			       pthread_mutex_t * mutex);
1018 
1019 PTW32_DLLPORT int pthread_cond_timedwait (pthread_cond_t * cond,
1020 				    pthread_mutex_t * mutex,
1021 				    const struct timespec *abstime);
1022 
1023 PTW32_DLLPORT int pthread_cond_signal (pthread_cond_t * cond);
1024 
1025 PTW32_DLLPORT int pthread_cond_broadcast (pthread_cond_t * cond);
1026 
1027 /*
1028  * Scheduling
1029  */
1030 PTW32_DLLPORT int pthread_setschedparam (pthread_t thread,
1031 				   int policy,
1032 				   const struct sched_param *param);
1033 
1034 PTW32_DLLPORT int pthread_getschedparam (pthread_t thread,
1035 				   int *policy,
1036 				   struct sched_param *param);
1037 
1038 PTW32_DLLPORT int pthread_setconcurrency (int);
1039 
1040 PTW32_DLLPORT int pthread_getconcurrency (void);
1041 
1042 /*
1043  * Read-Write Lock Functions
1044  */
1045 PTW32_DLLPORT int pthread_rwlock_init(pthread_rwlock_t *lock,
1046 				const pthread_rwlockattr_t *attr);
1047 
1048 PTW32_DLLPORT int pthread_rwlock_destroy(pthread_rwlock_t *lock);
1049 
1050 PTW32_DLLPORT int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
1051 
1052 PTW32_DLLPORT int pthread_rwlock_trywrlock(pthread_rwlock_t *);
1053 
1054 PTW32_DLLPORT int pthread_rwlock_rdlock(pthread_rwlock_t *lock);
1055 
1056 PTW32_DLLPORT int pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
1057 				       const struct timespec *abstime);
1058 
1059 PTW32_DLLPORT int pthread_rwlock_wrlock(pthread_rwlock_t *lock);
1060 
1061 PTW32_DLLPORT int pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
1062 				       const struct timespec *abstime);
1063 
1064 PTW32_DLLPORT int pthread_rwlock_unlock(pthread_rwlock_t *lock);
1065 
1066 PTW32_DLLPORT int pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
1067 
1068 PTW32_DLLPORT int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
1069 
1070 PTW32_DLLPORT int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
1071 					   int *pshared);
1072 
1073 PTW32_DLLPORT int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
1074 					   int pshared);
1075 
1076 #if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
1077 
1078 /*
1079  * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
1080  * already have signal.h that don't define these.
1081  */
1082 PTW32_DLLPORT int pthread_kill(pthread_t thread, int sig);
1083 
1084 /*
1085  * Non-portable functions
1086  */
1087 
1088 /*
1089  * Compatibility with Linux.
1090  */
1091 PTW32_DLLPORT int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
1092 					 int kind);
1093 PTW32_DLLPORT int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
1094 					 int *kind);
1095 
1096 /*
1097  * Possibly supported by other POSIX threads implementations
1098  */
1099 PTW32_DLLPORT int pthread_delay_np (struct timespec * interval);
1100 PTW32_DLLPORT int pthread_num_processors_np(void);
1101 
1102 /*
1103  * Useful if an application wants to statically link
1104  * the lib rather than load the DLL at run-time.
1105  */
1106 PTW32_DLLPORT int pthread_win32_process_attach_np(void);
1107 PTW32_DLLPORT int pthread_win32_process_detach_np(void);
1108 PTW32_DLLPORT int pthread_win32_thread_attach_np(void);
1109 PTW32_DLLPORT int pthread_win32_thread_detach_np(void);
1110 
1111 /*
1112  * Register a system time change with the library.
1113  * Causes the library to perform various functions
1114  * in response to the change. Should be called whenever
1115  * the application's top level window receives a
1116  * WM_TIMECHANGE message. It can be passed directly to
1117  * pthread_create() as a new thread if desired.
1118  */
1119 PTW32_DLLPORT void * pthread_timechange_handler_np(void *);
1120 
1121 #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
1122 
1123 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
1124 
1125 /*
1126  * Returns the Win32 HANDLE for the POSIX thread.
1127  */
1128 PTW32_DLLPORT HANDLE pthread_getw32threadhandle_np(pthread_t thread);
1129 
1130 
1131 /*
1132  * Protected Methods
1133  *
1134  * This function blocks until the given WIN32 handle
1135  * is signaled or pthread_cancel had been called.
1136  * This function allows the caller to hook into the
1137  * PThreads cancel mechanism. It is implemented using
1138  *
1139  *		WaitForMultipleObjects
1140  *
1141  * on 'waitHandle' and a manually reset WIN32 Event
1142  * used to implement pthread_cancel. The 'timeout'
1143  * argument to TimedWait is simply passed to
1144  * WaitForMultipleObjects.
1145  */
1146 PTW32_DLLPORT int pthreadCancelableWait (HANDLE waitHandle);
1147 PTW32_DLLPORT int pthreadCancelableTimedWait (HANDLE waitHandle,
1148 					DWORD timeout);
1149 
1150 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
1151 
1152 /*
1153  * Thread-Safe C Runtime Library Mappings.
1154  */
1155 #ifndef _UWIN
1156 #  if defined(NEED_ERRNO)
1157      PTW32_DLLPORT int * _errno( void );
1158 #  else
1159 #    ifndef errno
1160 #      if (defined(_MT) || defined(_DLL))
1161 	 __declspec(dllimport) extern int * __cdecl _errno(void);
1162 #	 define errno	(*_errno())
1163 #      endif
1164 #    endif
1165 #  endif
1166 #endif
1167 
1168 /*
1169  * WIN32 C runtime library had been made thread-safe
1170  * without affecting the user interface. Provide
1171  * mappings from the UNIX thread-safe versions to
1172  * the standard C runtime library calls.
1173  * Only provide function mappings for functions that
1174  * actually exist on WIN32.
1175  */
1176 
1177 #if !defined(__MINGW32__)
1178 #define strtok_r( _s, _sep, _lasts ) \
1179 	( *(_lasts) = strtok( (_s), (_sep) ) )
1180 #endif /* !__MINGW32__ */
1181 
1182 #define asctime_r( _tm, _buf ) \
1183 	( strcpy( (_buf), asctime( (_tm) ) ), \
1184 	  (_buf) )
1185 
1186 #define ctime_r( _clock, _buf ) \
1187 	( strcpy( (_buf), ctime( (_clock) ) ),	\
1188 	  (_buf) )
1189 
1190 #define gmtime_r( _clock, _result ) \
1191 	( *(_result) = *gmtime( (_clock) ), \
1192 	  (_result) )
1193 
1194 #define localtime_r( _clock, _result ) \
1195 	( *(_result) = *localtime( (_clock) ), \
1196 	  (_result) )
1197 
1198 #define rand_r( _seed ) \
1199 	( _seed == _seed? rand() : rand() )
1200 
1201 
1202 #ifdef __cplusplus
1203 
1204 /*
1205  * Internal exceptions
1206  */
1207 class ptw32_exception {};
1208 class ptw32_exception_cancel : public ptw32_exception {};
1209 class ptw32_exception_exit   : public ptw32_exception {};
1210 
1211 #endif
1212 
1213 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
1214 
1215 /* FIXME: This is only required if the library was built using SEH */
1216 /*
1217  * Get internal SEH tag
1218  */
1219 PTW32_DLLPORT DWORD ptw32_get_exception_services_code(void);
1220 
1221 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
1222 
1223 #ifndef PTW32_BUILD
1224 
1225 #ifdef __CLEANUP_SEH
1226 
1227 /*
1228  * Redefine the SEH __except keyword to ensure that applications
1229  * propagate our internal exceptions up to the library's internal handlers.
1230  */
1231 #define __except( E ) \
1232 	__except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
1233 		 ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
1234 
1235 #endif /* __CLEANUP_SEH */
1236 
1237 #ifdef __CLEANUP_CXX
1238 
1239 /*
1240  * Redefine the C++ catch keyword to ensure that applications
1241  * propagate our internal exceptions up to the library's internal handlers.
1242  */
1243 #ifdef _MSC_VER
1244 	/*
1245 	 * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
1246 	 * if you want Pthread-Win32 cancelation and pthread_exit to work.
1247 	 */
1248 
1249 #ifndef PtW32NoCatchWarn
1250 
1251 #pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
1252 #pragma message("------------------------------------------------------------------")
1253 #pragma message("When compiling applications with MSVC++ and C++ exception handling:")
1254 #pragma message("  Replace any 'catch( ... )' in routines called from POSIX threads")
1255 #pragma message("  with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
1256 #pragma message("  cancelation and pthread_exit to work. For example:")
1257 #pragma message("")
1258 #pragma message("    #ifdef PtW32CatchAll")
1259 #pragma message("      PtW32CatchAll")
1260 #pragma message("    #else")
1261 #pragma message("      catch(...)")
1262 #pragma message("    #endif")
1263 #pragma message("	 {")
1264 #pragma message("	   /* Catchall block processing */")
1265 #pragma message("	 }")
1266 #pragma message("------------------------------------------------------------------")
1267 
1268 #endif
1269 
1270 #define PtW32CatchAll \
1271 	catch( ptw32_exception & ) { throw; } \
1272 	catch( ... )
1273 
1274 #else /* _MSC_VER */
1275 
1276 #define catch( E ) \
1277 	catch( ptw32_exception & ) { throw; } \
1278 	catch( E )
1279 
1280 #endif /* _MSC_VER */
1281 
1282 #endif /* __CLEANUP_CXX */
1283 
1284 #endif /* ! PTW32_BUILD */
1285 
1286 #ifdef __cplusplus
1287 }				/* End of extern "C" */
1288 #endif				/* __cplusplus */
1289 
1290 #ifdef PTW32__HANDLE_DEF
1291 # undef HANDLE
1292 #endif
1293 #ifdef PTW32__DWORD_DEF
1294 # undef DWORD
1295 #endif
1296 
1297 #undef PTW32_LEVEL
1298 #undef PTW32_LEVEL_MAX
1299 
1300 #endif /* PTHREAD_H */
1301