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