Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

pthread.h

Go to the documentation of this file.
00001 /* This is an implementation of the threads API of POSIX 1003.1-2001.
00002  *
00003  * --------------------------------------------------------------------------
00004  *
00005  *      Pthreads-win32 - POSIX Threads Library for Win32
00006  *      Copyright(C) 1998 John E. Bossom
00007  *      Copyright(C) 1999,2003 Pthreads-win32 contributors
00008  * 
00009  *      Contact Email: rpj@callisto.canberra.edu.au
00010  * 
00011  *      The current list of contributors is contained
00012  *      in the file CONTRIBUTORS included with the source
00013  *      code distribution. The list can also be seen at the
00014  *      following World Wide Web location:
00015  *      http://sources.redhat.com/pthreads-win32/contributors.html
00016  * 
00017  *      This library is free software; you can redistribute it and/or
00018  *      modify it under the terms of the GNU Lesser General Public
00019  *      License as published by the Free Software Foundation; either
00020  *      version 2 of the License, or (at your option) any later version.
00021  * 
00022  *      This library is distributed in the hope that it will be useful,
00023  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  *      Lesser General Public License for more details.
00026  * 
00027  *      You should have received a copy of the GNU Lesser General Public
00028  *      License along with this library in the file COPYING.LIB;
00029  *      if not, write to the Free Software Foundation, Inc.,
00030  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00031  */
00032 
00033 #if !defined( PTHREAD_H )
00034 #define PTHREAD_H
00035 
00036 #undef PTW32_LEVEL
00037 
00038 #if defined(_POSIX_SOURCE)
00039 #define PTW32_LEVEL 0
00040 /* Early POSIX */
00041 #endif
00042 
00043 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
00044 #undef PTW32_LEVEL
00045 #define PTW32_LEVEL 1
00046 /* Include 1b, 1c and 1d */
00047 #endif
00048 
00049 #if defined(INCLUDE_NP)
00050 #undef PTW32_LEVEL
00051 #define PTW32_LEVEL 2
00052 /* Include Non-Portable extensions */
00053 #endif
00054 
00055 #define PTW32_LEVEL_MAX 3
00056 
00057 #if !defined(PTW32_LEVEL)
00058 #define PTW32_LEVEL PTW32_LEVEL_MAX
00059 /* Include everything */
00060 #endif
00061 
00062 #ifdef _UWIN
00063 #   define HAVE_STRUCT_TIMESPEC 1
00064 #   define HAVE_SIGNAL_H        1
00065 #   undef HAVE_CONFIG_H
00066 #   pragma comment(lib, "pthread")
00067 #endif
00068 
00069 /*
00070  * -------------------------------------------------------------
00071  *
00072  *
00073  * Module: pthread.h
00074  *
00075  * Purpose:
00076  *      Provides an implementation of PThreads based upon the
00077  *      standard:
00078  *
00079  *              POSIX 1003.1-2001
00080  *  and
00081  *    The Single Unix Specification version 3
00082  *
00083  *    (these two are equivalent)
00084  *
00085  *      in order to enhance code portability between Windows,
00086  *  various commercial Unix implementations, and Linux.
00087  *
00088  *      See the ANNOUNCE file for a full list of conforming
00089  *      routines and defined constants, and a list of missing
00090  *      routines and constants not defined in this implementation.
00091  *
00092  * Authors:
00093  *      There have been many contributors to this library.
00094  *      The initial implementation was contributed by
00095  *      John Bossom, and several others have provided major
00096  *      sections or revisions of parts of the implementation.
00097  *      Often significant effort has been contributed to
00098  *      find and fix important bugs and other problems to
00099  *      improve the reliability of the library, which sometimes
00100  *      is not reflected in the amount of code which changed as
00101  *      result.
00102  *      As much as possible, the contributors are acknowledged
00103  *      in the ChangeLog file in the source code distribution
00104  *      where their changes are noted in detail.
00105  *
00106  *      Contributors are listed in the CONTRIBUTORS file.
00107  *
00108  *      As usual, all bouquets go to the contributors, and all
00109  *      brickbats go to the project maintainer.
00110  *
00111  * Maintainer:
00112  *      The code base for this project is coordinated and
00113  *      eventually pre-tested, packaged, and made available by
00114  *
00115  *              Ross Johnson <rpj@ise.canberra.edu.au>
00116  *
00117  * QA Testers:
00118  *      Ultimately, the library is tested in the real world by
00119  *      a host of competent and demanding scientists and
00120  *      engineers who report bugs and/or provide solutions
00121  *      which are then fixed or incorporated into subsequent
00122  *      versions of the library. Each time a bug is fixed, a
00123  *      test case is written to prove the fix and ensure
00124  *      that later changes to the code don't reintroduce the
00125  *      same error. The number of test cases is slowly growing
00126  *      and therefore so is the code reliability.
00127  *
00128  * Compliance:
00129  *      See the file ANNOUNCE for the list of implemented
00130  *      and not-implemented routines and defined options.
00131  *      Of course, these are all defined is this file as well.
00132  *
00133  * Web site:
00134  *      The source code and other information about this library
00135  *      are available from
00136  *
00137  *              http://sources.redhat.com/pthreads-win32/
00138  *
00139  * -------------------------------------------------------------
00140  */
00141 
00142 /* Try to avoid including windows.h */
00143 #if defined(__MINGW32__) && defined(__cplusplus)
00144 /*
00145  * FIXME: The pthreadGCE.dll build gets linker unresolved errors
00146  * on pthread_key_create() unless windows.h is included here.
00147  * It appears to have something to do with an argument type mismatch.
00148  * Looking at tsd.o with 'nm' shows this line:
00149  * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
00150  * instead of
00151  * 00000000 T _pthread_key_create
00152  */
00153 #define PTW32_INCLUDE_WINDOWS_H
00154 #endif
00155 
00156 #ifdef PTW32_INCLUDE_WINDOWS_H
00157 #include <windows.h>
00158 #endif
00159 
00160 /*
00161  * -----------------
00162  * autoconf switches
00163  * -----------------
00164  */
00165 
00166 #if HAVE_CONFIG_H
00167 #include "config.h"
00168 #endif /* HAVE_CONFIG_H */
00169 
00170 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
00171 
00172 /* Try to avoid including windows.h */
00173 #if defined(__MINGW32__) && defined(__cplusplus)
00174 /*
00175  * FIXME: The pthreadGCE.dll build gets linker unresolved errors
00176  * on pthread_key_create() unless windows.h is included here.
00177  * It appears to have something to do with an argument type mismatch.
00178  * Looking at tsd.o with 'nm' shows this line:
00179  * 00000000 T _pthread_key_create__FPP14pthread_key_t_PFPv_v
00180  * instead of
00181  * 00000000 T _pthread_key_create
00182  */
00183 #define PTW32_INCLUDE_WINDOWS_H
00184 #endif
00185 
00186 #ifdef PTW32_INCLUDE_WINDOWS_H
00187 #include <windows.h>
00188 #endif
00189 
00190 #ifndef NEED_FTIME
00191 #include <time.h>
00192 #else /* NEED_FTIME */
00193 /* use native WIN32 time API */
00194 #endif /* NEED_FTIME */
00195 
00196 #if HAVE_SIGNAL_H
00197 #include <signal.h>
00198 #endif /* HAVE_SIGNAL_H */
00199 
00200 #include <setjmp.h>
00201 #include <limits.h>
00202 
00203 /*
00204  * Boolean values to make us independent of system includes.
00205  */
00206 enum {
00207   PTW32_FALSE = 0,
00208   PTW32_TRUE = (! PTW32_FALSE)
00209 };
00210 
00211 /*
00212  * This is a duplicate of what is in the autoconf config.h,
00213  * which is only used when building the pthread-win32 libraries.
00214  */
00215 
00216 #ifndef PTW32_CONFIG_H
00217 #  if defined(WINCE)
00218 #    define NEED_ERRNO
00219 #    define NEED_SEM
00220 #  endif
00221 #  if defined(_UWIN) || defined(__MINGW32__)
00222 #    define HAVE_MODE_T
00223 #  endif
00224 #endif
00225 
00226 /*
00227  *
00228  */
00229 
00230 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
00231 #ifdef NEED_ERRNO
00232 #include "need_errno.h"
00233 #else
00234 #include <errno.h>
00235 #endif
00236 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
00237 
00238 /*
00239  * Several systems don't define ENOTSUP. If not, we use
00240  * the same value as Solaris.
00241  */
00242 #ifndef ENOTSUP
00243 #  define ENOTSUP 48
00244 #endif
00245 
00246 #ifndef ETIMEDOUT
00247 #  define ETIMEDOUT 10060     /* This is the value in winsock.h. */
00248 #endif
00249 
00250 #include <sched.h>
00251 
00252 /*
00253  * To avoid including windows.h we define only those things that we
00254  * actually need from it. I don't like the potential incompatibility that
00255  * this creates with future versions of windows.
00256  */
00257 #ifndef PTW32_INCLUDE_WINDOWS_H
00258 #ifndef HANDLE
00259 # define PTW32__HANDLE_DEF
00260 # define HANDLE void *
00261 #endif
00262 #ifndef DWORD
00263 # define PTW32__DWORD_DEF
00264 # define DWORD unsigned long
00265 #endif
00266 #endif
00267 
00268 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
00269 
00270 #ifndef HAVE_STRUCT_TIMESPEC
00271 struct timespec {
00272         long tv_sec;
00273         long tv_nsec;
00274 };
00275 #endif /* HAVE_STRUCT_TIMESPEC */
00276 
00277 #ifndef SIG_BLOCK
00278 #define SIG_BLOCK 0
00279 #endif /* SIG_BLOCK */
00280 
00281 #ifndef SIG_UNBLOCK 
00282 #define SIG_UNBLOCK 1
00283 #endif /* SIG_UNBLOCK */
00284 
00285 #ifndef SIG_SETMASK
00286 #define SIG_SETMASK 2
00287 #endif /* SIG_SETMASK */
00288 
00289 #ifdef __cplusplus
00290 extern "C"
00291 {
00292 #endif                          /* __cplusplus */
00293 
00294 /*
00295  * -------------------------------------------------------------
00296  *
00297  * POSIX 1003.1-2001 Options
00298  * =========================
00299  *
00300  * _POSIX_THREADS (set)
00301  *                      If set, you can use threads
00302  *
00303  * _POSIX_THREAD_ATTR_STACKSIZE (set)
00304  *                      If set, you can control the size of a thread's
00305  *                      stack
00306  *                              pthread_attr_getstacksize
00307  *                              pthread_attr_setstacksize
00308  *
00309  * _POSIX_THREAD_ATTR_STACKADDR (not set)
00310  *                      If set, you can allocate and control a thread's
00311  *                      stack. If not supported, the following functions
00312  *                      will return ENOSYS, indicating they are not
00313  *                      supported:
00314  *                              pthread_attr_getstackaddr
00315  *                              pthread_attr_setstackaddr
00316  *
00317  * _POSIX_THREAD_PRIORITY_SCHEDULING (set)
00318  *                      If set, you can use realtime scheduling.
00319  *                      Indicates the availability of:
00320  *                              pthread_attr_getinheritsched
00321  *                              pthread_attr_getschedparam
00322  *                              pthread_attr_getschedpolicy
00323  *                              pthread_attr_getscope
00324  *                              pthread_attr_setinheritsched
00325  *                              pthread_attr_setschedparam
00326  *                              pthread_attr_setschedpolicy
00327  *                              pthread_attr_setscope
00328  *                              pthread_getschedparam
00329  *                              pthread_setschedparam
00330  *                              sched_get_priority_max
00331  *                              sched_get_priority_min
00332  *                              sched_rr_set_interval
00333  *
00334  * _POSIX_THREAD_PRIO_INHERIT (not set)
00335  *                      If set, you can create priority inheritance
00336  *                      mutexes.
00337  *                              pthread_mutexattr_getprotocol +
00338  *                              pthread_mutexattr_setprotocol +
00339  *
00340  * _POSIX_THREAD_PRIO_PROTECT (not set)
00341  *                      If set, you can create priority ceiling mutexes
00342  *                      Indicates the availability of:
00343  *                              pthread_mutex_getprioceiling
00344  *                              pthread_mutex_setprioceiling
00345  *                              pthread_mutexattr_getprioceiling
00346  *                              pthread_mutexattr_getprotocol     +
00347  *                              pthread_mutexattr_setprioceiling
00348  *                              pthread_mutexattr_setprotocol     +
00349  *
00350  * _POSIX_THREAD_PROCESS_SHARED (not set)
00351  *                      If set, you can create mutexes and condition
00352  *                      variables that can be shared with another
00353  *                      process.If set, indicates the availability
00354  *                      of:
00355  *                              pthread_mutexattr_getpshared
00356  *                              pthread_mutexattr_setpshared
00357  *                              pthread_condattr_getpshared
00358  *                              pthread_condattr_setpshared
00359  *
00360  * _POSIX_THREAD_SAFE_FUNCTIONS (set)
00361  *                      If set you can use the special *_r library
00362  *                      functions that provide thread-safe behaviour
00363  *
00364  * _POSIX_READER_WRITER_LOCKS (set)
00365  *                      If set, you can use read/write locks
00366  *
00367  * _POSIX_SPIN_LOCKS (set)
00368  *                      If set, you can use spin locks
00369  *
00370  * _POSIX_BARRIERS (set)
00371  *                      If set, you can use barriers
00372  *
00373  *      + These functions provide both 'inherit' and/or
00374  *        'protect' protocol, based upon these macro
00375  *        settings.
00376  *
00377  * POSIX 1003.1-2001 Limits
00378  * ===========================
00379  *
00380  * PTHREAD_DESTRUCTOR_ITERATIONS
00381  *                      Maximum number of attempts to destroy
00382  *                      a thread's thread-specific data on
00383  *                      termination (must be at least 4)
00384  *
00385  * PTHREAD_KEYS_MAX
00386  *                      Maximum number of thread-specific data keys
00387  *                      available per process (must be at least 128)
00388  *
00389  * PTHREAD_STACK_MIN
00390  *                      Minimum supported stack size for a thread
00391  *
00392  * PTHREAD_THREADS_MAX
00393  *                      Maximum number of threads supported per
00394  *                      process (must be at least 64).
00395  *
00396  * _POSIX_SEM_NSEMS_MAX
00397  *      The maximum number of semaphores a process can have.
00398  *      (only defined if not already defined)
00399  *
00400  * _POSIX_SEM_VALUE_MAX
00401  *      The maximum value a semaphore can have.
00402  *      (only defined if not already defined)
00403  *
00404  * -------------------------------------------------------------
00405  */
00406 
00407 /*
00408  * POSIX Options
00409  */
00410 #ifndef _POSIX_THREADS
00411 #define _POSIX_THREADS
00412 #endif
00413 
00414 #ifndef _POSIX_READER_WRITER_LOCKS
00415 #define _POSIX_READER_WRITER_LOCKS
00416 #endif
00417 
00418 #ifndef _POSIX_SPIN_LOCKS
00419 #define _POSIX_SPIN_LOCKS
00420 #endif
00421 
00422 #ifndef _POSIX_BARRIERS
00423 #define _POSIX_BARRIERS
00424 #endif
00425 
00426 #define _POSIX_THREAD_SAFE_FUNCTIONS
00427 #define _POSIX_THREAD_ATTR_STACKSIZE
00428 #define _POSIX_THREAD_PRIORITY_SCHEDULING
00429 
00430 #if defined( KLUDGE )
00431 /*
00432  * The following are not supported
00433  */
00434 #define _POSIX_THREAD_ATTR_STACKADDR
00435 #define _POSIX_THREAD_PRIO_INHERIT
00436 #define _POSIX_THREAD_PRIO_PROTECT
00437 #define _POSIX_THREAD_PROCESS_SHARED
00438 
00439 #endif                          /* KLUDGE */
00440 
00441 /*
00442  * POSIX Limits
00443  *
00444  *      PTHREAD_DESTRUCTOR_ITERATIONS
00445  *              Standard states this must be at least
00446  *              4.
00447  *
00448  *      PTHREAD_KEYS_MAX
00449  *              WIN32 permits only 64 TLS keys per process.
00450  *              This limitation could be worked around by
00451  *              simply simulating keys.
00452  *
00453  *      PTHREADS_STACK_MIN
00454  *              POSIX specifies 0 which is also the value WIN32
00455  *              interprets as allowing the system to
00456  *              set the size to that of the main thread. The
00457  *              maximum stack size in Win32 is 1Meg. WIN32
00458  *              allocates more stack as required up to the 1Meg
00459  *              limit.
00460  *
00461  *      PTHREAD_THREADS_MAX
00462  *              Not documented by WIN32. Wrote a test program
00463  *              that kept creating threads until it failed
00464  *              revealed this approximate number (Windows NT).
00465  *              This number is somewhat less for Windows 9x
00466  *              and is effectively less than 64. Perhaps this
00467  *              constant should be set at DLL load time.
00468  *
00469  */
00470 #define PTHREAD_DESTRUCTOR_ITERATIONS                          4
00471 #define PTHREAD_KEYS_MAX                        64
00472 #define PTHREAD_STACK_MIN                        0
00473 #define PTHREAD_THREADS_MAX                   2019
00474 #ifndef _POSIX_SEM_NSEMS_MAX
00475 /* Not used and only an arbitrary value. */
00476 #  define _POSIX_SEM_NSEMS_MAX                1024
00477 #endif
00478 #ifndef _POSIX_SEM_VALUE_MAX
00479 #  define _POSIX_SEM_VALUE_MAX         (INT_MAX/2)
00480 #endif
00481 
00482 #if __GNUC__ && ! defined (__declspec)
00483 # error Please upgrade your GNU compiler to one that supports __declspec.
00484 #endif
00485 
00486 /*
00487  * When building the DLL code, you should define PTW32_BUILD so that
00488  * the variables/functions are exported correctly. When using the DLL,
00489  * do NOT define PTW32_BUILD, and then the variables/functions will
00490  * be imported correctly.
00491  */
00492 #ifdef _DLL
00493 #  ifdef PTW32_BUILD
00494 #    define PTW32_DLLPORT __declspec (dllexport)
00495 #  else
00496 #    define PTW32_DLLPORT __declspec (dllimport)
00497 #  endif
00498 #endif
00499 
00500 #if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
00501 #   include     <sys/types.h>
00502 #else
00503 typedef struct pthread_t_ *pthread_t;
00504 typedef struct pthread_attr_t_ *pthread_attr_t;
00505 typedef struct pthread_once_t_ pthread_once_t;
00506 typedef struct pthread_key_t_ *pthread_key_t;
00507 typedef struct pthread_mutex_t_ *pthread_mutex_t;
00508 typedef struct pthread_mutexattr_t_ *pthread_mutexattr_t;
00509 typedef struct pthread_cond_t_ *pthread_cond_t;
00510 typedef struct pthread_condattr_t_ *pthread_condattr_t;
00511 #endif
00512 typedef struct pthread_rwlock_t_ *pthread_rwlock_t;
00513 typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t;
00514 typedef struct pthread_spinlock_t_ *pthread_spinlock_t;
00515 typedef struct pthread_barrier_t_ *pthread_barrier_t;
00516 typedef struct pthread_barrierattr_t_ *pthread_barrierattr_t;
00517 
00518 /*
00519  * ====================
00520  * ====================
00521  * POSIX Threads
00522  * ====================
00523  * ====================
00524  */
00525 
00526 enum {
00527 /*
00528  * pthread_attr_{get,set}detachstate
00529  */
00530   PTHREAD_CREATE_JOINABLE       = 0,  /* Default */
00531   PTHREAD_CREATE_DETACHED       = 1,
00532 
00533 /*
00534  * pthread_attr_{get,set}inheritsched
00535  */
00536   PTHREAD_INHERIT_SCHED         = 0,
00537   PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */
00538 
00539 /*
00540  * pthread_{get,set}scope
00541  */
00542   PTHREAD_SCOPE_PROCESS         = 0,
00543   PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */
00544 
00545 /*
00546  * pthread_setcancelstate paramters
00547  */
00548   PTHREAD_CANCEL_ENABLE         = 0,  /* Default */
00549   PTHREAD_CANCEL_DISABLE        = 1,
00550 
00551 /*
00552  * pthread_setcanceltype parameters
00553  */
00554   PTHREAD_CANCEL_ASYNCHRONOUS   = 0,
00555   PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */
00556 
00557 /*
00558  * pthread_mutexattr_{get,set}pshared
00559  * pthread_condattr_{get,set}pshared
00560  */
00561   PTHREAD_PROCESS_PRIVATE       = 0,
00562   PTHREAD_PROCESS_SHARED        = 1,
00563 
00564 /*
00565  * pthread_barrier_wait
00566  */
00567   PTHREAD_BARRIER_SERIAL_THREAD = -1
00568 };
00569 
00570 /*
00571  * ====================
00572  * ====================
00573  * Cancelation
00574  * ====================
00575  * ====================
00576  */
00577 #define PTHREAD_CANCELED       ((void *) -1)
00578 
00579 
00580 /*
00581  * ====================
00582  * ====================
00583  * Once Key
00584  * ====================
00585  * ====================
00586  */
00587 #define PTHREAD_ONCE_INIT       { PTW32_FALSE, -1 }
00588 
00589 struct pthread_once_t_
00590 {
00591   int done;                 /* indicates if user function executed  */
00592   long started;             /* First thread to increment this value */
00593                             /* to zero executes the user function   */
00594 };
00595 
00596 
00597 /*
00598  * ====================
00599  * ====================
00600  * Object initialisers
00601  * ====================
00602  * ====================
00603  */
00604 #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
00605 
00606 #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
00607 
00608 #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
00609 
00610 #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
00611 
00612 
00613 /*
00614  * Mutex types.
00615  */
00616 enum
00617 {
00618   /* Compatibility with LinuxThreads */
00619   PTHREAD_MUTEX_FAST_NP,
00620   PTHREAD_MUTEX_RECURSIVE_NP,
00621   PTHREAD_MUTEX_ERRORCHECK_NP,
00622   PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
00623   PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
00624   /* For compatibility with POSIX */
00625   PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
00626   PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
00627   PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
00628   PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
00629 };
00630 
00631 
00632 /* There are three implementations of cancel cleanup.
00633  * Note that pthread.h is included in both application
00634  * compilation units and also internally for the library.
00635  * The code here and within the library aims to work
00636  * for all reasonable combinations of environments.
00637  *
00638  * The three implementations are:
00639  *
00640  *   WIN32 SEH
00641  *   C
00642  *   C++
00643  *
00644  * Please note that exiting a push/pop block via
00645  * "return", "exit", "break", or "continue" will
00646  * lead to different behaviour amongst applications
00647  * depending upon whether the library was built
00648  * using SEH, C++, or C. For example, a library built
00649  * with SEH will call the cleanup routine, while both
00650  * C++ and C built versions will not.
00651  */
00652 
00653 /*
00654  * Define defaults for cleanup code.
00655  * Note: Unless the build explicitly defines one of the following, then
00656  * we default to standard C style cleanup. This style uses setjmp/longjmp
00657  * in the cancelation and thread exit implementations and therefore won't
00658  * do stack unwinding if linked to applications that have it (e.g.
00659  * C++ apps). This is currently consistent with most/all commercial Unix
00660  * POSIX threads implementations.
00661  */
00662 #if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
00663 # define __CLEANUP_C
00664 #endif
00665 
00666 #if defined( __CLEANUP_SEH ) && defined(__GNUC__)
00667 #error ERROR [__FILE__, line __LINE__]: GNUC does not support SEH.
00668 #endif
00669 
00670 typedef struct ptw32_cleanup_t ptw32_cleanup_t;
00671 typedef void (__cdecl *ptw32_cleanup_callback_t)(void *);
00672 
00673 struct ptw32_cleanup_t
00674 {
00675   ptw32_cleanup_callback_t routine;
00676   void *arg;
00677   struct ptw32_cleanup_t *prev;
00678 };
00679 
00680 #ifdef __CLEANUP_SEH
00681         /*
00682          * WIN32 SEH version of cancel cleanup.
00683          */
00684 
00685 #define pthread_cleanup_push( _rout, _arg ) \
00686         { \
00687             ptw32_cleanup_t     _cleanup; \
00688             \
00689         _cleanup.routine        = (ptw32_cleanup_callback_t)(_rout); \
00690             _cleanup.arg        = (_arg); \
00691             __try \
00692               { \
00693 
00694 #define pthread_cleanup_pop( _execute ) \
00695               } \
00696             __finally \
00697                 { \
00698                     if( _execute || AbnormalTermination()) \
00699                       { \
00700                           (*(_cleanup.routine))( _cleanup.arg ); \
00701                       } \
00702                 } \
00703         }
00704 
00705 #else /* __CLEANUP_SEH */
00706 
00707 #ifdef __CLEANUP_C
00708 
00709         /*
00710          * C implementation of PThreads cancel cleanup
00711          */
00712 
00713 #define pthread_cleanup_push( _rout, _arg ) \
00714         { \
00715             ptw32_cleanup_t     _cleanup; \
00716             \
00717             ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
00718 
00719 #define pthread_cleanup_pop( _execute ) \
00720             (void) ptw32_pop_cleanup( _execute ); \
00721         }
00722 
00723 #else /* __CLEANUP_C */
00724 
00725 #ifdef __CLEANUP_CXX
00726 
00727         /*
00728          * C++ version of cancel cleanup.
00729          * - John E. Bossom.
00730          */
00731 
00732         class PThreadCleanup {
00733           /*
00734            * PThreadCleanup
00735            *
00736            * Purpose
00737            *      This class is a C++ helper class that is
00738            *      used to implement pthread_cleanup_push/
00739            *      pthread_cleanup_pop.
00740            *      The destructor of this class automatically
00741            *      pops the pushed cleanup routine regardless
00742            *      of how the code exits the scope
00743            *      (i.e. such as by an exception)
00744            */
00745       ptw32_cleanup_callback_t cleanUpRout;
00746           void    *       obj;
00747           int             executeIt;
00748 
00749         public:
00750           PThreadCleanup() :
00751             cleanUpRout( 0 ),
00752             obj( 0 ),
00753             executeIt( 0 )
00754             /*
00755              * No cleanup performed
00756              */
00757             {
00758             }
00759 
00760           PThreadCleanup(
00761              ptw32_cleanup_callback_t routine,
00762                          void    *       arg ) :
00763             cleanUpRout( routine ),
00764             obj( arg ),
00765             executeIt( 1 )
00766             /*
00767              * Registers a cleanup routine for 'arg'
00768              */
00769             {
00770             }
00771 
00772           ~PThreadCleanup()
00773             {
00774               if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
00775                 {
00776                   (void) (*cleanUpRout)( obj );
00777                 }
00778             }
00779 
00780           void execute( int exec )
00781             {
00782               executeIt = exec;
00783             }
00784         };
00785 
00786         /*
00787          * C++ implementation of PThreads cancel cleanup;
00788          * This implementation takes advantage of a helper
00789          * class who's destructor automatically calls the
00790          * cleanup routine if we exit our scope weirdly
00791          */
00792 #define pthread_cleanup_push( _rout, _arg ) \
00793         { \
00794             PThreadCleanup  cleanup((ptw32_cleanup_callback_t)(_rout), \
00795                                     (void *) (_arg) );
00796 
00797 #define pthread_cleanup_pop( _execute ) \
00798             cleanup.execute( _execute ); \
00799         }
00800 
00801 #else
00802 
00803 #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
00804 
00805 #endif /* __CLEANUP_CXX */
00806 
00807 #endif /* __CLEANUP_C */
00808 
00809 #endif /* __CLEANUP_SEH */
00810 
00811 /*
00812  * ===============
00813  * ===============
00814  * Methods
00815  * ===============
00816  * ===============
00817  */
00818 
00819 /*
00820  * PThread Attribute Functions
00821  */
00822 PTW32_DLLPORT int pthread_attr_init (pthread_attr_t * attr);
00823 
00824 PTW32_DLLPORT int pthread_attr_destroy (pthread_attr_t * attr);
00825 
00826 PTW32_DLLPORT int pthread_attr_getdetachstate (const pthread_attr_t * attr,
00827                                          int *detachstate);
00828 
00829 PTW32_DLLPORT int pthread_attr_getstackaddr (const pthread_attr_t * attr,
00830                                        void **stackaddr);
00831 
00832 PTW32_DLLPORT int pthread_attr_getstacksize (const pthread_attr_t * attr,
00833                                        size_t * stacksize);
00834 
00835 PTW32_DLLPORT int pthread_attr_setdetachstate (pthread_attr_t * attr,
00836                                          int detachstate);
00837 
00838 PTW32_DLLPORT int pthread_attr_setstackaddr (pthread_attr_t * attr,
00839                                        void *stackaddr);
00840 
00841 PTW32_DLLPORT int pthread_attr_setstacksize (pthread_attr_t * attr,
00842                                        size_t stacksize);
00843 
00844 PTW32_DLLPORT int pthread_attr_getschedparam (const pthread_attr_t *attr,
00845                                         struct sched_param *param);
00846 
00847 PTW32_DLLPORT int pthread_attr_setschedparam (pthread_attr_t *attr,
00848                                         const struct sched_param *param);
00849 
00850 PTW32_DLLPORT int pthread_attr_setschedpolicy (pthread_attr_t *,
00851                                          int);
00852 
00853 PTW32_DLLPORT int pthread_attr_getschedpolicy (pthread_attr_t *,
00854                                          int *);
00855 
00856 PTW32_DLLPORT int pthread_attr_setinheritsched(pthread_attr_t * attr,
00857                                          int inheritsched);
00858 
00859 PTW32_DLLPORT int pthread_attr_getinheritsched(pthread_attr_t * attr,
00860                                          int * inheritsched);
00861 
00862 PTW32_DLLPORT int pthread_attr_setscope (pthread_attr_t *,
00863                                    int);
00864 
00865 PTW32_DLLPORT int pthread_attr_getscope (const pthread_attr_t *,
00866                                    int *);
00867 
00868 /*
00869  * PThread Functions
00870  */
00871 PTW32_DLLPORT int pthread_create (pthread_t * tid,
00872                             const pthread_attr_t * attr,
00873                             void *(*start) (void *),
00874                             void *arg);
00875 
00876 PTW32_DLLPORT int pthread_detach (pthread_t tid);
00877 
00878 PTW32_DLLPORT int pthread_equal (pthread_t t1,
00879                            pthread_t t2);
00880 
00881 PTW32_DLLPORT void pthread_exit (void *value_ptr);
00882 
00883 PTW32_DLLPORT int pthread_join (pthread_t thread,
00884                           void **value_ptr);
00885 
00886 PTW32_DLLPORT pthread_t pthread_self (void);
00887 
00888 PTW32_DLLPORT int pthread_cancel (pthread_t thread);
00889 
00890 PTW32_DLLPORT int pthread_setcancelstate (int state,
00891                                     int *oldstate);
00892 
00893 PTW32_DLLPORT int pthread_setcanceltype (int type,
00894                                    int *oldtype);
00895 
00896 PTW32_DLLPORT void pthread_testcancel (void);
00897 
00898 PTW32_DLLPORT int pthread_once (pthread_once_t * once_control,
00899                           void (*init_routine) (void));
00900 
00901 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
00902 PTW32_DLLPORT ptw32_cleanup_t *ptw32_pop_cleanup (int execute);
00903 
00904 PTW32_DLLPORT void ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
00905                                  void (*routine) (void *),
00906                                  void *arg);
00907 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
00908 
00909 /*
00910  * Thread Specific Data Functions
00911  */
00912 PTW32_DLLPORT int pthread_key_create (pthread_key_t * key,
00913                                 void (*destructor) (void *));
00914 
00915 PTW32_DLLPORT int pthread_key_delete (pthread_key_t key);
00916 
00917 PTW32_DLLPORT int pthread_setspecific (pthread_key_t key,
00918                                  const void *value);
00919 
00920 PTW32_DLLPORT void *pthread_getspecific (pthread_key_t key);
00921 
00922 
00923 /*
00924  * Mutex Attribute Functions
00925  */
00926 PTW32_DLLPORT int pthread_mutexattr_init (pthread_mutexattr_t * attr);
00927 
00928 PTW32_DLLPORT int pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
00929 
00930 PTW32_DLLPORT int pthread_mutexattr_getpshared (const pthread_mutexattr_t
00931                                           * attr,
00932                                           int *pshared);
00933 
00934 PTW32_DLLPORT int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
00935                                           int pshared);
00936 
00937 PTW32_DLLPORT int pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
00938 PTW32_DLLPORT int pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
00939 
00940 /*
00941  * Barrier Attribute Functions
00942  */
00943 PTW32_DLLPORT int pthread_barrierattr_init (pthread_barrierattr_t * attr);
00944 
00945 PTW32_DLLPORT int pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
00946 
00947 PTW32_DLLPORT int pthread_barrierattr_getpshared (const pthread_barrierattr_t
00948                                             * attr,
00949                                             int *pshared);
00950 
00951 PTW32_DLLPORT int pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
00952                                             int pshared);
00953 
00954 /*
00955  * Mutex Functions
00956  */
00957 PTW32_DLLPORT int pthread_mutex_init (pthread_mutex_t * mutex,
00958                                 const pthread_mutexattr_t * attr);
00959 
00960 PTW32_DLLPORT int pthread_mutex_destroy (pthread_mutex_t * mutex);
00961 
00962 PTW32_DLLPORT int pthread_mutex_lock (pthread_mutex_t * mutex);
00963 
00964 PTW32_DLLPORT int pthread_mutex_timedlock(pthread_mutex_t *mutex,
00965                                     const struct timespec *abstime);
00966 
00967 PTW32_DLLPORT int pthread_mutex_trylock (pthread_mutex_t * mutex);
00968 
00969 PTW32_DLLPORT int pthread_mutex_unlock (pthread_mutex_t * mutex);
00970 
00971 /*
00972  * Spinlock Functions
00973  */
00974 PTW32_DLLPORT int pthread_spin_init (pthread_spinlock_t * lock, int pshared);
00975 
00976 PTW32_DLLPORT int pthread_spin_destroy (pthread_spinlock_t * lock);
00977 
00978 PTW32_DLLPORT int pthread_spin_lock (pthread_spinlock_t * lock);
00979 
00980 PTW32_DLLPORT int pthread_spin_trylock (pthread_spinlock_t * lock);
00981 
00982 PTW32_DLLPORT int pthread_spin_unlock (pthread_spinlock_t * lock);
00983 
00984 /*
00985  * Barrier Functions
00986  */
00987 PTW32_DLLPORT int pthread_barrier_init (pthread_barrier_t * barrier,
00988                                   const pthread_barrierattr_t * attr,
00989                                   unsigned int count);
00990 
00991 PTW32_DLLPORT int pthread_barrier_destroy (pthread_barrier_t * barrier);
00992 
00993 PTW32_DLLPORT int pthread_barrier_wait (pthread_barrier_t * barrier);
00994 
00995 /*
00996  * Condition Variable Attribute Functions
00997  */
00998 PTW32_DLLPORT int pthread_condattr_init (pthread_condattr_t * attr);
00999 
01000 PTW32_DLLPORT int pthread_condattr_destroy (pthread_condattr_t * attr);
01001 
01002 PTW32_DLLPORT int pthread_condattr_getpshared (const pthread_condattr_t * attr,
01003                                          int *pshared);
01004 
01005 PTW32_DLLPORT int pthread_condattr_setpshared (pthread_condattr_t * attr,
01006                                          int pshared);
01007 
01008 /*
01009  * Condition Variable Functions
01010  */
01011 PTW32_DLLPORT int pthread_cond_init (pthread_cond_t * cond,
01012                                const pthread_condattr_t * attr);
01013 
01014 PTW32_DLLPORT int pthread_cond_destroy (pthread_cond_t * cond);
01015 
01016 PTW32_DLLPORT int pthread_cond_wait (pthread_cond_t * cond,
01017                                pthread_mutex_t * mutex);
01018 
01019 PTW32_DLLPORT int pthread_cond_timedwait (pthread_cond_t * cond,
01020                                     pthread_mutex_t * mutex,
01021                                     const struct timespec *abstime);
01022 
01023 PTW32_DLLPORT int pthread_cond_signal (pthread_cond_t * cond);
01024 
01025 PTW32_DLLPORT int pthread_cond_broadcast (pthread_cond_t * cond);
01026 
01027 /*
01028  * Scheduling
01029  */
01030 PTW32_DLLPORT int pthread_setschedparam (pthread_t thread,
01031                                    int policy,
01032                                    const struct sched_param *param);
01033 
01034 PTW32_DLLPORT int pthread_getschedparam (pthread_t thread,
01035                                    int *policy,
01036                                    struct sched_param *param);
01037 
01038 PTW32_DLLPORT int pthread_setconcurrency (int);
01039  
01040 PTW32_DLLPORT int pthread_getconcurrency (void);
01041 
01042 /*
01043  * Read-Write Lock Functions
01044  */
01045 PTW32_DLLPORT int pthread_rwlock_init(pthread_rwlock_t *lock,
01046                                 const pthread_rwlockattr_t *attr);
01047 
01048 PTW32_DLLPORT int pthread_rwlock_destroy(pthread_rwlock_t *lock);
01049 
01050 PTW32_DLLPORT int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
01051 
01052 PTW32_DLLPORT int pthread_rwlock_trywrlock(pthread_rwlock_t *);
01053 
01054 PTW32_DLLPORT int pthread_rwlock_rdlock(pthread_rwlock_t *lock);
01055 
01056 PTW32_DLLPORT int pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
01057                                        const struct timespec *abstime);
01058 
01059 PTW32_DLLPORT int pthread_rwlock_wrlock(pthread_rwlock_t *lock);
01060 
01061 PTW32_DLLPORT int pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
01062                                        const struct timespec *abstime);
01063 
01064 PTW32_DLLPORT int pthread_rwlock_unlock(pthread_rwlock_t *lock);
01065 
01066 PTW32_DLLPORT int pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
01067 
01068 PTW32_DLLPORT int pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
01069 
01070 PTW32_DLLPORT int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
01071                                            int *pshared);
01072 
01073 PTW32_DLLPORT int pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
01074                                            int pshared);
01075 
01076 #if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
01077 
01078 /*
01079  * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
01080  * already have signal.h that don't define these.
01081  */
01082 PTW32_DLLPORT int pthread_kill(pthread_t thread, int sig);
01083 
01084 /*
01085  * Non-portable functions
01086  */
01087 
01088 /*
01089  * Compatibility with Linux.
01090  */
01091 PTW32_DLLPORT int pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
01092                                          int kind);
01093 PTW32_DLLPORT int pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
01094                                          int *kind);
01095 
01096 /*
01097  * Possibly supported by other POSIX threads implementations
01098  */
01099 PTW32_DLLPORT int pthread_delay_np (struct timespec * interval);
01100 PTW32_DLLPORT int pthread_num_processors_np(void);
01101 
01102 /*
01103  * Useful if an application wants to statically link
01104  * the lib rather than load the DLL at run-time.
01105  */
01106 PTW32_DLLPORT int pthread_win32_process_attach_np(void);
01107 PTW32_DLLPORT int pthread_win32_process_detach_np(void);
01108 PTW32_DLLPORT int pthread_win32_thread_attach_np(void);
01109 PTW32_DLLPORT int pthread_win32_thread_detach_np(void);
01110 
01111 /*
01112  * Register a system time change with the library.
01113  * Causes the library to perform various functions
01114  * in response to the change. Should be called whenever
01115  * the application's top level window receives a
01116  * WM_TIMECHANGE message. It can be passed directly to
01117  * pthread_create() as a new thread if desired.
01118  */
01119 PTW32_DLLPORT void * pthread_timechange_handler_np(void *);
01120 
01121 #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
01122 
01123 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
01124 
01125 /*
01126  * Returns the Win32 HANDLE for the POSIX thread.
01127  */
01128 PTW32_DLLPORT HANDLE pthread_getw32threadhandle_np(pthread_t thread);
01129 
01130 
01131 /*
01132  * Protected Methods
01133  *
01134  * This function blocks until the given WIN32 handle
01135  * is signaled or pthread_cancel had been called.
01136  * This function allows the caller to hook into the
01137  * PThreads cancel mechanism. It is implemented using
01138  *
01139  *              WaitForMultipleObjects
01140  *
01141  * on 'waitHandle' and a manually reset WIN32 Event
01142  * used to implement pthread_cancel. The 'timeout'
01143  * argument to TimedWait is simply passed to
01144  * WaitForMultipleObjects.
01145  */
01146 PTW32_DLLPORT int pthreadCancelableWait (HANDLE waitHandle);
01147 PTW32_DLLPORT int pthreadCancelableTimedWait (HANDLE waitHandle,
01148                                         DWORD timeout);
01149 
01150 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
01151 
01152 /*
01153  * Thread-Safe C Runtime Library Mappings.
01154  */
01155 #ifndef _UWIN
01156 #  if defined(NEED_ERRNO)
01157      PTW32_DLLPORT int * _errno( void );
01158 #  else
01159 #    ifndef errno
01160 #      if (defined(_MT) || defined(_DLL))
01161          __declspec(dllimport) extern int * __cdecl _errno(void);
01162 #        define errno   (*_errno())
01163 #      endif
01164 #    endif
01165 #  endif
01166 #endif
01167 
01168 /*
01169  * WIN32 C runtime library had been made thread-safe
01170  * without affecting the user interface. Provide
01171  * mappings from the UNIX thread-safe versions to
01172  * the standard C runtime library calls.
01173  * Only provide function mappings for functions that
01174  * actually exist on WIN32.
01175  */
01176 
01177 #if !defined(__MINGW32__)
01178 #define strtok_r( _s, _sep, _lasts ) \
01179         ( *(_lasts) = strtok( (_s), (_sep) ) )
01180 #endif /* !__MINGW32__ */
01181 
01182 #define asctime_r( _tm, _buf ) \
01183         ( strcpy( (_buf), asctime( (_tm) ) ), \
01184           (_buf) )
01185 
01186 #define ctime_r( _clock, _buf ) \
01187         ( strcpy( (_buf), ctime( (_clock) ) ),  \
01188           (_buf) )
01189 
01190 #define gmtime_r( _clock, _result ) \
01191         ( *(_result) = *gmtime( (_clock) ), \
01192           (_result) )
01193 
01194 #define localtime_r( _clock, _result ) \
01195         ( *(_result) = *localtime( (_clock) ), \
01196           (_result) )
01197 
01198 #define rand_r( _seed ) \
01199         ( _seed == _seed? rand() : rand() )
01200 
01201 
01202 #ifdef __cplusplus
01203 
01204 /*
01205  * Internal exceptions
01206  */
01207 class ptw32_exception {};
01208 class ptw32_exception_cancel : public ptw32_exception {};
01209 class ptw32_exception_exit   : public ptw32_exception {};
01210 
01211 #endif
01212 
01213 #if PTW32_LEVEL >= PTW32_LEVEL_MAX
01214 
01215 /* FIXME: This is only required if the library was built using SEH */
01216 /*
01217  * Get internal SEH tag
01218  */
01219 PTW32_DLLPORT DWORD ptw32_get_exception_services_code(void);
01220 
01221 #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
01222 
01223 #ifndef PTW32_BUILD
01224 
01225 #ifdef __CLEANUP_SEH
01226 
01227 /*
01228  * Redefine the SEH __except keyword to ensure that applications
01229  * propagate our internal exceptions up to the library's internal handlers.
01230  */
01231 #define __except( E ) \
01232         __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
01233                  ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
01234 
01235 #endif /* __CLEANUP_SEH */
01236 
01237 #ifdef __CLEANUP_CXX
01238 
01239 /*
01240  * Redefine the C++ catch keyword to ensure that applications
01241  * propagate our internal exceptions up to the library's internal handlers.
01242  */
01243 #ifdef _MSC_VER
01244         /*
01245          * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
01246          * if you want Pthread-Win32 cancelation and pthread_exit to work.
01247          */
01248 
01249 #ifndef PtW32NoCatchWarn
01250 
01251 #pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
01252 #pragma message("------------------------------------------------------------------")
01253 #pragma message("When compiling applications with MSVC++ and C++ exception handling:")
01254 #pragma message("  Replace any 'catch( ... )' in routines called from POSIX threads")
01255 #pragma message("  with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
01256 #pragma message("  cancelation and pthread_exit to work. For example:")
01257 #pragma message("")
01258 #pragma message("    #ifdef PtW32CatchAll")
01259 #pragma message("      PtW32CatchAll")
01260 #pragma message("    #else")
01261 #pragma message("      catch(...)")
01262 #pragma message("    #endif")
01263 #pragma message("        {")
01264 #pragma message("          /* Catchall block processing */")
01265 #pragma message("        }")
01266 #pragma message("------------------------------------------------------------------")
01267 
01268 #endif
01269 
01270 #define PtW32CatchAll \
01271         catch( ptw32_exception & ) { throw; } \
01272         catch( ... )
01273 
01274 #else /* _MSC_VER */
01275 
01276 #define catch( E ) \
01277         catch( ptw32_exception & ) { throw; } \
01278         catch( E )
01279 
01280 #endif /* _MSC_VER */
01281 
01282 #endif /* __CLEANUP_CXX */
01283 
01284 #endif /* ! PTW32_BUILD */
01285 
01286 #ifdef __cplusplus
01287 }                               /* End of extern "C" */
01288 #endif                          /* __cplusplus */
01289 
01290 #ifdef PTW32__HANDLE_DEF
01291 # undef HANDLE
01292 #endif
01293 #ifdef PTW32__DWORD_DEF
01294 # undef DWORD
01295 #endif
01296 
01297 #undef PTW32_LEVEL
01298 #undef PTW32_LEVEL_MAX
01299 
01300 #endif /* PTHREAD_H */

Generated on Sun May 14 14:51:20 2006 by  doxygen 1.4.2