/* This is an implementation of the threads API of POSIX 1003.1-2001.1*2* --------------------------------------------------------------------------3*4* Pthreads-win32 - POSIX Threads Library for Win325* Copyright(C) 1998 John E. Bossom6* Copyright(C) 1999,2005 Pthreads-win32 contributors7*8* Contact Email: [email protected]9*10* The current list of contributors is contained11* in the file CONTRIBUTORS included with the source12* code distribution. The list can also be seen at the13* following World Wide Web location:14* http://sources.redhat.com/pthreads-win32/contributors.html15*16* This library is free software; you can redistribute it and/or17* modify it under the terms of the GNU Lesser General Public18* License as published by the Free Software Foundation; either19* version 2 of the License, or (at your option) any later version.20*21* This library is distributed in the hope that it will be useful,22* but WITHOUT ANY WARRANTY; without even the implied warranty of23* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU24* Lesser General Public License for more details.25*26* You should have received a copy of the GNU Lesser General Public27* License along with this library in the file COPYING.LIB;28* if not, write to the Free Software Foundation, Inc.,29* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA30*/3132// undef for DLLs33#define PTW32_STATIC_LIB343536#if !defined( PTHREAD_H )37#define PTHREAD_H3839/*40* See the README file for an explanation of the pthreads-win32 version41* numbering scheme and how the DLL is named etc.42*/43#define PTW32_VERSION 2,9,1,044#define PTW32_VERSION_STRING "2, 9, 1, 0\0"4546/* There are three implementations of cancel cleanup.47* Note that pthread.h is included in both application48* compilation units and also internally for the library.49* The code here and within the library aims to work50* for all reasonable combinations of environments.51*52* The three implementations are:53*54* WIN32 SEH55* C56* C++57*58* Please note that exiting a push/pop block via59* "return", "exit", "break", or "continue" will60* lead to different behaviour amongst applications61* depending upon whether the library was built62* using SEH, C++, or C. For example, a library built63* with SEH will call the cleanup routine, while both64* C++ and C built versions will not.65*/6667/*68* Define defaults for cleanup code.69* Note: Unless the build explicitly defines one of the following, then70* we default to standard C style cleanup. This style uses setjmp/longjmp71* in the cancelation and thread exit implementations and therefore won't72* do stack unwinding if linked to applications that have it (e.g.73* C++ apps). This is currently consistent with most/all commercial Unix74* POSIX threads implementations.75*/76#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )77# define __CLEANUP_C78#endif7980#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))81#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.82#endif8384/*85* Stop here if we are being included by the resource compiler.86*/87#if !defined(RC_INVOKED)8889#undef PTW32_LEVEL9091#if defined(_POSIX_SOURCE)92#define PTW32_LEVEL 093/* Early POSIX */94#endif9596#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 19930997#undef PTW32_LEVEL98#define PTW32_LEVEL 199/* Include 1b, 1c and 1d */100#endif101102#if defined(INCLUDE_NP)103#undef PTW32_LEVEL104#define PTW32_LEVEL 2105/* Include Non-Portable extensions */106#endif107108#define PTW32_LEVEL_MAX 3109110#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL)111#define PTW32_LEVEL PTW32_LEVEL_MAX112/* Include everything */113#endif114115#if defined(_UWIN)116# define HAVE_STRUCT_TIMESPEC 1117# define HAVE_SIGNAL_H 1118# undef HAVE_PTW32_CONFIG_H119# pragma comment(lib, "pthread")120#endif121122/*123* -------------------------------------------------------------124*125*126* Module: pthread.h127*128* Purpose:129* Provides an implementation of PThreads based upon the130* standard:131*132* POSIX 1003.1-2001133* and134* The Single Unix Specification version 3135*136* (these two are equivalent)137*138* in order to enhance code portability between Windows,139* various commercial Unix implementations, and Linux.140*141* See the ANNOUNCE file for a full list of conforming142* routines and defined constants, and a list of missing143* routines and constants not defined in this implementation.144*145* Authors:146* There have been many contributors to this library.147* The initial implementation was contributed by148* John Bossom, and several others have provided major149* sections or revisions of parts of the implementation.150* Often significant effort has been contributed to151* find and fix important bugs and other problems to152* improve the reliability of the library, which sometimes153* is not reflected in the amount of code which changed as154* result.155* As much as possible, the contributors are acknowledged156* in the ChangeLog file in the source code distribution157* where their changes are noted in detail.158*159* Contributors are listed in the CONTRIBUTORS file.160*161* As usual, all bouquets go to the contributors, and all162* brickbats go to the project maintainer.163*164* Maintainer:165* The code base for this project is coordinated and166* eventually pre-tested, packaged, and made available by167*168* Ross Johnson <[email protected]>169*170* QA Testers:171* Ultimately, the library is tested in the real world by172* a host of competent and demanding scientists and173* engineers who report bugs and/or provide solutions174* which are then fixed or incorporated into subsequent175* versions of the library. Each time a bug is fixed, a176* test case is written to prove the fix and ensure177* that later changes to the code don't reintroduce the178* same error. The number of test cases is slowly growing179* and therefore so is the code reliability.180*181* Compliance:182* See the file ANNOUNCE for the list of implemented183* and not-implemented routines and defined options.184* Of course, these are all defined is this file as well.185*186* Web site:187* The source code and other information about this library188* are available from189*190* http://sources.redhat.com/pthreads-win32/191*192* -------------------------------------------------------------193*/194195/* Try to avoid including windows.h */196#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus)197#define PTW32_INCLUDE_WINDOWS_H198#endif199200#if defined(PTW32_INCLUDE_WINDOWS_H)201#include <windows.h>202#endif203204#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)205/*206* VC++6.0 or early compiler's header has no DWORD_PTR type.207*/208typedef unsigned long DWORD_PTR;209typedef unsigned long ULONG_PTR;210#endif211/*212* -----------------213* autoconf switches214* -----------------215*/216217#if defined(HAVE_PTW32_CONFIG_H)218#include "config.h"219#endif /* HAVE_PTW32_CONFIG_H */220221#if !defined(NEED_FTIME)222#include <time.h>223#else /* NEED_FTIME */224/* use native WIN32 time API */225#endif /* NEED_FTIME */226227#if defined(HAVE_SIGNAL_H)228#include <signal.h>229#endif /* HAVE_SIGNAL_H */230231#include <limits.h>232233/*234* Boolean values to make us independent of system includes.235*/236enum {237PTW32_FALSE = 0,238PTW32_TRUE = (! PTW32_FALSE)239};240241/*242* This is a duplicate of what is in the autoconf config.h,243* which is only used when building the pthread-win32 libraries.244*/245246#if !defined(PTW32_CONFIG_H)247# if defined(WINCE)248# define NEED_ERRNO249# define NEED_SEM250# endif251# if defined(__MINGW64__)252# define HAVE_STRUCT_TIMESPEC253# define HAVE_MODE_T254# elif defined(_UWIN) || defined(__MINGW32__)255# define HAVE_MODE_T256# endif257#endif258259/*260*261*/262263#if PTW32_LEVEL >= PTW32_LEVEL_MAX264#if defined(NEED_ERRNO)265#include "need_errno.h"266#else267#include <errno.h>268#endif269#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */270271/*272* Several systems don't define some error numbers.273*/274#if !defined(ENOTSUP)275# define ENOTSUP 48 /* This is the value in Solaris. */276#endif277278#if !defined(ETIMEDOUT)279# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */280#endif281282#if !defined(ENOSYS)283# define ENOSYS 140 /* Semi-arbitrary value */284#endif285286#if !defined(EDEADLK)287# if defined(EDEADLOCK)288# define EDEADLK EDEADLOCK289# else290# define EDEADLK 36 /* This is the value in MSVC. */291# endif292#endif293294/* POSIX 2008 - related to robust mutexes */295#if !defined(EOWNERDEAD)296# define EOWNERDEAD 43297#endif298#if !defined(ENOTRECOVERABLE)299# define ENOTRECOVERABLE 44300#endif301302#include <sched.h>303304/*305* To avoid including windows.h we define only those things that we306* actually need from it.307*/308#if !defined(PTW32_INCLUDE_WINDOWS_H)309#if !defined(HANDLE)310# define PTW32__HANDLE_DEF311# define HANDLE void *312#endif313#if !defined(DWORD)314# define PTW32__DWORD_DEF315# define DWORD unsigned long316#endif317#endif318319#if !defined(HAVE_STRUCT_TIMESPEC)320#define HAVE_STRUCT_TIMESPEC321#if !defined(_TIMESPEC_DEFINED)322#define _TIMESPEC_DEFINED323struct timespec {324time_t tv_sec;325long tv_nsec;326};327#endif /* _TIMESPEC_DEFINED */328#endif /* HAVE_STRUCT_TIMESPEC */329330#if !defined(SIG_BLOCK)331#define SIG_BLOCK 0332#endif /* SIG_BLOCK */333334#if !defined(SIG_UNBLOCK)335#define SIG_UNBLOCK 1336#endif /* SIG_UNBLOCK */337338#if !defined(SIG_SETMASK)339#define SIG_SETMASK 2340#endif /* SIG_SETMASK */341342#if defined(__cplusplus)343extern "C"344{345#endif /* __cplusplus */346347/*348* -------------------------------------------------------------349*350* POSIX 1003.1-2001 Options351* =========================352*353* Options are normally set in <unistd.h>, which is not provided354* with pthreads-win32.355*356* For conformance with the Single Unix Specification (version 3), all of the357* options below are defined, and have a value of either -1 (not supported)358* or 200112L (supported).359*360* These options can neither be left undefined nor have a value of 0, because361* either indicates that sysconf(), which is not implemented, may be used at362* runtime to check the status of the option.363*364* _POSIX_THREADS (== 200112L)365* If == 200112L, you can use threads366*367* _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)368* If == 200112L, you can control the size of a thread's369* stack370* pthread_attr_getstacksize371* pthread_attr_setstacksize372*373* _POSIX_THREAD_ATTR_STACKADDR (== -1)374* If == 200112L, you can allocate and control a thread's375* stack. If not supported, the following functions376* will return ENOSYS, indicating they are not377* supported:378* pthread_attr_getstackaddr379* pthread_attr_setstackaddr380*381* _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)382* If == 200112L, you can use realtime scheduling.383* This option indicates that the behaviour of some384* implemented functions conforms to the additional TPS385* requirements in the standard. E.g. rwlocks favour386* writers over readers when threads have equal priority.387*388* _POSIX_THREAD_PRIO_INHERIT (== -1)389* If == 200112L, you can create priority inheritance390* mutexes.391* pthread_mutexattr_getprotocol +392* pthread_mutexattr_setprotocol +393*394* _POSIX_THREAD_PRIO_PROTECT (== -1)395* If == 200112L, you can create priority ceiling mutexes396* Indicates the availability of:397* pthread_mutex_getprioceiling398* pthread_mutex_setprioceiling399* pthread_mutexattr_getprioceiling400* pthread_mutexattr_getprotocol +401* pthread_mutexattr_setprioceiling402* pthread_mutexattr_setprotocol +403*404* _POSIX_THREAD_PROCESS_SHARED (== -1)405* If set, you can create mutexes and condition406* variables that can be shared with another407* process.If set, indicates the availability408* of:409* pthread_mutexattr_getpshared410* pthread_mutexattr_setpshared411* pthread_condattr_getpshared412* pthread_condattr_setpshared413*414* _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)415* If == 200112L you can use the special *_r library416* functions that provide thread-safe behaviour417*418* _POSIX_READER_WRITER_LOCKS (== 200112L)419* If == 200112L, you can use read/write locks420*421* _POSIX_SPIN_LOCKS (== 200112L)422* If == 200112L, you can use spin locks423*424* _POSIX_BARRIERS (== 200112L)425* If == 200112L, you can use barriers426*427* + These functions provide both 'inherit' and/or428* 'protect' protocol, based upon these macro429* settings.430*431* -------------------------------------------------------------432*/433434/*435* POSIX Options436*/437#undef _POSIX_THREADS438#define _POSIX_THREADS 200809L439440#undef _POSIX_READER_WRITER_LOCKS441#define _POSIX_READER_WRITER_LOCKS 200809L442443#undef _POSIX_SPIN_LOCKS444#define _POSIX_SPIN_LOCKS 200809L445446#undef _POSIX_BARRIERS447#define _POSIX_BARRIERS 200809L448449#undef _POSIX_THREAD_SAFE_FUNCTIONS450#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L451452#undef _POSIX_THREAD_ATTR_STACKSIZE453#define _POSIX_THREAD_ATTR_STACKSIZE 200809L454455/*456* The following options are not supported457*/458#undef _POSIX_THREAD_ATTR_STACKADDR459#define _POSIX_THREAD_ATTR_STACKADDR -1460461#undef _POSIX_THREAD_PRIO_INHERIT462#define _POSIX_THREAD_PRIO_INHERIT -1463464#undef _POSIX_THREAD_PRIO_PROTECT465#define _POSIX_THREAD_PRIO_PROTECT -1466467/* TPS is not fully supported. */468#undef _POSIX_THREAD_PRIORITY_SCHEDULING469#define _POSIX_THREAD_PRIORITY_SCHEDULING -1470471#undef _POSIX_THREAD_PROCESS_SHARED472#define _POSIX_THREAD_PROCESS_SHARED -1473474475/*476* POSIX 1003.1-2001 Limits477* ===========================478*479* These limits are normally set in <limits.h>, which is not provided with480* pthreads-win32.481*482* PTHREAD_DESTRUCTOR_ITERATIONS483* Maximum number of attempts to destroy484* a thread's thread-specific data on485* termination (must be at least 4)486*487* PTHREAD_KEYS_MAX488* Maximum number of thread-specific data keys489* available per process (must be at least 128)490*491* PTHREAD_STACK_MIN492* Minimum supported stack size for a thread493*494* PTHREAD_THREADS_MAX495* Maximum number of threads supported per496* process (must be at least 64).497*498* SEM_NSEMS_MAX499* The maximum number of semaphores a process can have.500* (must be at least 256)501*502* SEM_VALUE_MAX503* The maximum value a semaphore can have.504* (must be at least 32767)505*506*/507#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS508#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4509510#undef PTHREAD_DESTRUCTOR_ITERATIONS511#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS512513#undef _POSIX_THREAD_KEYS_MAX514#define _POSIX_THREAD_KEYS_MAX 128515516#undef PTHREAD_KEYS_MAX517#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX518519#undef PTHREAD_STACK_MIN520#define PTHREAD_STACK_MIN 0521522#undef _POSIX_THREAD_THREADS_MAX523#define _POSIX_THREAD_THREADS_MAX 64524525/* Arbitrary value */526#undef PTHREAD_THREADS_MAX527#define PTHREAD_THREADS_MAX 2019528529#undef _POSIX_SEM_NSEMS_MAX530#define _POSIX_SEM_NSEMS_MAX 256531532/* Arbitrary value */533#undef SEM_NSEMS_MAX534#define SEM_NSEMS_MAX 1024535536#undef _POSIX_SEM_VALUE_MAX537#define _POSIX_SEM_VALUE_MAX 32767538539#undef SEM_VALUE_MAX540#define SEM_VALUE_MAX INT_MAX541542543#if defined(__GNUC__) && !defined(__declspec)544# error Please upgrade your GNU compiler to one that supports __declspec.545#endif546547/*548* When building the library, you should define PTW32_BUILD so that549* the variables/functions are exported correctly. When using the library,550* do NOT define PTW32_BUILD, and then the variables/functions will551* be imported correctly.552*/553#if !defined(PTW32_STATIC_LIB)554# if defined(PTW32_BUILD)555# define PTW32_DLLPORT __declspec (dllexport)556# else557# define PTW32_DLLPORT __declspec (dllimport)558# endif559#else560# define PTW32_DLLPORT561#endif562563/*564* The Open Watcom C/C++ compiler uses a non-standard calling convention565* that passes function args in registers unless __cdecl is explicitly specified566* in exposed function prototypes.567*568* We force all calls to cdecl even though this could slow Watcom code down569* slightly. If you know that the Watcom compiler will be used to build both570* the DLL and application, then you can probably define this as a null string.571* Remember that pthread.h (this file) is used for both the DLL and application builds.572*/573#define PTW32_CDECL __cdecl574575#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX576# include <sys/types.h>577#else578/*579* Generic handle type - intended to extend uniqueness beyond580* that available with a simple pointer. It should scale for either581* IA-32 or IA-64.582*/583typedef struct {584void * p; /* Pointer to actual object */585unsigned int x; /* Extra information - reuse count etc */586} ptw32_handle_t;587588typedef ptw32_handle_t pthread_t;589typedef struct pthread_attr_t_ * pthread_attr_t;590typedef struct pthread_once_t_ pthread_once_t;591typedef struct pthread_key_t_ * pthread_key_t;592typedef struct pthread_mutex_t_ * pthread_mutex_t;593typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;594typedef struct pthread_cond_t_ * pthread_cond_t;595typedef struct pthread_condattr_t_ * pthread_condattr_t;596#endif597typedef struct pthread_rwlock_t_ * pthread_rwlock_t;598typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;599typedef struct pthread_spinlock_t_ * pthread_spinlock_t;600typedef struct pthread_barrier_t_ * pthread_barrier_t;601typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;602603/*604* ====================605* ====================606* POSIX Threads607* ====================608* ====================609*/610611enum {612/*613* pthread_attr_{get,set}detachstate614*/615PTHREAD_CREATE_JOINABLE = 0, /* Default */616PTHREAD_CREATE_DETACHED = 1,617618/*619* pthread_attr_{get,set}inheritsched620*/621PTHREAD_INHERIT_SCHED = 0,622PTHREAD_EXPLICIT_SCHED = 1, /* Default */623624/*625* pthread_{get,set}scope626*/627PTHREAD_SCOPE_PROCESS = 0,628PTHREAD_SCOPE_SYSTEM = 1, /* Default */629630/*631* pthread_setcancelstate paramters632*/633PTHREAD_CANCEL_ENABLE = 0, /* Default */634PTHREAD_CANCEL_DISABLE = 1,635636/*637* pthread_setcanceltype parameters638*/639PTHREAD_CANCEL_ASYNCHRONOUS = 0,640PTHREAD_CANCEL_DEFERRED = 1, /* Default */641642/*643* pthread_mutexattr_{get,set}pshared644* pthread_condattr_{get,set}pshared645*/646PTHREAD_PROCESS_PRIVATE = 0,647PTHREAD_PROCESS_SHARED = 1,648649/*650* pthread_mutexattr_{get,set}robust651*/652PTHREAD_MUTEX_STALLED = 0, /* Default */653PTHREAD_MUTEX_ROBUST = 1,654655/*656* pthread_barrier_wait657*/658PTHREAD_BARRIER_SERIAL_THREAD = -1659};660661/*662* ====================663* ====================664* Cancelation665* ====================666* ====================667*/668#define PTHREAD_CANCELED ((void *)(size_t) -1)669670671/*672* ====================673* ====================674* Once Key675* ====================676* ====================677*/678#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0}679680struct pthread_once_t_681{682int done; /* indicates if user function has been executed */683void * lock;684int reserved1;685int reserved2;686};687688689/*690* ====================691* ====================692* Object initialisers693* ====================694* ====================695*/696#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1)697#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2)698#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3)699700/*701* Compatibility with LinuxThreads702*/703#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER704#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER705706#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1)707708#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1)709710#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1)711712713/*714* Mutex types.715*/716enum717{718/* Compatibility with LinuxThreads */719PTHREAD_MUTEX_FAST_NP,720PTHREAD_MUTEX_RECURSIVE_NP,721PTHREAD_MUTEX_ERRORCHECK_NP,722PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,723PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,724/* For compatibility with POSIX */725PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,726PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,727PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,728PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL729};730731732typedef struct ptw32_cleanup_t ptw32_cleanup_t;733734#if defined(_MSC_VER)735/* Disable MSVC 'anachronism used' warning */736#pragma warning( disable : 4229 )737#endif738739typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *);740741#if defined(_MSC_VER)742#pragma warning( default : 4229 )743#endif744745struct ptw32_cleanup_t746{747ptw32_cleanup_callback_t routine;748void *arg;749struct ptw32_cleanup_t *prev;750};751752#if defined(__CLEANUP_SEH)753/*754* WIN32 SEH version of cancel cleanup.755*/756757#define pthread_cleanup_push( _rout, _arg ) \758{ \759ptw32_cleanup_t _cleanup; \760\761_cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \762_cleanup.arg = (_arg); \763__try \764{ \765766#define pthread_cleanup_pop( _execute ) \767} \768__finally \769{ \770if( _execute || AbnormalTermination()) \771{ \772(*(_cleanup.routine))( _cleanup.arg ); \773} \774} \775}776777#else /* __CLEANUP_SEH */778779#if defined(__CLEANUP_C)780781/*782* C implementation of PThreads cancel cleanup783*/784785#define pthread_cleanup_push( _rout, _arg ) \786{ \787ptw32_cleanup_t _cleanup; \788\789ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \790791#define pthread_cleanup_pop( _execute ) \792(void) ptw32_pop_cleanup( _execute ); \793}794795#else /* __CLEANUP_C */796797#if defined(__CLEANUP_CXX)798799/*800* C++ version of cancel cleanup.801* - John E. Bossom.802*/803804class PThreadCleanup {805/*806* PThreadCleanup807*808* Purpose809* This class is a C++ helper class that is810* used to implement pthread_cleanup_push/811* pthread_cleanup_pop.812* The destructor of this class automatically813* pops the pushed cleanup routine regardless814* of how the code exits the scope815* (i.e. such as by an exception)816*/817ptw32_cleanup_callback_t cleanUpRout;818void * obj;819int executeIt;820821public:822PThreadCleanup() :823cleanUpRout( 0 ),824obj( 0 ),825executeIt( 0 )826/*827* No cleanup performed828*/829{830}831832PThreadCleanup(833ptw32_cleanup_callback_t routine,834void * arg ) :835cleanUpRout( routine ),836obj( arg ),837executeIt( 1 )838/*839* Registers a cleanup routine for 'arg'840*/841{842}843844~PThreadCleanup()845{846if ( executeIt && ((void *) cleanUpRout != (void *) 0) )847{848(void) (*cleanUpRout)( obj );849}850}851852void execute( int exec )853{854executeIt = exec;855}856};857858/*859* C++ implementation of PThreads cancel cleanup;860* This implementation takes advantage of a helper861* class who's destructor automatically calls the862* cleanup routine if we exit our scope weirdly863*/864#define pthread_cleanup_push( _rout, _arg ) \865{ \866PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \867(void *) (_arg) );868869#define pthread_cleanup_pop( _execute ) \870cleanup.execute( _execute ); \871}872873#else874875#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.876877#endif /* __CLEANUP_CXX */878879#endif /* __CLEANUP_C */880881#endif /* __CLEANUP_SEH */882883/*884* ===============885* ===============886* Methods887* ===============888* ===============889*/890891/*892* PThread Attribute Functions893*/894PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr);895896PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr);897898PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr,899int *detachstate);900901PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr,902void **stackaddr);903904PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr,905size_t * stacksize);906907PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr,908int detachstate);909910PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr,911void *stackaddr);912913PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr,914size_t stacksize);915916PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr,917struct sched_param *param);918919PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr,920const struct sched_param *param);921922PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *,923int);924925PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *,926int *);927928PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,929int inheritsched);930931PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr,932int * inheritsched);933934PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,935int);936937PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,938int *);939940/*941* PThread Functions942*/943PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,944const pthread_attr_t * attr,945void *(PTW32_CDECL *start) (void *),946void *arg);947948PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);949950PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,951pthread_t t2);952953PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);954955PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,956void **value_ptr);957958PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);959960PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);961962PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,963int *oldstate);964965PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,966int *oldtype);967968PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);969970PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,971void (PTW32_CDECL *init_routine) (void));972973#if PTW32_LEVEL >= PTW32_LEVEL_MAX974PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);975976PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,977ptw32_cleanup_callback_t routine,978void *arg);979#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */980981/*982* Thread Specific Data Functions983*/984PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,985void (PTW32_CDECL *destructor) (void *));986987PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);988989PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,990const void *value);991992PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);993994995/*996* Mutex Attribute Functions997*/998PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);9991000PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);10011002PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t1003* attr,1004int *pshared);10051006PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,1007int pshared);10081009PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);1010PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind);10111012PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust(1013pthread_mutexattr_t *attr,1014int robust);1015PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust(1016const pthread_mutexattr_t * attr,1017int * robust);10181019/*1020* Barrier Attribute Functions1021*/1022PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);10231024PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);10251026PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t1027* attr,1028int *pshared);10291030PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,1031int pshared);10321033/*1034* Mutex Functions1035*/1036PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,1037const pthread_mutexattr_t * attr);10381039PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);10401041PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);10421043PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex,1044const struct timespec *abstime);10451046PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);10471048PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);10491050PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex);10511052/*1053* Spinlock Functions1054*/1055PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);10561057PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);10581059PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);10601061PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);10621063PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);10641065/*1066* Barrier Functions1067*/1068PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,1069const pthread_barrierattr_t * attr,1070unsigned int count);10711072PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);10731074PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);10751076/*1077* Condition Variable Attribute Functions1078*/1079PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);10801081PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);10821083PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,1084int *pshared);10851086PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,1087int pshared);10881089/*1090* Condition Variable Functions1091*/1092PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,1093const pthread_condattr_t * attr);10941095PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);10961097PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,1098pthread_mutex_t * mutex);10991100PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,1101pthread_mutex_t * mutex,1102const struct timespec *abstime);11031104PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);11051106PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);11071108/*1109* Scheduling1110*/1111PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,1112int policy,1113const struct sched_param *param);11141115PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,1116int *policy,1117struct sched_param *param);11181119PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);11201121PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);11221123/*1124* Read-Write Lock Functions1125*/1126PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,1127const pthread_rwlockattr_t *attr);11281129PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);11301131PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);11321133PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);11341135PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);11361137PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,1138const struct timespec *abstime);11391140PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);11411142PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,1143const struct timespec *abstime);11441145PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);11461147PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);11481149PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);11501151PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,1152int *pshared);11531154PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,1155int pshared);11561157#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 111581159/*1160* Signal Functions. Should be defined in <signal.h> but MSVC and MinGW321161* already have signal.h that don't define these.1162*/1163PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);11641165/*1166* Non-portable functions1167*/11681169/*1170* Compatibility with Linux.1171*/1172PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,1173int kind);1174PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,1175int *kind);11761177/*1178* Possibly supported by other POSIX threads implementations1179*/1180PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);1181PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);1182PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread);11831184/*1185* Useful if an application wants to statically link1186* the lib rather than load the DLL at run-time.1187*/1188PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);1189PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);1190PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);1191PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);11921193/*1194* Features that are auto-detected at load/run time.1195*/1196PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);1197enum ptw32_features {1198PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */1199PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */1200};12011202/*1203* Register a system time change with the library.1204* Causes the library to perform various functions1205* in response to the change. Should be called whenever1206* the application's top level window receives a1207* WM_TIMECHANGE message. It can be passed directly to1208* pthread_create() as a new thread if desired.1209*/1210PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);12111212#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */12131214#if PTW32_LEVEL >= PTW32_LEVEL_MAX12151216/*1217* Returns the Win32 HANDLE for the POSIX thread.1218*/1219PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);1220/*1221* Returns the win32 thread ID for POSIX thread.1222*/1223PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread);122412251226/*1227* Protected Methods1228*1229* This function blocks until the given WIN32 handle1230* is signaled or pthread_cancel had been called.1231* This function allows the caller to hook into the1232* PThreads cancel mechanism. It is implemented using1233*1234* WaitForMultipleObjects1235*1236* on 'waitHandle' and a manually reset WIN32 Event1237* used to implement pthread_cancel. The 'timeout'1238* argument to TimedWait is simply passed to1239* WaitForMultipleObjects.1240*/1241PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);1242PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,1243DWORD timeout);12441245#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */12461247/*1248* Thread-Safe C Runtime Library Mappings.1249*/1250#if !defined(_UWIN)1251# if defined(NEED_ERRNO)1252PTW32_DLLPORT int * PTW32_CDECL _errno( void );1253# else1254# if !defined(errno)1255# if (defined(_MT) || defined(_DLL))1256__declspec(dllimport) extern int * __cdecl _errno(void);1257# define errno (*_errno())1258# endif1259# endif1260# endif1261#endif12621263/*1264* Some compiler environments don't define some things.1265*/1266#if defined(__BORLANDC__)1267# define _ftime ftime1268# define _timeb timeb1269#endif12701271#if defined(__cplusplus)12721273/*1274* Internal exceptions1275*/1276class ptw32_exception {};1277class ptw32_exception_cancel : public ptw32_exception {};1278class ptw32_exception_exit : public ptw32_exception {};12791280#endif12811282#if PTW32_LEVEL >= PTW32_LEVEL_MAX12831284/* FIXME: This is only required if the library was built using SEH */1285/*1286* Get internal SEH tag1287*/1288PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);12891290#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */12911292#if !defined(PTW32_BUILD)12931294#if defined(__CLEANUP_SEH)12951296/*1297* Redefine the SEH __except keyword to ensure that applications1298* propagate our internal exceptions up to the library's internal handlers.1299*/1300#define __except( E ) \1301__except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \1302? EXCEPTION_CONTINUE_SEARCH : ( E ) )13031304#endif /* __CLEANUP_SEH */13051306#if defined(__CLEANUP_CXX)13071308/*1309* Redefine the C++ catch keyword to ensure that applications1310* propagate our internal exceptions up to the library's internal handlers.1311*/1312#if defined(_MSC_VER)1313/*1314* WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'1315* if you want Pthread-Win32 cancelation and pthread_exit to work.1316*/13171318#if !defined(PtW32NoCatchWarn)13191320#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")1321#pragma message("------------------------------------------------------------------")1322#pragma message("When compiling applications with MSVC++ and C++ exception handling:")1323#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")1324#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")1325#pragma message(" cancelation and pthread_exit to work. For example:")1326#pragma message("")1327#pragma message(" #if defined(PtW32CatchAll)")1328#pragma message(" PtW32CatchAll")1329#pragma message(" #else")1330#pragma message(" catch(...)")1331#pragma message(" #endif")1332#pragma message(" {")1333#pragma message(" /* Catchall block processing */")1334#pragma message(" }")1335#pragma message("------------------------------------------------------------------")13361337#endif13381339#define PtW32CatchAll \1340catch( ptw32_exception & ) { throw; } \1341catch( ... )13421343#else /* _MSC_VER */13441345#define catch( E ) \1346catch( ptw32_exception & ) { throw; } \1347catch( E )13481349#endif /* _MSC_VER */13501351#endif /* __CLEANUP_CXX */13521353#endif /* ! PTW32_BUILD */13541355#if defined(__cplusplus)1356} /* End of extern "C" */1357#endif /* __cplusplus */13581359#if defined(PTW32__HANDLE_DEF)1360# undef HANDLE1361#endif1362#if defined(PTW32__DWORD_DEF)1363# undef DWORD1364#endif13651366#undef PTW32_LEVEL1367#undef PTW32_LEVEL_MAX13681369#endif /* ! RC_INVOKED */13701371#endif /* PTHREAD_H */137213731374