1 /* This is an implementation of the threads API of POSIX 1003.1-2001.
\r
3 * --------------------------------------------------------------------------
\r
5 * Pthreads-win32 - POSIX Threads Library for Win32
\r
6 * Copyright(C) 1998 John E. Bossom
\r
7 * Copyright(C) 1999,2005 Pthreads-win32 contributors
\r
9 * Contact Email: rpj@callisto.canberra.edu.au
\r
11 * The current list of contributors is contained
\r
12 * in the file CONTRIBUTORS included with the source
\r
13 * code distribution. The list can also be seen at the
\r
14 * following World Wide Web location:
\r
15 * http://sources.redhat.com/pthreads-win32/contributors.html
\r
17 * This library is free software; you can redistribute it and/or
\r
18 * modify it under the terms of the GNU Lesser General Public
\r
19 * License as published by the Free Software Foundation; either
\r
20 * version 2 of the License, or (at your option) any later version.
\r
22 * This library is distributed in the hope that it will be useful,
\r
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
25 * Lesser General Public License for more details.
\r
27 * You should have received a copy of the GNU Lesser General Public
\r
28 * License along with this library in the file COPYING.LIB;
\r
29 * if not, write to the Free Software Foundation, Inc.,
\r
30 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
\r
33 #if !defined( PTHREAD_H )
\r
37 * See the README file for an explanation of the pthreads-win32 version
\r
38 * numbering scheme and how the DLL is named etc.
\r
40 #define PTW32_VERSION 2,8,0,0
\r
41 #define PTW32_VERSION_STRING "2, 8, 0, 0\0"
\r
43 /* There are three implementations of cancel cleanup.
\r
44 * Note that pthread.h is included in both application
\r
45 * compilation units and also internally for the library.
\r
46 * The code here and within the library aims to work
\r
47 * for all reasonable combinations of environments.
\r
49 * The three implementations are:
\r
55 * Please note that exiting a push/pop block via
\r
56 * "return", "exit", "break", or "continue" will
\r
57 * lead to different behaviour amongst applications
\r
58 * depending upon whether the library was built
\r
59 * using SEH, C++, or C. For example, a library built
\r
60 * with SEH will call the cleanup routine, while both
\r
61 * C++ and C built versions will not.
\r
65 * Define defaults for cleanup code.
\r
66 * Note: Unless the build explicitly defines one of the following, then
\r
67 * we default to standard C style cleanup. This style uses setjmp/longjmp
\r
68 * in the cancelation and thread exit implementations and therefore won't
\r
69 * do stack unwinding if linked to applications that have it (e.g.
\r
70 * C++ apps). This is currently consistent with most/all commercial Unix
\r
71 * POSIX threads implementations.
\r
73 #if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
\r
74 # define __CLEANUP_C
\r
77 #if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
\r
78 #error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
\r
82 * Stop here if we are being included by the resource compiler.
\r
88 #if defined(_POSIX_SOURCE)
\r
89 #define PTW32_LEVEL 0
\r
93 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
\r
95 #define PTW32_LEVEL 1
\r
96 /* Include 1b, 1c and 1d */
\r
99 #if defined(INCLUDE_NP)
\r
101 #define PTW32_LEVEL 2
\r
102 /* Include Non-Portable extensions */
\r
105 #define PTW32_LEVEL_MAX 3
\r
107 #if !defined(PTW32_LEVEL)
\r
108 #define PTW32_LEVEL PTW32_LEVEL_MAX
\r
109 /* Include everything */
\r
113 # define HAVE_STRUCT_TIMESPEC 1
\r
114 # define HAVE_SIGNAL_H 1
\r
115 # undef HAVE_CONFIG_H
\r
116 # pragma comment(lib, "pthread")
\r
120 * -------------------------------------------------------------
\r
123 * Module: pthread.h
\r
126 * Provides an implementation of PThreads based upon the
\r
129 * POSIX 1003.1-2001
\r
131 * The Single Unix Specification version 3
\r
133 * (these two are equivalent)
\r
135 * in order to enhance code portability between Windows,
\r
136 * various commercial Unix implementations, and Linux.
\r
138 * See the ANNOUNCE file for a full list of conforming
\r
139 * routines and defined constants, and a list of missing
\r
140 * routines and constants not defined in this implementation.
\r
143 * There have been many contributors to this library.
\r
144 * The initial implementation was contributed by
\r
145 * John Bossom, and several others have provided major
\r
146 * sections or revisions of parts of the implementation.
\r
147 * Often significant effort has been contributed to
\r
148 * find and fix important bugs and other problems to
\r
149 * improve the reliability of the library, which sometimes
\r
150 * is not reflected in the amount of code which changed as
\r
152 * As much as possible, the contributors are acknowledged
\r
153 * in the ChangeLog file in the source code distribution
\r
154 * where their changes are noted in detail.
\r
156 * Contributors are listed in the CONTRIBUTORS file.
\r
158 * As usual, all bouquets go to the contributors, and all
\r
159 * brickbats go to the project maintainer.
\r
162 * The code base for this project is coordinated and
\r
163 * eventually pre-tested, packaged, and made available by
\r
165 * Ross Johnson <rpj@callisto.canberra.edu.au>
\r
168 * Ultimately, the library is tested in the real world by
\r
169 * a host of competent and demanding scientists and
\r
170 * engineers who report bugs and/or provide solutions
\r
171 * which are then fixed or incorporated into subsequent
\r
172 * versions of the library. Each time a bug is fixed, a
\r
173 * test case is written to prove the fix and ensure
\r
174 * that later changes to the code don't reintroduce the
\r
175 * same error. The number of test cases is slowly growing
\r
176 * and therefore so is the code reliability.
\r
179 * See the file ANNOUNCE for the list of implemented
\r
180 * and not-implemented routines and defined options.
\r
181 * Of course, these are all defined is this file as well.
\r
184 * The source code and other information about this library
\r
185 * are available from
\r
187 * http://sources.redhat.com/pthreads-win32/
\r
189 * -------------------------------------------------------------
\r
192 /* Try to avoid including windows.h */
\r
193 #if defined(__MINGW32__) && defined(__cplusplus)
\r
194 #define PTW32_INCLUDE_WINDOWS_H
\r
197 #ifdef PTW32_INCLUDE_WINDOWS_H
\r
198 #include <windows.h>
\r
201 #if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
\r
203 * VC++6.0 or early compiler's header has no DWORD_PTR type.
\r
205 typedef unsigned long DWORD_PTR;
\r
208 * -----------------
\r
209 * autoconf switches
\r
210 * -----------------
\r
214 #include "config.h"
\r
215 #endif /* HAVE_CONFIG_H */
\r
219 #else /* NEED_FTIME */
\r
220 /* use native WIN32 time API */
\r
221 #endif /* NEED_FTIME */
\r
224 #include <signal.h>
\r
225 #endif /* HAVE_SIGNAL_H */
\r
227 #include <setjmp.h>
\r
228 #include <limits.h>
\r
231 * Boolean values to make us independent of system includes.
\r
235 PTW32_TRUE = (!PTW32_FALSE)
\r
239 * This is a duplicate of what is in the autoconf config.h,
\r
240 * which is only used when building the pthread-win32 libraries.
\r
243 #ifndef PTW32_CONFIG_H
\r
244 # if defined(WINCE)
\r
245 # define NEED_ERRNO
\r
248 # if defined(_UWIN) || defined(__MINGW32__)
\r
249 # define HAVE_MODE_T
\r
257 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
\r
259 #include "need_errno.h"
\r
263 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
\r
266 * Several systems don't define some error numbers.
\r
269 # define ENOTSUP 48 /* This is the value in Solaris. */
\r
273 # define ETIMEDOUT 10060 /* This is the value in winsock.h. */
\r
277 # define ENOSYS 140 /* Semi-arbitrary value */
\r
282 # define EDEADLK EDEADLOCK
\r
284 # define EDEADLK 36 /* This is the value in MSVC. */
\r
291 * To avoid including windows.h we define only those things that we
\r
292 * actually need from it.
\r
294 #ifndef PTW32_INCLUDE_WINDOWS_H
\r
296 # define PTW32__HANDLE_DEF
\r
297 # define HANDLE void *
\r
300 # define PTW32__DWORD_DEF
\r
301 # define DWORD unsigned long
\r
305 #ifndef _CRT_NO_TIME_T
\r
306 #define HAVE_STRUCT_TIMESPEC 1
\r
309 #ifndef HAVE_STRUCT_TIMESPEC
\r
310 #define HAVE_STRUCT_TIMESPEC 1
\r
315 #endif /* HAVE_STRUCT_TIMESPEC */
\r
318 #define SIG_BLOCK 0
\r
319 #endif /* SIG_BLOCK */
\r
321 #ifndef SIG_UNBLOCK
\r
322 #define SIG_UNBLOCK 1
\r
323 #endif /* SIG_UNBLOCK */
\r
325 #ifndef SIG_SETMASK
\r
326 #define SIG_SETMASK 2
\r
327 #endif /* SIG_SETMASK */
\r
332 #endif /* __cplusplus */
\r
335 * -------------------------------------------------------------
\r
337 * POSIX 1003.1-2001 Options
\r
338 * =========================
\r
340 * Options are normally set in <unistd.h>, which is not provided
\r
341 * with pthreads-win32.
\r
343 * For conformance with the Single Unix Specification (version 3), all of the
\r
344 * options below are defined, and have a value of either -1 (not supported)
\r
345 * or 200112L (supported).
\r
347 * These options can neither be left undefined nor have a value of 0, because
\r
348 * either indicates that sysconf(), which is not implemented, may be used at
\r
349 * runtime to check the status of the option.
\r
351 * _POSIX_THREADS (== 200112L)
\r
352 * If == 200112L, you can use threads
\r
354 * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
\r
355 * If == 200112L, you can control the size of a thread's
\r
357 * pthread_attr_getstacksize
\r
358 * pthread_attr_setstacksize
\r
360 * _POSIX_THREAD_ATTR_STACKADDR (== -1)
\r
361 * If == 200112L, you can allocate and control a thread's
\r
362 * stack. If not supported, the following functions
\r
363 * will return ENOSYS, indicating they are not
\r
365 * pthread_attr_getstackaddr
\r
366 * pthread_attr_setstackaddr
\r
368 * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
\r
369 * If == 200112L, you can use realtime scheduling.
\r
370 * This option indicates that the behaviour of some
\r
371 * implemented functions conforms to the additional TPS
\r
372 * requirements in the standard. E.g. rwlocks favour
\r
373 * writers over readers when threads have equal priority.
\r
375 * _POSIX_THREAD_PRIO_INHERIT (== -1)
\r
376 * If == 200112L, you can create priority inheritance
\r
378 * pthread_mutexattr_getprotocol +
\r
379 * pthread_mutexattr_setprotocol +
\r
381 * _POSIX_THREAD_PRIO_PROTECT (== -1)
\r
382 * If == 200112L, you can create priority ceiling mutexes
\r
383 * Indicates the availability of:
\r
384 * pthread_mutex_getprioceiling
\r
385 * pthread_mutex_setprioceiling
\r
386 * pthread_mutexattr_getprioceiling
\r
387 * pthread_mutexattr_getprotocol +
\r
388 * pthread_mutexattr_setprioceiling
\r
389 * pthread_mutexattr_setprotocol +
\r
391 * _POSIX_THREAD_PROCESS_SHARED (== -1)
\r
392 * If set, you can create mutexes and condition
\r
393 * variables that can be shared with another
\r
394 * process.If set, indicates the availability
\r
396 * pthread_mutexattr_getpshared
\r
397 * pthread_mutexattr_setpshared
\r
398 * pthread_condattr_getpshared
\r
399 * pthread_condattr_setpshared
\r
401 * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
\r
402 * If == 200112L you can use the special *_r library
\r
403 * functions that provide thread-safe behaviour
\r
405 * _POSIX_READER_WRITER_LOCKS (== 200112L)
\r
406 * If == 200112L, you can use read/write locks
\r
408 * _POSIX_SPIN_LOCKS (== 200112L)
\r
409 * If == 200112L, you can use spin locks
\r
411 * _POSIX_BARRIERS (== 200112L)
\r
412 * If == 200112L, you can use barriers
\r
414 * + These functions provide both 'inherit' and/or
\r
415 * 'protect' protocol, based upon these macro
\r
418 * -------------------------------------------------------------
\r
424 #undef _POSIX_THREADS
\r
425 #define _POSIX_THREADS 200112L
\r
427 #undef _POSIX_READER_WRITER_LOCKS
\r
428 #define _POSIX_READER_WRITER_LOCKS 200112L
\r
430 #undef _POSIX_SPIN_LOCKS
\r
431 #define _POSIX_SPIN_LOCKS 200112L
\r
433 #undef _POSIX_BARRIERS
\r
434 #define _POSIX_BARRIERS 200112L
\r
436 #undef _POSIX_THREAD_SAFE_FUNCTIONS
\r
437 #define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
\r
439 #undef _POSIX_THREAD_ATTR_STACKSIZE
\r
440 #define _POSIX_THREAD_ATTR_STACKSIZE 200112L
\r
443 * The following options are not supported
\r
445 #undef _POSIX_THREAD_ATTR_STACKADDR
\r
446 #define _POSIX_THREAD_ATTR_STACKADDR -1
\r
448 #undef _POSIX_THREAD_PRIO_INHERIT
\r
449 #define _POSIX_THREAD_PRIO_INHERIT -1
\r
451 #undef _POSIX_THREAD_PRIO_PROTECT
\r
452 #define _POSIX_THREAD_PRIO_PROTECT -1
\r
454 /* TPS is not fully supported. */
\r
455 #undef _POSIX_THREAD_PRIORITY_SCHEDULING
\r
456 #define _POSIX_THREAD_PRIORITY_SCHEDULING -1
\r
458 #undef _POSIX_THREAD_PROCESS_SHARED
\r
459 #define _POSIX_THREAD_PROCESS_SHARED -1
\r
463 * POSIX 1003.1-2001 Limits
\r
464 * ===========================
\r
466 * These limits are normally set in <limits.h>, which is not provided with
\r
469 * PTHREAD_DESTRUCTOR_ITERATIONS
\r
470 * Maximum number of attempts to destroy
\r
471 * a thread's thread-specific data on
\r
472 * termination (must be at least 4)
\r
475 * Maximum number of thread-specific data keys
\r
476 * available per process (must be at least 128)
\r
478 * PTHREAD_STACK_MIN
\r
479 * Minimum supported stack size for a thread
\r
481 * PTHREAD_THREADS_MAX
\r
482 * Maximum number of threads supported per
\r
483 * process (must be at least 64).
\r
486 * The maximum number of semaphores a process can have.
\r
487 * (must be at least 256)
\r
490 * The maximum value a semaphore can have.
\r
491 * (must be at least 32767)
\r
494 #undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
\r
495 #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
\r
497 #undef PTHREAD_DESTRUCTOR_ITERATIONS
\r
498 #define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
\r
500 #undef _POSIX_THREAD_KEYS_MAX
\r
501 #define _POSIX_THREAD_KEYS_MAX 128
\r
503 #undef PTHREAD_KEYS_MAX
\r
504 #define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX
\r
506 #undef PTHREAD_STACK_MIN
\r
507 #define PTHREAD_STACK_MIN 0
\r
509 #undef _POSIX_THREAD_THREADS_MAX
\r
510 #define _POSIX_THREAD_THREADS_MAX 64
\r
512 /* Arbitrary value */
\r
513 #undef PTHREAD_THREADS_MAX
\r
514 #define PTHREAD_THREADS_MAX 2019
\r
516 #undef _POSIX_SEM_NSEMS_MAX
\r
517 #define _POSIX_SEM_NSEMS_MAX 256
\r
519 /* Arbitrary value */
\r
520 #undef SEM_NSEMS_MAX
\r
521 #define SEM_NSEMS_MAX 1024
\r
523 #undef _POSIX_SEM_VALUE_MAX
\r
524 #define _POSIX_SEM_VALUE_MAX 32767
\r
526 #undef SEM_VALUE_MAX
\r
527 #define SEM_VALUE_MAX INT_MAX
\r
530 #if __GNUC__ && ! defined (__declspec)
\r
531 # error Please upgrade your GNU compiler to one that supports __declspec.
\r
535 * When building the DLL code, you should define PTW32_BUILD so that
\r
536 * the variables/functions are exported correctly. When using the DLL,
\r
537 * do NOT define PTW32_BUILD, and then the variables/functions will
\r
538 * be imported correctly.
\r
540 #ifndef PTW32_STATIC_LIB
\r
541 # ifdef PTW32_BUILD
\r
542 # define PTW32_DLLPORT __declspec (dllexport)
\r
544 # define PTW32_DLLPORT __declspec (dllimport)
\r
547 # define PTW32_DLLPORT
\r
551 * The Open Watcom C/C++ compiler uses a non-standard calling convention
\r
552 * that passes function args in registers unless __cdecl is explicitly specified
\r
553 * in exposed function prototypes.
\r
555 * We force all calls to cdecl even though this could slow Watcom code down
\r
556 * slightly. If you know that the Watcom compiler will be used to build both
\r
557 * the DLL and application, then you can probably define this as a null string.
\r
558 * Remember that pthread.h (this file) is used for both the DLL and application builds.
\r
560 #define PTW32_CDECL __cdecl
\r
562 #if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
\r
563 # include <sys/types.h>
\r
566 * Generic handle type - intended to extend uniqueness beyond
\r
567 * that available with a simple pointer. It should scale for either
\r
571 void * p; /* Pointer to actual object */
\r
572 unsigned int x; /* Extra information - reuse count etc */
\r
575 typedef ptw32_handle_t pthread_t;
\r
576 typedef struct pthread_attr_t_ * pthread_attr_t;
\r
577 typedef struct pthread_once_t_ pthread_once_t;
\r
578 typedef struct pthread_key_t_ * pthread_key_t;
\r
579 typedef struct pthread_mutex_t_ * pthread_mutex_t;
\r
580 typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
\r
581 typedef struct pthread_cond_t_ * pthread_cond_t;
\r
582 typedef struct pthread_condattr_t_ * pthread_condattr_t;
\r
584 typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
\r
585 typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
\r
586 typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
\r
587 typedef struct pthread_barrier_t_ * pthread_barrier_t;
\r
588 typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
\r
591 * ====================
\r
592 * ====================
\r
594 * ====================
\r
595 * ====================
\r
600 * pthread_attr_{get,set}detachstate
\r
602 PTHREAD_CREATE_JOINABLE = 0, /* Default */
\r
603 PTHREAD_CREATE_DETACHED = 1,
\r
606 * pthread_attr_{get,set}inheritsched
\r
608 PTHREAD_INHERIT_SCHED = 0,
\r
609 PTHREAD_EXPLICIT_SCHED = 1, /* Default */
\r
612 * pthread_{get,set}scope
\r
614 PTHREAD_SCOPE_PROCESS = 0,
\r
615 PTHREAD_SCOPE_SYSTEM = 1, /* Default */
\r
618 * pthread_setcancelstate paramters
\r
620 PTHREAD_CANCEL_ENABLE = 0, /* Default */
\r
621 PTHREAD_CANCEL_DISABLE = 1,
\r
624 * pthread_setcanceltype parameters
\r
626 PTHREAD_CANCEL_ASYNCHRONOUS = 0,
\r
627 PTHREAD_CANCEL_DEFERRED = 1, /* Default */
\r
630 * pthread_mutexattr_{get,set}pshared
\r
631 * pthread_condattr_{get,set}pshared
\r
633 PTHREAD_PROCESS_PRIVATE = 0,
\r
634 PTHREAD_PROCESS_SHARED = 1,
\r
637 * pthread_barrier_wait
\r
639 PTHREAD_BARRIER_SERIAL_THREAD = -1
\r
643 * ====================
\r
644 * ====================
\r
646 * ====================
\r
647 * ====================
\r
649 #define PTHREAD_CANCELED ((void *) -1)
\r
653 * ====================
\r
654 * ====================
\r
656 * ====================
\r
657 * ====================
\r
659 #define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0}
\r
661 struct pthread_once_t_
\r
663 int done; /* indicates if user function has been executed */
\r
671 * ====================
\r
672 * ====================
\r
673 * Object initialisers
\r
674 * ====================
\r
675 * ====================
\r
677 #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
\r
678 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
\r
679 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
\r
682 * Compatibility with LinuxThreads
\r
684 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
\r
685 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
\r
687 #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
\r
689 #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
\r
691 #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
\r
699 /* Compatibility with LinuxThreads */
\r
700 PTHREAD_MUTEX_FAST_NP,
\r
701 PTHREAD_MUTEX_RECURSIVE_NP,
\r
702 PTHREAD_MUTEX_ERRORCHECK_NP,
\r
703 PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
\r
704 PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
\r
705 /* For compatibility with POSIX */
\r
706 PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
\r
707 PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
\r
708 PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
\r
709 PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
\r
713 typedef struct ptw32_cleanup_t ptw32_cleanup_t;
\r
715 #if defined(_MSC_VER)
\r
716 /* Disable MSVC 'anachronism used' warning */
\r
717 #pragma warning( disable : 4229 )
\r
720 typedef void(*PTW32_CDECL ptw32_cleanup_callback_t)(void *);
\r
722 #if defined(_MSC_VER)
\r
723 #pragma warning( default : 4229 )
\r
726 struct ptw32_cleanup_t
\r
728 ptw32_cleanup_callback_t routine;
\r
730 struct ptw32_cleanup_t *prev;
\r
733 #ifdef __CLEANUP_SEH
\r
735 * WIN32 SEH version of cancel cleanup.
\r
738 #define pthread_cleanup_push( _rout, _arg ) \
\r
740 ptw32_cleanup_t _cleanup; \
\r
742 _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
\r
743 _cleanup.arg = (_arg); \
\r
747 #define pthread_cleanup_pop( _execute ) \
\r
751 if( _execute || AbnormalTermination()) \
\r
753 (*(_cleanup.routine))( _cleanup.arg ); \
\r
758 #else /* __CLEANUP_SEH */
\r
763 * C implementation of PThreads cancel cleanup
\r
766 #define pthread_cleanup_push( _rout, _arg ) \
\r
768 ptw32_cleanup_t _cleanup; \
\r
770 ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
\r
772 #define pthread_cleanup_pop( _execute ) \
\r
773 (void) ptw32_pop_cleanup( _execute ); \
\r
776 #else /* __CLEANUP_C */
\r
778 #ifdef __CLEANUP_CXX
\r
781 * C++ version of cancel cleanup.
\r
782 * - John E. Bossom.
\r
785 class PThreadCleanup {
\r
790 * This class is a C++ helper class that is
\r
791 * used to implement pthread_cleanup_push/
\r
792 * pthread_cleanup_pop.
\r
793 * The destructor of this class automatically
\r
794 * pops the pushed cleanup routine regardless
\r
795 * of how the code exits the scope
\r
796 * (i.e. such as by an exception)
\r
798 ptw32_cleanup_callback_t cleanUpRout;
\r
808 * No cleanup performed
\r
814 ptw32_cleanup_callback_t routine,
\r
816 cleanUpRout(routine),
\r
820 * Registers a cleanup routine for 'arg'
\r
827 if (executeIt && ((void *)cleanUpRout != (void *)0))
\r
829 (void)(*cleanUpRout)(obj);
\r
833 void execute(int exec)
\r
840 * C++ implementation of PThreads cancel cleanup;
\r
841 * This implementation takes advantage of a helper
\r
842 * class who's destructor automatically calls the
\r
843 * cleanup routine if we exit our scope weirdly
\r
845 #define pthread_cleanup_push( _rout, _arg ) \
\r
847 PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \
\r
850 #define pthread_cleanup_pop( _execute ) \
\r
851 cleanup.execute( _execute ); \
\r
856 #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
\r
858 #endif /* __CLEANUP_CXX */
\r
860 #endif /* __CLEANUP_C */
\r
862 #endif /* __CLEANUP_SEH */
\r
873 * PThread Attribute Functions
\r
875 PTW32_DLLPORT int PTW32_CDECL pthread_attr_init(pthread_attr_t * attr);
\r
877 PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy(pthread_attr_t * attr);
\r
879 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate(const pthread_attr_t * attr,
\r
882 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr(const pthread_attr_t * attr,
\r
885 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize(const pthread_attr_t * attr,
\r
886 size_t * stacksize);
\r
888 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate(pthread_attr_t * attr,
\r
891 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr(pthread_attr_t * attr,
\r
894 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize(pthread_attr_t * attr,
\r
897 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam(const pthread_attr_t *attr,
\r
898 struct sched_param *param);
\r
900 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam(pthread_attr_t *attr,
\r
901 const struct sched_param *param);
\r
903 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy(pthread_attr_t *,
\r
906 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy(pthread_attr_t *,
\r
909 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
\r
912 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr,
\r
913 int * inheritsched);
\r
915 PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope(pthread_attr_t *,
\r
918 PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope(const pthread_attr_t *,
\r
922 * PThread Functions
\r
924 PTW32_DLLPORT int PTW32_CDECL pthread_create(pthread_t * tid,
\r
925 const pthread_attr_t * attr,
\r
926 void *(*start) (void *),
\r
929 PTW32_DLLPORT int PTW32_CDECL pthread_detach(pthread_t tid);
\r
931 PTW32_DLLPORT int PTW32_CDECL pthread_equal(pthread_t t1,
\r
934 PTW32_DLLPORT void PTW32_CDECL pthread_exit(void *value_ptr);
\r
936 PTW32_DLLPORT int PTW32_CDECL pthread_join(pthread_t thread,
\r
939 PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self(void);
\r
941 PTW32_DLLPORT int PTW32_CDECL pthread_cancel(pthread_t thread);
\r
943 PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate(int state,
\r
946 PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype(int type,
\r
949 PTW32_DLLPORT void PTW32_CDECL pthread_testcancel(void);
\r
951 PTW32_DLLPORT int PTW32_CDECL pthread_once(pthread_once_t * once_control,
\r
952 void(*init_routine) (void));
\r
954 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
\r
955 PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup(int execute);
\r
957 PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup(ptw32_cleanup_t * cleanup,
\r
958 void(*routine) (void *),
\r
960 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
\r
963 * Thread Specific Data Functions
\r
965 PTW32_DLLPORT int PTW32_CDECL pthread_key_create(pthread_key_t * key,
\r
966 void(*destructor) (void *));
\r
968 PTW32_DLLPORT int PTW32_CDECL pthread_key_delete(pthread_key_t key);
\r
970 PTW32_DLLPORT int PTW32_CDECL pthread_setspecific(pthread_key_t key,
\r
971 const void *value);
\r
973 PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific(pthread_key_t key);
\r
977 * Mutex Attribute Functions
\r
979 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init(pthread_mutexattr_t * attr);
\r
981 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy(pthread_mutexattr_t * attr);
\r
983 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared(const pthread_mutexattr_t
\r
987 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared(pthread_mutexattr_t * attr,
\r
990 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype(pthread_mutexattr_t * attr, int kind);
\r
991 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype(pthread_mutexattr_t * attr, int *kind);
\r
994 * Barrier Attribute Functions
\r
996 PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init(pthread_barrierattr_t * attr);
\r
998 PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy(pthread_barrierattr_t * attr);
\r
1000 PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared(const pthread_barrierattr_t
\r
1004 PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared(pthread_barrierattr_t * attr,
\r
1010 PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init(pthread_mutex_t * mutex,
\r
1011 const pthread_mutexattr_t * attr);
\r
1013 PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy(pthread_mutex_t * mutex);
\r
1015 PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock(pthread_mutex_t * mutex);
\r
1017 PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex,
\r
1018 const struct timespec *abstime);
\r
1020 PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock(pthread_mutex_t * mutex);
\r
1022 PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock(pthread_mutex_t * mutex);
\r
1025 * Spinlock Functions
\r
1027 PTW32_DLLPORT int PTW32_CDECL pthread_spin_init(pthread_spinlock_t * lock, int pshared);
\r
1029 PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy(pthread_spinlock_t * lock);
\r
1031 PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock(pthread_spinlock_t * lock);
\r
1033 PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock(pthread_spinlock_t * lock);
\r
1035 PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock(pthread_spinlock_t * lock);
\r
1038 * Barrier Functions
\r
1040 PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init(pthread_barrier_t * barrier,
\r
1041 const pthread_barrierattr_t * attr,
\r
1042 unsigned int count);
\r
1044 PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy(pthread_barrier_t * barrier);
\r
1046 PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait(pthread_barrier_t * barrier);
\r
1049 * Condition Variable Attribute Functions
\r
1051 PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init(pthread_condattr_t * attr);
\r
1053 PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy(pthread_condattr_t * attr);
\r
1055 PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared(const pthread_condattr_t * attr,
\r
1058 PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared(pthread_condattr_t * attr,
\r
1062 * Condition Variable Functions
\r
1064 PTW32_DLLPORT int PTW32_CDECL pthread_cond_init(pthread_cond_t * cond,
\r
1065 const pthread_condattr_t * attr);
\r
1067 PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy(pthread_cond_t * cond);
\r
1069 PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait(pthread_cond_t * cond,
\r
1070 pthread_mutex_t * mutex);
\r
1072 PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait(pthread_cond_t * cond,
\r
1073 pthread_mutex_t * mutex,
\r
1074 const struct timespec *abstime);
\r
1076 PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal(pthread_cond_t * cond);
\r
1078 PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast(pthread_cond_t * cond);
\r
1083 PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam(pthread_t thread,
\r
1085 const struct sched_param *param);
\r
1087 PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam(pthread_t thread,
\r
1089 struct sched_param *param);
\r
1091 PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency(int);
\r
1093 PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency(void);
\r
1096 * Read-Write Lock Functions
\r
1098 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
\r
1099 const pthread_rwlockattr_t *attr);
\r
1101 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
\r
1103 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
\r
1105 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
\r
1107 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
\r
1109 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
\r
1110 const struct timespec *abstime);
\r
1112 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
\r
1114 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
\r
1115 const struct timespec *abstime);
\r
1117 PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
\r
1119 PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init(pthread_rwlockattr_t * attr);
\r
1121 PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy(pthread_rwlockattr_t * attr);
\r
1123 PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * attr,
\r
1126 PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared(pthread_rwlockattr_t * attr,
\r
1129 #if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
\r
1132 * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
\r
1133 * already have signal.h that don't define these.
\r
1135 PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
\r
1138 * Non-portable functions
\r
1142 * Compatibility with Linux.
\r
1144 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
\r
1146 PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
\r
1150 * Possibly supported by other POSIX threads implementations
\r
1152 PTW32_DLLPORT int PTW32_CDECL pthread_delay_np(struct timespec * interval);
\r
1153 PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
\r
1156 * Useful if an application wants to statically link
\r
1157 * the lib rather than load the DLL at run-time.
\r
1159 PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
\r
1160 PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
\r
1161 PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
\r
1162 PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
\r
1165 * Features that are auto-detected at load/run time.
\r
1167 PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
\r
1168 enum ptw32_features {
\r
1169 PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
\r
1170 PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */
\r
1174 * Register a system time change with the library.
\r
1175 * Causes the library to perform various functions
\r
1176 * in response to the change. Should be called whenever
\r
1177 * the application's top level window receives a
\r
1178 * WM_TIMECHANGE message. It can be passed directly to
\r
1179 * pthread_create() as a new thread if desired.
\r
1181 PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
\r
1183 #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
\r
1185 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
\r
1188 * Returns the Win32 HANDLE for the POSIX thread.
\r
1190 PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
\r
1194 * Protected Methods
\r
1196 * This function blocks until the given WIN32 handle
\r
1197 * is signaled or pthread_cancel had been called.
\r
1198 * This function allows the caller to hook into the
\r
1199 * PThreads cancel mechanism. It is implemented using
\r
1201 * WaitForMultipleObjects
\r
1203 * on 'waitHandle' and a manually reset WIN32 Event
\r
1204 * used to implement pthread_cancel. The 'timeout'
\r
1205 * argument to TimedWait is simply passed to
\r
1206 * WaitForMultipleObjects.
\r
1208 PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait(HANDLE waitHandle);
\r
1209 PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait(HANDLE waitHandle,
\r
1212 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
\r
1215 * Thread-Safe C Runtime Library Mappings.
\r
1218 # if defined(NEED_ERRNO)
\r
1219 PTW32_DLLPORT int * PTW32_CDECL _errno(void);
\r
1222 # if (defined(_MT) || defined(_DLL))
\r
1223 __declspec(dllimport) extern int * __cdecl _errno(void);
\r
1224 # define errno (*_errno())
\r
1231 * WIN32 C runtime library had been made thread-safe
\r
1232 * without affecting the user interface. Provide
\r
1233 * mappings from the UNIX thread-safe versions to
\r
1234 * the standard C runtime library calls.
\r
1235 * Only provide function mappings for functions that
\r
1236 * actually exist on WIN32.
\r
1239 #if !defined(__MINGW32__)
\r
1240 #define strtok_r( _s, _sep, _lasts ) \
\r
1241 ( *(_lasts) = strtok( (_s), (_sep) ) )
\r
1242 #endif /* !__MINGW32__ */
\r
1244 #define asctime_r( _tm, _buf ) \
\r
1245 ( strcpy( (_buf), asctime( (_tm) ) ), \
\r
1248 #define ctime_r( _clock, _buf ) \
\r
1249 ( strcpy( (_buf), ctime( (_clock) ) ), \
\r
1252 #define gmtime_r( _clock, _result ) \
\r
1253 ( *(_result) = *gmtime( (_clock) ), \
\r
1256 #define localtime_r( _clock, _result ) \
\r
1257 ( *(_result) = *localtime( (_clock) ), \
\r
1260 #define rand_r( _seed ) \
\r
1261 ( _seed == _seed? rand() : rand() )
\r
1265 * Some compiler environments don't define some things.
\r
1267 #if defined(__BORLANDC__)
\r
1268 # define _ftime ftime
\r
1269 # define _timeb timeb
\r
1272 #ifdef __cplusplus
\r
1275 * Internal exceptions
\r
1277 class ptw32_exception {};
\r
1278 class ptw32_exception_cancel : public ptw32_exception {};
\r
1279 class ptw32_exception_exit : public ptw32_exception {};
\r
1283 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
\r
1285 /* FIXME: This is only required if the library was built using SEH */
\r
1287 * Get internal SEH tag
\r
1289 PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
\r
1291 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
\r
1293 #ifndef PTW32_BUILD
\r
1295 #ifdef __CLEANUP_SEH
\r
1298 * Redefine the SEH __except keyword to ensure that applications
\r
1299 * propagate our internal exceptions up to the library's internal handlers.
\r
1301 #define __except( E ) \
\r
1302 __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
\r
1303 ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
\r
1305 #endif /* __CLEANUP_SEH */
\r
1307 #ifdef __CLEANUP_CXX
\r
1310 * Redefine the C++ catch keyword to ensure that applications
\r
1311 * propagate our internal exceptions up to the library's internal handlers.
\r
1315 * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
\r
1316 * if you want Pthread-Win32 cancelation and pthread_exit to work.
\r
1319 #ifndef PtW32NoCatchWarn
\r
1321 #pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
\r
1322 #pragma message("------------------------------------------------------------------")
\r
1323 #pragma message("When compiling applications with MSVC++ and C++ exception handling:")
\r
1324 #pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")
\r
1325 #pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
\r
1326 #pragma message(" cancelation and pthread_exit to work. For example:")
\r
1327 #pragma message("")
\r
1328 #pragma message(" #ifdef PtW32CatchAll")
\r
1329 #pragma message(" PtW32CatchAll")
\r
1330 #pragma message(" #else")
\r
1331 #pragma message(" catch(...)")
\r
1332 #pragma message(" #endif")
\r
1333 #pragma message(" {")
\r
1334 #pragma message(" /* Catchall block processing */")
\r
1335 #pragma message(" }")
\r
1336 #pragma message("------------------------------------------------------------------")
\r
1340 #define PtW32CatchAll \
\r
1341 catch( ptw32_exception & ) { throw; } \
\r
1344 #else /* _MSC_VER */
\r
1346 #define catch( E ) \
\r
1347 catch( ptw32_exception & ) { throw; } \
\r
1350 #endif /* _MSC_VER */
\r
1352 #endif /* __CLEANUP_CXX */
\r
1354 #endif /* ! PTW32_BUILD */
\r
1356 #ifdef __cplusplus
\r
1357 } /* End of extern "C" */
\r
1358 #endif /* __cplusplus */
\r
1360 #ifdef PTW32__HANDLE_DEF
\r
1363 #ifdef PTW32__DWORD_DEF
\r
1367 #undef PTW32_LEVEL
\r
1368 #undef PTW32_LEVEL_MAX
\r
1370 #endif /* ! RC_INVOKED */
\r
1372 #endif /* PTHREAD_H */
\r