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


syntax highlighted by Code2HTML, v. 0.9.1