home *** CD-ROM | disk | FTP | other *** search
/ Game Programming - All in One (3rd Edition) / game_prog_all_in_one_3rd_ed.iso / pthread / include / pthread.h next >
Encoding:
C/C++ Source or Header  |  2003-09-02  |  33.5 KB  |  1,301 lines

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