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