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