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