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