pthread.h
上传用户:gzdtt123
上传日期:2022-01-26
资源大小:88k
文件大小:35k
开发平台:

Visual C++

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