| /* This is an implementation of the threads API of POSIX 1003.1-2001. |
| * |
| * -------------------------------------------------------------------------- |
| * |
| * Pthreads-win32 - POSIX Threads Library for Win32 |
| * Copyright(C) 1998 John E. Bossom |
| * Copyright(C) 1999,2005 Pthreads-win32 contributors |
| * |
| * Contact Email: rpj@callisto.canberra.edu.au |
| * |
| * The current list of contributors is contained |
| * in the file CONTRIBUTORS included with the source |
| * code distribution. The list can also be seen at the |
| * following World Wide Web location: |
| * http://sources.redhat.com/pthreads-win32/contributors.html |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library in the file COPYING.LIB; |
| * if not, write to the Free Software Foundation, Inc., |
| * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
| */ |
| |
| #if !defined( PTHREAD_H ) |
| #define PTHREAD_H |
| |
| // Next 6 lines added by ESL for consitency accross all projects |
| #ifndef __CLEANUP_C |
| #define __CLEANUP_C |
| #endif |
| #ifdef PTW32_STATIC_LIB |
| #error Using this library as static lib is problematic because of the initialization routines, especially when exiting a Win32 thread. Use only as DLL |
| #endif |
| |
| /* |
| * See the README file for an explanation of the pthreads-win32 version |
| * numbering scheme and how the DLL is named etc. |
| */ |
| #define PTW32_VERSION 2,8,0,0 |
| #define PTW32_VERSION_STRING "2, 8, 0, 0\0" |
| |
| /* There are three implementations of cancel cleanup. |
| * Note that pthread.h is included in both application |
| * compilation units and also internally for the library. |
| * The code here and within the library aims to work |
| * for all reasonable combinations of environments. |
| * |
| * The three implementations are: |
| * |
| * WIN32 SEH |
| * C |
| * C++ |
| * |
| * Please note that exiting a push/pop block via |
| * "return", "exit", "break", or "continue" will |
| * lead to different behaviour amongst applications |
| * depending upon whether the library was built |
| * using SEH, C++, or C. For example, a library built |
| * with SEH will call the cleanup routine, while both |
| * C++ and C built versions will not. |
| */ |
| |
| /* |
| * Define defaults for cleanup code. |
| * Note: Unless the build explicitly defines one of the following, then |
| * we default to standard C style cleanup. This style uses setjmp/longjmp |
| * in the cancelation and thread exit implementations and therefore won't |
| * do stack unwinding if linked to applications that have it (e.g. |
| * C++ apps). This is currently consistent with most/all commercial Unix |
| * POSIX threads implementations. |
| */ |
| #if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) |
| # define __CLEANUP_C |
| #endif |
| |
| #if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) |
| #error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. |
| #endif |
| |
| /* |
| * Stop here if we are being included by the resource compiler. |
| */ |
| #ifndef RC_INVOKED |
| |
| #undef PTW32_LEVEL |
| |
| #if defined(_POSIX_SOURCE) |
| #define PTW32_LEVEL 0 |
| /* Early POSIX */ |
| #endif |
| |
| #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 |
| #undef PTW32_LEVEL |
| #define PTW32_LEVEL 1 |
| /* Include 1b, 1c and 1d */ |
| #endif |
| |
| #if defined(INCLUDE_NP) |
| #undef PTW32_LEVEL |
| #define PTW32_LEVEL 2 |
| /* Include Non-Portable extensions */ |
| #endif |
| |
| #define PTW32_LEVEL_MAX 3 |
| |
| #if !defined(PTW32_LEVEL) |
| #define PTW32_LEVEL PTW32_LEVEL_MAX |
| /* Include everything */ |
| #endif |
| |
| #ifdef _UWIN |
| # define HAVE_STRUCT_TIMESPEC 1 |
| # define HAVE_SIGNAL_H 1 |
| # undef HAVE_CONFIG_H |
| # pragma comment(lib, "pthread") |
| #endif |
| |
| /* |
| * ------------------------------------------------------------- |
| * |
| * |
| * Module: pthread.h |
| * |
| * Purpose: |
| * Provides an implementation of PThreads based upon the |
| * standard: |
| * |
| * POSIX 1003.1-2001 |
| * and |
| * The Single Unix Specification version 3 |
| * |
| * (these two are equivalent) |
| * |
| * in order to enhance code portability between Windows, |
| * various commercial Unix implementations, and Linux. |
| * |
| * See the ANNOUNCE file for a full list of conforming |
| * routines and defined constants, and a list of missing |
| * routines and constants not defined in this implementation. |
| * |
| * Authors: |
| * There have been many contributors to this library. |
| * The initial implementation was contributed by |
| * John Bossom, and several others have provided major |
| * sections or revisions of parts of the implementation. |
| * Often significant effort has been contributed to |
| * find and fix important bugs and other problems to |
| * improve the reliability of the library, which sometimes |
| * is not reflected in the amount of code which changed as |
| * result. |
| * As much as possible, the contributors are acknowledged |
| * in the ChangeLog file in the source code distribution |
| * where their changes are noted in detail. |
| * |
| * Contributors are listed in the CONTRIBUTORS file. |
| * |
| * As usual, all bouquets go to the contributors, and all |
| * brickbats go to the project maintainer. |
| * |
| * Maintainer: |
| * The code base for this project is coordinated and |
| * eventually pre-tested, packaged, and made available by |
| * |
| * Ross Johnson <rpj@callisto.canberra.edu.au> |
| * |
| * QA Testers: |
| * Ultimately, the library is tested in the real world by |
| * a host of competent and demanding scientists and |
| * engineers who report bugs and/or provide solutions |
| * which are then fixed or incorporated into subsequent |
| * versions of the library. Each time a bug is fixed, a |
| * test case is written to prove the fix and ensure |
| * that later changes to the code don't reintroduce the |
| * same error. The number of test cases is slowly growing |
| * and therefore so is the code reliability. |
| * |
| * Compliance: |
| * See the file ANNOUNCE for the list of implemented |
| * and not-implemented routines and defined options. |
| * Of course, these are all defined is this file as well. |
| * |
| * Web site: |
| * The source code and other information about this library |
| * are available from |
| * |
| * http://sources.redhat.com/pthreads-win32/ |
| * |
| * ------------------------------------------------------------- |
| */ |
| |
| /* Try to avoid including windows.h */ |
| #if defined(__MINGW32__) && defined(__cplusplus) |
| #define PTW32_INCLUDE_WINDOWS_H |
| #endif |
| |
| #ifdef PTW32_INCLUDE_WINDOWS_H |
| #include <windows.h> |
| #endif |
| |
| #if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) |
| /* |
| * VC++6.0 or early compiler's header has no DWORD_PTR type. |
| */ |
| typedef unsigned long DWORD_PTR; |
| #endif |
| /* |
| * ----------------- |
| * autoconf switches |
| * ----------------- |
| */ |
| |
| #if HAVE_CONFIG_H |
| #include "config.h" |
| #endif /* HAVE_CONFIG_H */ |
| |
| #ifndef NEED_FTIME |
| #include <time.h> |
| #else /* NEED_FTIME */ |
| /* use native WIN32 time API */ |
| #endif /* NEED_FTIME */ |
| |
| #if HAVE_SIGNAL_H |
| #include <signal.h> |
| #endif /* HAVE_SIGNAL_H */ |
| |
| #include <setjmp.h> |
| #include <limits.h> |
| |
| /* |
| * Boolean values to make us independent of system includes. |
| */ |
| enum { |
| PTW32_FALSE = 0, |
| PTW32_TRUE = (! PTW32_FALSE) |
| }; |
| |
| /* |
| * This is a duplicate of what is in the autoconf config.h, |
| * which is only used when building the pthread-win32 libraries. |
| */ |
| |
| #ifndef PTW32_CONFIG_H |
| # if defined(WINCE) |
| # define NEED_ERRNO |
| # define NEED_SEM |
| # endif |
| # if defined(_UWIN) || defined(__MINGW32__) |
| # define HAVE_MODE_T |
| # endif |
| #endif |
| |
| /* |
| * |
| */ |
| |
| #if PTW32_LEVEL >= PTW32_LEVEL_MAX |
| #ifdef NEED_ERRNO |
| #include "need_errno.h" |
| #else |
| #include <errno.h> |
| #endif |
| #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ |
| |
| /* |
| * Several systems don't define some error numbers. |
| */ |
| #ifndef ENOTSUP |
| # define ENOTSUP 48 /* This is the value in Solaris. */ |
| #endif |
| |
| #ifndef ETIMEDOUT |
| # define ETIMEDOUT 10060 /* This is the value in winsock.h. */ |
| #endif |
| |
| #ifndef ENOSYS |
| # define ENOSYS 140 /* Semi-arbitrary value */ |
| #endif |
| |
| #ifndef EDEADLK |
| # ifdef EDEADLOCK |
| # define EDEADLK EDEADLOCK |
| # else |
| # define EDEADLK 36 /* This is the value in MSVC. */ |
| # endif |
| #endif |
| |
| #include <sched.h> |
| |
| /* |
| * To avoid including windows.h we define only those things that we |
| * actually need from it. |
| */ |
| #ifndef PTW32_INCLUDE_WINDOWS_H |
| #ifndef HANDLE |
| # define PTW32__HANDLE_DEF |
| # define HANDLE void * |
| #endif |
| #ifndef DWORD |
| # define PTW32__DWORD_DEF |
| # define DWORD unsigned long |
| #endif |
| #endif |
| |
| #ifndef HAVE_STRUCT_TIMESPEC |
| #define HAVE_STRUCT_TIMESPEC 1 |
| struct timespec { |
| long tv_sec; |
| long tv_nsec; |
| }; |
| #endif /* HAVE_STRUCT_TIMESPEC */ |
| |
| #ifndef SIG_BLOCK |
| #define SIG_BLOCK 0 |
| #endif /* SIG_BLOCK */ |
| |
| #ifndef SIG_UNBLOCK |
| #define SIG_UNBLOCK 1 |
| #endif /* SIG_UNBLOCK */ |
| |
| #ifndef SIG_SETMASK |
| #define SIG_SETMASK 2 |
| #endif /* SIG_SETMASK */ |
| |
| #ifdef __cplusplus |
| extern "C" |
| { |
| #endif /* __cplusplus */ |
| |
| /* |
| * ------------------------------------------------------------- |
| * |
| * POSIX 1003.1-2001 Options |
| * ========================= |
| * |
| * Options are normally set in <unistd.h>, which is not provided |
| * with pthreads-win32. |
| * |
| * For conformance with the Single Unix Specification (version 3), all of the |
| * options below are defined, and have a value of either -1 (not supported) |
| * or 200112L (supported). |
| * |
| * These options can neither be left undefined nor have a value of 0, because |
| * either indicates that sysconf(), which is not implemented, may be used at |
| * runtime to check the status of the option. |
| * |
| * _POSIX_THREADS (== 200112L) |
| * If == 200112L, you can use threads |
| * |
| * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) |
| * If == 200112L, you can control the size of a thread's |
| * stack |
| * pthread_attr_getstacksize |
| * pthread_attr_setstacksize |
| * |
| * _POSIX_THREAD_ATTR_STACKADDR (== -1) |
| * If == 200112L, you can allocate and control a thread's |
| * stack. If not supported, the following functions |
| * will return ENOSYS, indicating they are not |
| * supported: |
| * pthread_attr_getstackaddr |
| * pthread_attr_setstackaddr |
| * |
| * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) |
| * If == 200112L, you can use realtime scheduling. |
| * This option indicates that the behaviour of some |
| * implemented functions conforms to the additional TPS |
| * requirements in the standard. E.g. rwlocks favour |
| * writers over readers when threads have equal priority. |
| * |
| * _POSIX_THREAD_PRIO_INHERIT (== -1) |
| * If == 200112L, you can create priority inheritance |
| * mutexes. |
| * pthread_mutexattr_getprotocol + |
| * pthread_mutexattr_setprotocol + |
| * |
| * _POSIX_THREAD_PRIO_PROTECT (== -1) |
| * If == 200112L, you can create priority ceiling mutexes |
| * Indicates the availability of: |
| * pthread_mutex_getprioceiling |
| * pthread_mutex_setprioceiling |
| * pthread_mutexattr_getprioceiling |
| * pthread_mutexattr_getprotocol + |
| * pthread_mutexattr_setprioceiling |
| * pthread_mutexattr_setprotocol + |
| * |
| * _POSIX_THREAD_PROCESS_SHARED (== -1) |
| * If set, you can create mutexes and condition |
| * variables that can be shared with another |
| * process.If set, indicates the availability |
| * of: |
| * pthread_mutexattr_getpshared |
| * pthread_mutexattr_setpshared |
| * pthread_condattr_getpshared |
| * pthread_condattr_setpshared |
| * |
| * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) |
| * If == 200112L you can use the special *_r library |
| * functions that provide thread-safe behaviour |
| * |
| * _POSIX_READER_WRITER_LOCKS (== 200112L) |
| * If == 200112L, you can use read/write locks |
| * |
| * _POSIX_SPIN_LOCKS (== 200112L) |
| * If == 200112L, you can use spin locks |
| * |
| * _POSIX_BARRIERS (== 200112L) |
| * If == 200112L, you can use barriers |
| * |
| * + These functions provide both 'inherit' and/or |
| * 'protect' protocol, based upon these macro |
| * settings. |
| * |
| * ------------------------------------------------------------- |
| */ |
| |
| /* |
| * POSIX Options |
| */ |
| #undef _POSIX_THREADS |
| #define _POSIX_THREADS 200112L |
| |
| #undef _POSIX_READER_WRITER_LOCKS |
| #define _POSIX_READER_WRITER_LOCKS 200112L |
| |
| #undef _POSIX_SPIN_LOCKS |
| #define _POSIX_SPIN_LOCKS 200112L |
| |
| #undef _POSIX_BARRIERS |
| #define _POSIX_BARRIERS 200112L |
| |
| #undef _POSIX_THREAD_SAFE_FUNCTIONS |
| #define _POSIX_THREAD_SAFE_FUNCTIONS 200112L |
| |
| #undef _POSIX_THREAD_ATTR_STACKSIZE |
| #define _POSIX_THREAD_ATTR_STACKSIZE 200112L |
| |
| /* |
| * The following options are not supported |
| */ |
| #undef _POSIX_THREAD_ATTR_STACKADDR |
| #define _POSIX_THREAD_ATTR_STACKADDR -1 |
| |
| #undef _POSIX_THREAD_PRIO_INHERIT |
| #define _POSIX_THREAD_PRIO_INHERIT -1 |
| |
| #undef _POSIX_THREAD_PRIO_PROTECT |
| #define _POSIX_THREAD_PRIO_PROTECT -1 |
| |
| /* TPS is not fully supported. */ |
| #undef _POSIX_THREAD_PRIORITY_SCHEDULING |
| #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 |
| |
| #undef _POSIX_THREAD_PROCESS_SHARED |
| #define _POSIX_THREAD_PROCESS_SHARED -1 |
| |
| |
| /* |
| * POSIX 1003.1-2001 Limits |
| * =========================== |
| * |
| * These limits are normally set in <limits.h>, which is not provided with |
| * pthreads-win32. |
| * |
| * PTHREAD_DESTRUCTOR_ITERATIONS |
| * Maximum number of attempts to destroy |
| * a thread's thread-specific data on |
| * termination (must be at least 4) |
| * |
| * PTHREAD_KEYS_MAX |
| * Maximum number of thread-specific data keys |
| * available per process (must be at least 128) |
| * |
| * PTHREAD_STACK_MIN |
| * Minimum supported stack size for a thread |
| * |
| * PTHREAD_THREADS_MAX |
| * Maximum number of threads supported per |
| * process (must be at least 64). |
| * |
| * SEM_NSEMS_MAX |
| * The maximum number of semaphores a process can have. |
| * (must be at least 256) |
| * |
| * SEM_VALUE_MAX |
| * The maximum value a semaphore can have. |
| * (must be at least 32767) |
| * |
| */ |
| #undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS |
| #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 |
| |
| #undef PTHREAD_DESTRUCTOR_ITERATIONS |
| #define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS |
| |
| #undef _POSIX_THREAD_KEYS_MAX |
| #define _POSIX_THREAD_KEYS_MAX 128 |
| |
| #undef PTHREAD_KEYS_MAX |
| #define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX |
| |
| #undef PTHREAD_STACK_MIN |
| #define PTHREAD_STACK_MIN 0 |
| |
| #undef _POSIX_THREAD_THREADS_MAX |
| #define _POSIX_THREAD_THREADS_MAX 64 |
| |
| /* Arbitrary value */ |
| #undef PTHREAD_THREADS_MAX |
| #define PTHREAD_THREADS_MAX 2019 |
| |
| #undef _POSIX_SEM_NSEMS_MAX |
| #define _POSIX_SEM_NSEMS_MAX 256 |
| |
| /* Arbitrary value */ |
| #undef SEM_NSEMS_MAX |
| #define SEM_NSEMS_MAX 1024 |
| |
| #undef _POSIX_SEM_VALUE_MAX |
| #define _POSIX_SEM_VALUE_MAX 32767 |
| |
| #undef SEM_VALUE_MAX |
| #define SEM_VALUE_MAX INT_MAX |
| |
| |
| #if __GNUC__ && ! defined (__declspec) |
| # error Please upgrade your GNU compiler to one that supports __declspec. |
| #endif |
| |
| /* |
| * When building the DLL code, you should define PTW32_BUILD so that |
| * the variables/functions are exported correctly. When using the DLL, |
| * do NOT define PTW32_BUILD, and then the variables/functions will |
| * be imported correctly. |
| */ |
| #ifndef PTW32_STATIC_LIB |
| # ifdef PTW32_BUILD |
| # define PTW32_DLLPORT __declspec (dllexport) |
| # else |
| # define PTW32_DLLPORT __declspec (dllimport) |
| # endif |
| #else |
| # define PTW32_DLLPORT |
| #endif |
| |
| /* |
| * The Open Watcom C/C++ compiler uses a non-standard calling convention |
| * that passes function args in registers unless __cdecl is explicitly specified |
| * in exposed function prototypes. |
| * |
| * We force all calls to cdecl even though this could slow Watcom code down |
| * slightly. If you know that the Watcom compiler will be used to build both |
| * the DLL and application, then you can probably define this as a null string. |
| * Remember that pthread.h (this file) is used for both the DLL and application builds. |
| */ |
| #define PTW32_CDECL __cdecl |
| |
| #if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX |
| # include <sys/types.h> |
| #else |
| /* |
| * Generic handle type - intended to extend uniqueness beyond |
| * that available with a simple pointer. It should scale for either |
| * IA-32 or IA-64. |
| */ |
| typedef struct { |
| void * p; /* Pointer to actual object */ |
| unsigned int x; /* Extra information - reuse count etc */ |
| } ptw32_handle_t; |
| |
| typedef ptw32_handle_t pthread_t; |
| typedef struct pthread_attr_t_ * pthread_attr_t; |
| typedef struct pthread_once_t_ pthread_once_t; |
| typedef struct pthread_key_t_ * pthread_key_t; |
| typedef struct pthread_mutex_t_ * pthread_mutex_t; |
| typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; |
| typedef struct pthread_cond_t_ * pthread_cond_t; |
| typedef struct pthread_condattr_t_ * pthread_condattr_t; |
| #endif |
| typedef struct pthread_rwlock_t_ * pthread_rwlock_t; |
| typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; |
| typedef struct pthread_spinlock_t_ * pthread_spinlock_t; |
| typedef struct pthread_barrier_t_ * pthread_barrier_t; |
| typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; |
| |
| /* |
| * ==================== |
| * ==================== |
| * POSIX Threads |
| * ==================== |
| * ==================== |
| */ |
| |
| enum { |
| /* |
| * pthread_attr_{get,set}detachstate |
| */ |
| PTHREAD_CREATE_JOINABLE = 0, /* Default */ |
| PTHREAD_CREATE_DETACHED = 1, |
| |
| /* |
| * pthread_attr_{get,set}inheritsched |
| */ |
| PTHREAD_INHERIT_SCHED = 0, |
| PTHREAD_EXPLICIT_SCHED = 1, /* Default */ |
| |
| /* |
| * pthread_{get,set}scope |
| */ |
| PTHREAD_SCOPE_PROCESS = 0, |
| PTHREAD_SCOPE_SYSTEM = 1, /* Default */ |
| |
| /* |
| * pthread_setcancelstate paramters |
| */ |
| PTHREAD_CANCEL_ENABLE = 0, /* Default */ |
| PTHREAD_CANCEL_DISABLE = 1, |
| |
| /* |
| * pthread_setcanceltype parameters |
| */ |
| PTHREAD_CANCEL_ASYNCHRONOUS = 0, |
| PTHREAD_CANCEL_DEFERRED = 1, /* Default */ |
| |
| /* |
| * pthread_mutexattr_{get,set}pshared |
| * pthread_condattr_{get,set}pshared |
| */ |
| PTHREAD_PROCESS_PRIVATE = 0, |
| PTHREAD_PROCESS_SHARED = 1, |
| |
| /* |
| * pthread_barrier_wait |
| */ |
| PTHREAD_BARRIER_SERIAL_THREAD = -1 |
| }; |
| |
| /* |
| * ==================== |
| * ==================== |
| * Cancelation |
| * ==================== |
| * ==================== |
| */ |
| #define PTHREAD_CANCELED ((void *) -1) |
| |
| |
| /* |
| * ==================== |
| * ==================== |
| * Once Key |
| * ==================== |
| * ==================== |
| */ |
| #define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} |
| |
| struct pthread_once_t_ |
| { |
| int done; /* indicates if user function has been executed */ |
| void * lock; |
| int reserved1; |
| int reserved2; |
| }; |
| |
| |
| /* |
| * ==================== |
| * ==================== |
| * Object initialisers |
| * ==================== |
| * ==================== |
| */ |
| #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) |
| #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) |
| #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) |
| |
| /* |
| * Compatibility with LinuxThreads |
| */ |
| #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER |
| #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER |
| |
| #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) |
| |
| #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) |
| |
| #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) |
| |
| |
| /* |
| * Mutex types. |
| */ |
| enum |
| { |
| /* Compatibility with LinuxThreads */ |
| PTHREAD_MUTEX_FAST_NP, |
| PTHREAD_MUTEX_RECURSIVE_NP, |
| PTHREAD_MUTEX_ERRORCHECK_NP, |
| PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, |
| PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, |
| /* For compatibility with POSIX */ |
| PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, |
| PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, |
| PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, |
| PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL |
| }; |
| |
| |
| typedef struct ptw32_cleanup_t ptw32_cleanup_t; |
| |
| #if defined(_MSC_VER) |
| /* Disable MSVC 'anachronism used' warning */ |
| #pragma warning( disable : 4229 ) |
| #endif |
| |
| typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); |
| |
| #if defined(_MSC_VER) |
| #pragma warning( default : 4229 ) |
| #endif |
| |
| struct ptw32_cleanup_t |
| { |
| ptw32_cleanup_callback_t routine; |
| void *arg; |
| struct ptw32_cleanup_t *prev; |
| }; |
| |
| #ifdef __CLEANUP_SEH |
| /* |
| * WIN32 SEH version of cancel cleanup. |
| */ |
| |
| #define pthread_cleanup_push( _rout, _arg ) \ |
| { \ |
| ptw32_cleanup_t _cleanup; \ |
| \ |
| _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ |
| _cleanup.arg = (_arg); \ |
| __try \ |
| { \ |
| |
| #define pthread_cleanup_pop( _execute ) \ |
| } \ |
| __finally \ |
| { \ |
| if( _execute || AbnormalTermination()) \ |
| { \ |
| (*(_cleanup.routine))( _cleanup.arg ); \ |
| } \ |
| } \ |
| } |
| |
| #else /* __CLEANUP_SEH */ |
| |
| #ifdef __CLEANUP_C |
| |
| /* |
| * C implementation of PThreads cancel cleanup |
| */ |
| |
| #define pthread_cleanup_push( _rout, _arg ) \ |
| { \ |
| ptw32_cleanup_t _cleanup; \ |
| \ |
| ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ |
| |
| #define pthread_cleanup_pop( _execute ) \ |
| (void) ptw32_pop_cleanup( _execute ); \ |
| } |
| |
| #else /* __CLEANUP_C */ |
| |
| #ifdef __CLEANUP_CXX |
| |
| /* |
| * C++ version of cancel cleanup. |
| * - John E. Bossom. |
| */ |
| |
| class PThreadCleanup { |
| /* |
| * PThreadCleanup |
| * |
| * Purpose |
| * This class is a C++ helper class that is |
| * used to implement pthread_cleanup_push/ |
| * pthread_cleanup_pop. |
| * The destructor of this class automatically |
| * pops the pushed cleanup routine regardless |
| * of how the code exits the scope |
| * (i.e. such as by an exception) |
| */ |
| ptw32_cleanup_callback_t cleanUpRout; |
| void * obj; |
| int executeIt; |
| |
| public: |
| PThreadCleanup() : |
| cleanUpRout( 0 ), |
| obj( 0 ), |
| executeIt( 0 ) |
| /* |
| * No cleanup performed |
| */ |
| { |
| } |
| |
| PThreadCleanup( |
| ptw32_cleanup_callback_t routine, |
| void * arg ) : |
| cleanUpRout( routine ), |
| obj( arg ), |
| executeIt( 1 ) |
| /* |
| * Registers a cleanup routine for 'arg' |
| */ |
| { |
| } |
| |
| ~PThreadCleanup() |
| { |
| if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) |
| { |
| (void) (*cleanUpRout)( obj ); |
| } |
| } |
| |
| void execute( int exec ) |
| { |
| executeIt = exec; |
| } |
| }; |
| |
| /* |
| * C++ implementation of PThreads cancel cleanup; |
| * This implementation takes advantage of a helper |
| * class who's destructor automatically calls the |
| * cleanup routine if we exit our scope weirdly |
| */ |
| #define pthread_cleanup_push( _rout, _arg ) \ |
| { \ |
| PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ |
| (void *) (_arg) ); |
| |
| #define pthread_cleanup_pop( _execute ) \ |
| cleanup.execute( _execute ); \ |
| } |
| |
| #else |
| |
| #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. |
| |
| #endif /* __CLEANUP_CXX */ |
| |
| #endif /* __CLEANUP_C */ |
| |
| #endif /* __CLEANUP_SEH */ |
| |
| /* |
| * =============== |
| * =============== |
| * Methods |
| * =============== |
| * =============== |
| */ |
| |
| /* |
| * PThread Attribute Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, |
| int *detachstate); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, |
| void **stackaddr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, |
| size_t * stacksize); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, |
| int detachstate); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, |
| void *stackaddr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, |
| size_t stacksize); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, |
| struct sched_param *param); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, |
| const struct sched_param *param); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, |
| int); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *, |
| int *); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, |
| int inheritsched); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr, |
| int * inheritsched); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, |
| int); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, |
| int *); |
| |
| /* |
| * PThread Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, |
| const pthread_attr_t * attr, |
| void *(*start) (void *), |
| void *arg); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, |
| pthread_t t2); |
| |
| PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, |
| void **value_ptr); |
| |
| PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, |
| int *oldstate); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, |
| int *oldtype); |
| |
| PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, |
| void (*init_routine) (void)); |
| |
| #if PTW32_LEVEL >= PTW32_LEVEL_MAX |
| PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); |
| |
| PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, |
| void (*routine) (void *), |
| void *arg); |
| #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ |
| |
| /* |
| * Thread Specific Data Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, |
| void (*destructor) (void *)); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, |
| const void *value); |
| |
| PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); |
| |
| |
| /* |
| * Mutex Attribute Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t |
| * attr, |
| int *pshared); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, |
| int pshared); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); |
| |
| /* |
| * Barrier Attribute Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t |
| * attr, |
| int *pshared); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, |
| int pshared); |
| |
| /* |
| * Mutex Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, |
| const pthread_mutexattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex, |
| const struct timespec *abstime); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); |
| |
| /* |
| * Spinlock Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); |
| |
| /* |
| * Barrier Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, |
| const pthread_barrierattr_t * attr, |
| unsigned int count); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); |
| |
| /* |
| * Condition Variable Attribute Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, |
| int *pshared); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, |
| int pshared); |
| |
| /* |
| * Condition Variable Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, |
| const pthread_condattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, |
| pthread_mutex_t * mutex); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, |
| pthread_mutex_t * mutex, |
| const struct timespec *abstime); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); |
| |
| /* |
| * Scheduling |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, |
| int policy, |
| const struct sched_param *param); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, |
| int *policy, |
| struct sched_param *param); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); |
| |
| /* |
| * Read-Write Lock Functions |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, |
| const pthread_rwlockattr_t *attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, |
| const struct timespec *abstime); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, |
| const struct timespec *abstime); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, |
| int *pshared); |
| |
| PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, |
| int pshared); |
| |
| #if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 |
| |
| /* |
| * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32 |
| * already have signal.h that don't define these. |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); |
| |
| /* |
| * Non-portable functions |
| */ |
| |
| /* |
| * Compatibility with Linux. |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, |
| int kind); |
| PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, |
| int *kind); |
| |
| /* |
| * Possibly supported by other POSIX threads implementations |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); |
| PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); |
| |
| /* |
| * Useful if an application wants to statically link |
| * the lib rather than load the DLL at run-time. |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); |
| PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); |
| PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); |
| PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); |
| |
| /* |
| * Features that are auto-detected at load/run time. |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); |
| enum ptw32_features { |
| PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ |
| PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ |
| }; |
| |
| /* |
| * Register a system time change with the library. |
| * Causes the library to perform various functions |
| * in response to the change. Should be called whenever |
| * the application's top level window receives a |
| * WM_TIMECHANGE message. It can be passed directly to |
| * pthread_create() as a new thread if desired. |
| */ |
| PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); |
| |
| #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ |
| |
| #if PTW32_LEVEL >= PTW32_LEVEL_MAX |
| |
| /* |
| * Returns the Win32 HANDLE for the POSIX thread. |
| */ |
| PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); |
| |
| |
| /* |
| * Protected Methods |
| * |
| * This function blocks until the given WIN32 handle |
| * is signaled or pthread_cancel had been called. |
| * This function allows the caller to hook into the |
| * PThreads cancel mechanism. It is implemented using |
| * |
| * WaitForMultipleObjects |
| * |
| * on 'waitHandle' and a manually reset WIN32 Event |
| * used to implement pthread_cancel. The 'timeout' |
| * argument to TimedWait is simply passed to |
| * WaitForMultipleObjects. |
| */ |
| PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); |
| PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, |
| DWORD timeout); |
| |
| #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ |
| |
| /* |
| * Thread-Safe C Runtime Library Mappings. |
| */ |
| #ifndef _UWIN |
| # if defined(NEED_ERRNO) |
| # ifndef errno |
| PTW32_DLLPORT int * PTW32_CDECL _errno( void ); |
| # endif |
| # else |
| # ifndef errno |
| # if (defined(_MT) || defined(_DLL)) |
| __declspec(dllimport) extern int * __cdecl _errno(void); |
| # define errno (*_errno()) |
| # endif |
| # endif |
| # endif |
| #endif |
| |
| /* |
| * WIN32 C runtime library had been made thread-safe |
| * without affecting the user interface. Provide |
| * mappings from the UNIX thread-safe versions to |
| * the standard C runtime library calls. |
| * Only provide function mappings for functions that |
| * actually exist on WIN32. |
| */ |
| |
| #if !defined(__MINGW32__) |
| #define strtok_r( _s, _sep, _lasts ) \ |
| ( *(_lasts) = strtok( (_s), (_sep) ) ) |
| #endif /* !__MINGW32__ */ |
| |
| #define asctime_r( _tm, _buf ) \ |
| ( strcpy( (_buf), asctime( (_tm) ) ), \ |
| (_buf) ) |
| |
| #define ctime_r( _clock, _buf ) \ |
| ( strcpy( (_buf), ctime( (_clock) ) ), \ |
| (_buf) ) |
| |
| #define gmtime_r( _clock, _result ) \ |
| ( *(_result) = *gmtime( (_clock) ), \ |
| (_result) ) |
| |
| #define localtime_r( _clock, _result ) \ |
| ( *(_result) = *localtime( (_clock) ), \ |
| (_result) ) |
| |
| #define rand_r( _seed ) \ |
| ( _seed == _seed? rand() : rand() ) |
| |
| |
| /* |
| * Some compiler environments don't define some things. |
| */ |
| #if defined(__BORLANDC__) |
| # define _ftime ftime |
| # define _timeb timeb |
| #endif |
| |
| #ifdef __cplusplus |
| |
| /* |
| * Internal exceptions |
| */ |
| class ptw32_exception {}; |
| class ptw32_exception_cancel : public ptw32_exception {}; |
| class ptw32_exception_exit : public ptw32_exception {}; |
| |
| #endif |
| |
| #if PTW32_LEVEL >= PTW32_LEVEL_MAX |
| |
| /* FIXME: This is only required if the library was built using SEH */ |
| /* |
| * Get internal SEH tag |
| */ |
| PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); |
| |
| #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ |
| |
| #ifndef PTW32_BUILD |
| |
| #ifdef __CLEANUP_SEH |
| |
| /* |
| * Redefine the SEH __except keyword to ensure that applications |
| * propagate our internal exceptions up to the library's internal handlers. |
| */ |
| #define __except( E ) \ |
| __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ |
| ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) |
| |
| #endif /* __CLEANUP_SEH */ |
| |
| #ifdef __CLEANUP_CXX |
| |
| /* |
| * Redefine the C++ catch keyword to ensure that applications |
| * propagate our internal exceptions up to the library's internal handlers. |
| */ |
| #ifdef _MSC_VER |
| /* |
| * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' |
| * if you want Pthread-Win32 cancelation and pthread_exit to work. |
| */ |
| |
| #ifndef PtW32NoCatchWarn |
| |
| #pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") |
| #pragma message("------------------------------------------------------------------") |
| #pragma message("When compiling applications with MSVC++ and C++ exception handling:") |
| #pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") |
| #pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") |
| #pragma message(" cancelation and pthread_exit to work. For example:") |
| #pragma message("") |
| #pragma message(" #ifdef PtW32CatchAll") |
| #pragma message(" PtW32CatchAll") |
| #pragma message(" #else") |
| #pragma message(" catch(...)") |
| #pragma message(" #endif") |
| #pragma message(" {") |
| #pragma message(" /* Catchall block processing */") |
| #pragma message(" }") |
| #pragma message("------------------------------------------------------------------") |
| |
| #endif |
| |
| #define PtW32CatchAll \ |
| catch( ptw32_exception & ) { throw; } \ |
| catch( ... ) |
| |
| #else /* _MSC_VER */ |
| |
| #define catch( E ) \ |
| catch( ptw32_exception & ) { throw; } \ |
| catch( E ) |
| |
| #endif /* _MSC_VER */ |
| |
| #endif /* __CLEANUP_CXX */ |
| |
| #endif /* ! PTW32_BUILD */ |
| |
| #ifdef __cplusplus |
| } /* End of extern "C" */ |
| #endif /* __cplusplus */ |
| |
| #ifdef PTW32__HANDLE_DEF |
| # undef HANDLE |
| #endif |
| #ifdef PTW32__DWORD_DEF |
| # undef DWORD |
| #endif |
| |
| #undef PTW32_LEVEL |
| #undef PTW32_LEVEL_MAX |
| |
| #endif /* ! RC_INVOKED */ |
| |
| #endif /* PTHREAD_H */ |