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