Commit | Line | Data |
---|---|---|
abbca718 LOK |
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,8,0,0 | |
41 | #define PTW32_VERSION_STRING "2, 8, 0, 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 | #ifndef 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(PTW32_LEVEL) | |
108 | #define PTW32_LEVEL PTW32_LEVEL_MAX | |
109 | /* Include everything */ | |
110 | #endif | |
111 | ||
112 | #ifdef _UWIN | |
113 | # define HAVE_STRUCT_TIMESPEC 1 | |
114 | # define HAVE_SIGNAL_H 1 | |
115 | # undef HAVE_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(__MINGW32__) && defined(__cplusplus) | |
194 | #define PTW32_INCLUDE_WINDOWS_H | |
195 | #endif | |
196 | ||
197 | #ifdef 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 | #endif | |
207 | /* | |
208 | * ----------------- | |
209 | * autoconf switches | |
210 | * ----------------- | |
211 | */ | |
212 | ||
213 | #if HAVE_CONFIG_H | |
214 | #include "config.h" | |
215 | #endif /* HAVE_CONFIG_H */ | |
216 | ||
217 | #ifndef NEED_FTIME | |
218 | #include <time.h> | |
219 | #else /* NEED_FTIME */ | |
220 | /* use native WIN32 time API */ | |
221 | #endif /* NEED_FTIME */ | |
222 | ||
223 | #if HAVE_SIGNAL_H | |
224 | #include <signal.h> | |
225 | #endif /* HAVE_SIGNAL_H */ | |
226 | ||
227 | #include <setjmp.h> | |
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 | #ifndef PTW32_CONFIG_H | |
244 | # if defined(WINCE) | |
245 | # define NEED_ERRNO | |
246 | # define NEED_SEM | |
247 | # endif | |
248 | # if defined(_UWIN) || defined(__MINGW32__) | |
249 | # define HAVE_MODE_T | |
250 | # endif | |
251 | #endif | |
252 | ||
253 | /* | |
254 | * | |
255 | */ | |
256 | ||
257 | #if PTW32_LEVEL >= PTW32_LEVEL_MAX | |
258 | #ifdef NEED_ERRNO | |
259 | #include "need_errno.h" | |
260 | #else | |
261 | #include <errno.h> | |
262 | #endif | |
263 | #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ | |
264 | ||
265 | /* | |
266 | * Several systems don't define some error numbers. | |
267 | */ | |
268 | #ifndef ENOTSUP | |
269 | # define ENOTSUP 48 /* This is the value in Solaris. */ | |
270 | #endif | |
271 | ||
272 | #ifndef ETIMEDOUT | |
273 | # define ETIMEDOUT 10060 /* This is the value in winsock.h. */ | |
274 | #endif | |
275 | ||
276 | #ifndef ENOSYS | |
277 | # define ENOSYS 140 /* Semi-arbitrary value */ | |
278 | #endif | |
279 | ||
280 | #ifndef EDEADLK | |
281 | # ifdef EDEADLOCK | |
282 | # define EDEADLK EDEADLOCK | |
283 | # else | |
284 | # define EDEADLK 36 /* This is the value in MSVC. */ | |
285 | # endif | |
286 | #endif | |
287 | ||
288 | #include "sched.h" | |
289 | ||
290 | /* | |
291 | * To avoid including windows.h we define only those things that we | |
292 | * actually need from it. | |
293 | */ | |
294 | #ifndef PTW32_INCLUDE_WINDOWS_H | |
295 | #ifndef HANDLE | |
296 | # define PTW32__HANDLE_DEF | |
297 | # define HANDLE void * | |
298 | #endif | |
299 | #ifndef DWORD | |
300 | # define PTW32__DWORD_DEF | |
301 | # define DWORD unsigned long | |
302 | #endif | |
303 | #endif | |
304 | ||
305 | #ifndef HAVE_STRUCT_TIMESPEC | |
306 | #define HAVE_STRUCT_TIMESPEC 1 | |
307 | struct timespec { | |
308 | long tv_sec; | |
309 | long tv_nsec; | |
310 | }; | |
311 | #endif /* HAVE_STRUCT_TIMESPEC */ | |
312 | ||
313 | #ifndef SIG_BLOCK | |
314 | #define SIG_BLOCK 0 | |
315 | #endif /* SIG_BLOCK */ | |
316 | ||
317 | #ifndef SIG_UNBLOCK | |
318 | #define SIG_UNBLOCK 1 | |
319 | #endif /* SIG_UNBLOCK */ | |
320 | ||
321 | #ifndef SIG_SETMASK | |
322 | #define SIG_SETMASK 2 | |
323 | #endif /* SIG_SETMASK */ | |
324 | ||
325 | #ifdef __cplusplus | |
326 | extern "C" | |
327 | { | |
328 | #endif /* __cplusplus */ | |
329 | ||
330 | /* | |
331 | * ------------------------------------------------------------- | |
332 | * | |
333 | * POSIX 1003.1-2001 Options | |
334 | * ========================= | |
335 | * | |
336 | * Options are normally set in <unistd.h>, which is not provided | |
337 | * with pthreads-win32. | |
338 | * | |
339 | * For conformance with the Single Unix Specification (version 3), all of the | |
340 | * options below are defined, and have a value of either -1 (not supported) | |
341 | * or 200112L (supported). | |
342 | * | |
343 | * These options can neither be left undefined nor have a value of 0, because | |
344 | * either indicates that sysconf(), which is not implemented, may be used at | |
345 | * runtime to check the status of the option. | |
346 | * | |
347 | * _POSIX_THREADS (== 200112L) | |
348 | * If == 200112L, you can use threads | |
349 | * | |
350 | * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) | |
351 | * If == 200112L, you can control the size of a thread's | |
352 | * stack | |
353 | * pthread_attr_getstacksize | |
354 | * pthread_attr_setstacksize | |
355 | * | |
356 | * _POSIX_THREAD_ATTR_STACKADDR (== -1) | |
357 | * If == 200112L, you can allocate and control a thread's | |
358 | * stack. If not supported, the following functions | |
359 | * will return ENOSYS, indicating they are not | |
360 | * supported: | |
361 | * pthread_attr_getstackaddr | |
362 | * pthread_attr_setstackaddr | |
363 | * | |
364 | * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) | |
365 | * If == 200112L, you can use realtime scheduling. | |
366 | * This option indicates that the behaviour of some | |
367 | * implemented functions conforms to the additional TPS | |
368 | * requirements in the standard. E.g. rwlocks favour | |
369 | * writers over readers when threads have equal priority. | |
370 | * | |
371 | * _POSIX_THREAD_PRIO_INHERIT (== -1) | |
372 | * If == 200112L, you can create priority inheritance | |
373 | * mutexes. | |
374 | * pthread_mutexattr_getprotocol + | |
375 | * pthread_mutexattr_setprotocol + | |
376 | * | |
377 | * _POSIX_THREAD_PRIO_PROTECT (== -1) | |
378 | * If == 200112L, you can create priority ceiling mutexes | |
379 | * Indicates the availability of: | |
380 | * pthread_mutex_getprioceiling | |
381 | * pthread_mutex_setprioceiling | |
382 | * pthread_mutexattr_getprioceiling | |
383 | * pthread_mutexattr_getprotocol + | |
384 | * pthread_mutexattr_setprioceiling | |
385 | * pthread_mutexattr_setprotocol + | |
386 | * | |
387 | * _POSIX_THREAD_PROCESS_SHARED (== -1) | |
388 | * If set, you can create mutexes and condition | |
389 | * variables that can be shared with another | |
390 | * process.If set, indicates the availability | |
391 | * of: | |
392 | * pthread_mutexattr_getpshared | |
393 | * pthread_mutexattr_setpshared | |
394 | * pthread_condattr_getpshared | |
395 | * pthread_condattr_setpshared | |
396 | * | |
397 | * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) | |
398 | * If == 200112L you can use the special *_r library | |
399 | * functions that provide thread-safe behaviour | |
400 | * | |
401 | * _POSIX_READER_WRITER_LOCKS (== 200112L) | |
402 | * If == 200112L, you can use read/write locks | |
403 | * | |
404 | * _POSIX_SPIN_LOCKS (== 200112L) | |
405 | * If == 200112L, you can use spin locks | |
406 | * | |
407 | * _POSIX_BARRIERS (== 200112L) | |
408 | * If == 200112L, you can use barriers | |
409 | * | |
410 | * + These functions provide both 'inherit' and/or | |
411 | * 'protect' protocol, based upon these macro | |
412 | * settings. | |
413 | * | |
414 | * ------------------------------------------------------------- | |
415 | */ | |
416 | ||
417 | /* | |
418 | * POSIX Options | |
419 | */ | |
420 | #undef _POSIX_THREADS | |
421 | #define _POSIX_THREADS 200112L | |
422 | ||
423 | #undef _POSIX_READER_WRITER_LOCKS | |
424 | #define _POSIX_READER_WRITER_LOCKS 200112L | |
425 | ||
426 | #undef _POSIX_SPIN_LOCKS | |
427 | #define _POSIX_SPIN_LOCKS 200112L | |
428 | ||
429 | #undef _POSIX_BARRIERS | |
430 | #define _POSIX_BARRIERS 200112L | |
431 | ||
432 | #undef _POSIX_THREAD_SAFE_FUNCTIONS | |
433 | #define _POSIX_THREAD_SAFE_FUNCTIONS 200112L | |
434 | ||
435 | #undef _POSIX_THREAD_ATTR_STACKSIZE | |
436 | #define _POSIX_THREAD_ATTR_STACKSIZE 200112L | |
437 | ||
438 | /* | |
439 | * The following options are not supported | |
440 | */ | |
441 | #undef _POSIX_THREAD_ATTR_STACKADDR | |
442 | #define _POSIX_THREAD_ATTR_STACKADDR -1 | |
443 | ||
444 | #undef _POSIX_THREAD_PRIO_INHERIT | |
445 | #define _POSIX_THREAD_PRIO_INHERIT -1 | |
446 | ||
447 | #undef _POSIX_THREAD_PRIO_PROTECT | |
448 | #define _POSIX_THREAD_PRIO_PROTECT -1 | |
449 | ||
450 | /* TPS is not fully supported. */ | |
451 | #undef _POSIX_THREAD_PRIORITY_SCHEDULING | |
452 | #define _POSIX_THREAD_PRIORITY_SCHEDULING -1 | |
453 | ||
454 | #undef _POSIX_THREAD_PROCESS_SHARED | |
455 | #define _POSIX_THREAD_PROCESS_SHARED -1 | |
456 | ||
457 | ||
458 | /* | |
459 | * POSIX 1003.1-2001 Limits | |
460 | * =========================== | |
461 | * | |
462 | * These limits are normally set in <limits.h>, which is not provided with | |
463 | * pthreads-win32. | |
464 | * | |
465 | * PTHREAD_DESTRUCTOR_ITERATIONS | |
466 | * Maximum number of attempts to destroy | |
467 | * a thread's thread-specific data on | |
468 | * termination (must be at least 4) | |
469 | * | |
470 | * PTHREAD_KEYS_MAX | |
471 | * Maximum number of thread-specific data keys | |
472 | * available per process (must be at least 128) | |
473 | * | |
474 | * PTHREAD_STACK_MIN | |
475 | * Minimum supported stack size for a thread | |
476 | * | |
477 | * PTHREAD_THREADS_MAX | |
478 | * Maximum number of threads supported per | |
479 | * process (must be at least 64). | |
480 | * | |
481 | * SEM_NSEMS_MAX | |
482 | * The maximum number of semaphores a process can have. | |
483 | * (must be at least 256) | |
484 | * | |
485 | * SEM_VALUE_MAX | |
486 | * The maximum value a semaphore can have. | |
487 | * (must be at least 32767) | |
488 | * | |
489 | */ | |
490 | #undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS | |
491 | #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 | |
492 | ||
493 | #undef PTHREAD_DESTRUCTOR_ITERATIONS | |
494 | #define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS | |
495 | ||
496 | #undef _POSIX_THREAD_KEYS_MAX | |
497 | #define _POSIX_THREAD_KEYS_MAX 128 | |
498 | ||
499 | #undef PTHREAD_KEYS_MAX | |
500 | #define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX | |
501 | ||
502 | #undef PTHREAD_STACK_MIN | |
503 | #define PTHREAD_STACK_MIN 0 | |
504 | ||
505 | #undef _POSIX_THREAD_THREADS_MAX | |
506 | #define _POSIX_THREAD_THREADS_MAX 64 | |
507 | ||
508 | /* Arbitrary value */ | |
509 | #undef PTHREAD_THREADS_MAX | |
510 | #define PTHREAD_THREADS_MAX 2019 | |
511 | ||
512 | #undef _POSIX_SEM_NSEMS_MAX | |
513 | #define _POSIX_SEM_NSEMS_MAX 256 | |
514 | ||
515 | /* Arbitrary value */ | |
516 | #undef SEM_NSEMS_MAX | |
517 | #define SEM_NSEMS_MAX 1024 | |
518 | ||
519 | #undef _POSIX_SEM_VALUE_MAX | |
520 | #define _POSIX_SEM_VALUE_MAX 32767 | |
521 | ||
522 | #undef SEM_VALUE_MAX | |
523 | #define SEM_VALUE_MAX INT_MAX | |
524 | ||
525 | ||
526 | #if __GNUC__ && ! defined (__declspec) | |
527 | # error Please upgrade your GNU compiler to one that supports __declspec. | |
528 | #endif | |
529 | ||
530 | /* | |
531 | * When building the DLL code, you should define PTW32_BUILD so that | |
532 | * the variables/functions are exported correctly. When using the DLL, | |
533 | * do NOT define PTW32_BUILD, and then the variables/functions will | |
534 | * be imported correctly. | |
535 | */ | |
536 | #ifndef PTW32_STATIC_LIB | |
537 | # ifdef PTW32_BUILD | |
538 | # define PTW32_DLLPORT __declspec (dllexport) | |
539 | # else | |
540 | # define PTW32_DLLPORT __declspec (dllimport) | |
541 | # endif | |
542 | #else | |
543 | # define PTW32_DLLPORT | |
544 | #endif | |
545 | ||
546 | /* | |
547 | * The Open Watcom C/C++ compiler uses a non-standard calling convention | |
548 | * that passes function args in registers unless __cdecl is explicitly specified | |
549 | * in exposed function prototypes. | |
550 | * | |
551 | * We force all calls to cdecl even though this could slow Watcom code down | |
552 | * slightly. If you know that the Watcom compiler will be used to build both | |
553 | * the DLL and application, then you can probably define this as a null string. | |
554 | * Remember that pthread.h (this file) is used for both the DLL and application builds. | |
555 | */ | |
556 | #define PTW32_CDECL __cdecl | |
557 | ||
558 | #if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX | |
559 | # include <sys/types.h> | |
560 | #else | |
561 | /* | |
562 | * Generic handle type - intended to extend uniqueness beyond | |
563 | * that available with a simple pointer. It should scale for either | |
564 | * IA-32 or IA-64. | |
565 | */ | |
566 | typedef struct { | |
567 | void * p; /* Pointer to actual object */ | |
568 | unsigned int x; /* Extra information - reuse count etc */ | |
569 | } ptw32_handle_t; | |
570 | ||
571 | typedef ptw32_handle_t pthread_t; | |
572 | typedef struct pthread_attr_t_ * pthread_attr_t; | |
573 | typedef struct pthread_once_t_ pthread_once_t; | |
574 | typedef struct pthread_key_t_ * pthread_key_t; | |
575 | typedef struct pthread_mutex_t_ * pthread_mutex_t; | |
576 | typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; | |
577 | typedef struct pthread_cond_t_ * pthread_cond_t; | |
578 | typedef struct pthread_condattr_t_ * pthread_condattr_t; | |
579 | #endif | |
580 | typedef struct pthread_rwlock_t_ * pthread_rwlock_t; | |
581 | typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; | |
582 | typedef struct pthread_spinlock_t_ * pthread_spinlock_t; | |
583 | typedef struct pthread_barrier_t_ * pthread_barrier_t; | |
584 | typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; | |
585 | ||
586 | /* | |
587 | * ==================== | |
588 | * ==================== | |
589 | * POSIX Threads | |
590 | * ==================== | |
591 | * ==================== | |
592 | */ | |
593 | ||
594 | enum { | |
595 | /* | |
596 | * pthread_attr_{get,set}detachstate | |
597 | */ | |
598 | PTHREAD_CREATE_JOINABLE = 0, /* Default */ | |
599 | PTHREAD_CREATE_DETACHED = 1, | |
600 | ||
601 | /* | |
602 | * pthread_attr_{get,set}inheritsched | |
603 | */ | |
604 | PTHREAD_INHERIT_SCHED = 0, | |
605 | PTHREAD_EXPLICIT_SCHED = 1, /* Default */ | |
606 | ||
607 | /* | |
608 | * pthread_{get,set}scope | |
609 | */ | |
610 | PTHREAD_SCOPE_PROCESS = 0, | |
611 | PTHREAD_SCOPE_SYSTEM = 1, /* Default */ | |
612 | ||
613 | /* | |
614 | * pthread_setcancelstate paramters | |
615 | */ | |
616 | PTHREAD_CANCEL_ENABLE = 0, /* Default */ | |
617 | PTHREAD_CANCEL_DISABLE = 1, | |
618 | ||
619 | /* | |
620 | * pthread_setcanceltype parameters | |
621 | */ | |
622 | PTHREAD_CANCEL_ASYNCHRONOUS = 0, | |
623 | PTHREAD_CANCEL_DEFERRED = 1, /* Default */ | |
624 | ||
625 | /* | |
626 | * pthread_mutexattr_{get,set}pshared | |
627 | * pthread_condattr_{get,set}pshared | |
628 | */ | |
629 | PTHREAD_PROCESS_PRIVATE = 0, | |
630 | PTHREAD_PROCESS_SHARED = 1, | |
631 | ||
632 | /* | |
633 | * pthread_barrier_wait | |
634 | */ | |
635 | PTHREAD_BARRIER_SERIAL_THREAD = -1 | |
636 | }; | |
637 | ||
638 | /* | |
639 | * ==================== | |
640 | * ==================== | |
641 | * Cancelation | |
642 | * ==================== | |
643 | * ==================== | |
644 | */ | |
645 | #define PTHREAD_CANCELED ((void *) -1) | |
646 | ||
647 | ||
648 | /* | |
649 | * ==================== | |
650 | * ==================== | |
651 | * Once Key | |
652 | * ==================== | |
653 | * ==================== | |
654 | */ | |
655 | #define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} | |
656 | ||
657 | struct pthread_once_t_ | |
658 | { | |
659 | int done; /* indicates if user function has been executed */ | |
660 | void * lock; | |
661 | int reserved1; | |
662 | int reserved2; | |
663 | }; | |
664 | ||
665 | ||
666 | /* | |
667 | * ==================== | |
668 | * ==================== | |
669 | * Object initialisers | |
670 | * ==================== | |
671 | * ==================== | |
672 | */ | |
673 | #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) | |
674 | #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2) | |
675 | #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3) | |
676 | ||
677 | /* | |
678 | * Compatibility with LinuxThreads | |
679 | */ | |
680 | #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER | |
681 | #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER | |
682 | ||
683 | #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) | |
684 | ||
685 | #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1) | |
686 | ||
687 | #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1) | |
688 | ||
689 | ||
690 | /* | |
691 | * Mutex types. | |
692 | */ | |
693 | enum | |
694 | { | |
695 | /* Compatibility with LinuxThreads */ | |
696 | PTHREAD_MUTEX_FAST_NP, | |
697 | PTHREAD_MUTEX_RECURSIVE_NP, | |
698 | PTHREAD_MUTEX_ERRORCHECK_NP, | |
699 | PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, | |
700 | PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, | |
701 | /* For compatibility with POSIX */ | |
702 | PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, | |
703 | PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, | |
704 | PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, | |
705 | PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL | |
706 | }; | |
707 | ||
708 | ||
709 | typedef struct ptw32_cleanup_t ptw32_cleanup_t; | |
710 | ||
711 | #if defined(_MSC_VER) | |
712 | /* Disable MSVC 'anachronism used' warning */ | |
713 | #pragma warning( disable : 4229 ) | |
714 | #endif | |
715 | ||
716 | typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); | |
717 | ||
718 | #if defined(_MSC_VER) | |
719 | #pragma warning( default : 4229 ) | |
720 | #endif | |
721 | ||
722 | struct ptw32_cleanup_t | |
723 | { | |
724 | ptw32_cleanup_callback_t routine; | |
725 | void *arg; | |
726 | struct ptw32_cleanup_t *prev; | |
727 | }; | |
728 | ||
729 | #ifdef __CLEANUP_SEH | |
730 | /* | |
731 | * WIN32 SEH version of cancel cleanup. | |
732 | */ | |
733 | ||
734 | #define pthread_cleanup_push( _rout, _arg ) \ | |
735 | { \ | |
736 | ptw32_cleanup_t _cleanup; \ | |
737 | \ | |
738 | _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ | |
739 | _cleanup.arg = (_arg); \ | |
740 | __try \ | |
741 | { \ | |
742 | ||
743 | #define pthread_cleanup_pop( _execute ) \ | |
744 | } \ | |
745 | __finally \ | |
746 | { \ | |
747 | if( _execute || AbnormalTermination()) \ | |
748 | { \ | |
749 | (*(_cleanup.routine))( _cleanup.arg ); \ | |
750 | } \ | |
751 | } \ | |
752 | } | |
753 | ||
754 | #else /* __CLEANUP_SEH */ | |
755 | ||
756 | #ifdef __CLEANUP_C | |
757 | ||
758 | /* | |
759 | * C implementation of PThreads cancel cleanup | |
760 | */ | |
761 | ||
762 | #define pthread_cleanup_push( _rout, _arg ) \ | |
763 | { \ | |
764 | ptw32_cleanup_t _cleanup; \ | |
765 | \ | |
766 | ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ | |
767 | ||
768 | #define pthread_cleanup_pop( _execute ) \ | |
769 | (void) ptw32_pop_cleanup( _execute ); \ | |
770 | } | |
771 | ||
772 | #else /* __CLEANUP_C */ | |
773 | ||
774 | #ifdef __CLEANUP_CXX | |
775 | ||
776 | /* | |
777 | * C++ version of cancel cleanup. | |
778 | * - John E. Bossom. | |
779 | */ | |
780 | ||
781 | class PThreadCleanup { | |
782 | /* | |
783 | * PThreadCleanup | |
784 | * | |
785 | * Purpose | |
786 | * This class is a C++ helper class that is | |
787 | * used to implement pthread_cleanup_push/ | |
788 | * pthread_cleanup_pop. | |
789 | * The destructor of this class automatically | |
790 | * pops the pushed cleanup routine regardless | |
791 | * of how the code exits the scope | |
792 | * (i.e. such as by an exception) | |
793 | */ | |
794 | ptw32_cleanup_callback_t cleanUpRout; | |
795 | void * obj; | |
796 | int executeIt; | |
797 | ||
798 | public: | |
799 | PThreadCleanup() : | |
800 | cleanUpRout( 0 ), | |
801 | obj( 0 ), | |
802 | executeIt( 0 ) | |
803 | /* | |
804 | * No cleanup performed | |
805 | */ | |
806 | { | |
807 | } | |
808 | ||
809 | PThreadCleanup( | |
810 | ptw32_cleanup_callback_t routine, | |
811 | void * arg ) : | |
812 | cleanUpRout( routine ), | |
813 | obj( arg ), | |
814 | executeIt( 1 ) | |
815 | /* | |
816 | * Registers a cleanup routine for 'arg' | |
817 | */ | |
818 | { | |
819 | } | |
820 | ||
821 | ~PThreadCleanup() | |
822 | { | |
823 | if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) | |
824 | { | |
825 | (void) (*cleanUpRout)( obj ); | |
826 | } | |
827 | } | |
828 | ||
829 | void execute( int exec ) | |
830 | { | |
831 | executeIt = exec; | |
832 | } | |
833 | }; | |
834 | ||
835 | /* | |
836 | * C++ implementation of PThreads cancel cleanup; | |
837 | * This implementation takes advantage of a helper | |
838 | * class who's destructor automatically calls the | |
839 | * cleanup routine if we exit our scope weirdly | |
840 | */ | |
841 | #define pthread_cleanup_push( _rout, _arg ) \ | |
842 | { \ | |
843 | PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ | |
844 | (void *) (_arg) ); | |
845 | ||
846 | #define pthread_cleanup_pop( _execute ) \ | |
847 | cleanup.execute( _execute ); \ | |
848 | } | |
849 | ||
850 | #else | |
851 | ||
852 | #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. | |
853 | ||
854 | #endif /* __CLEANUP_CXX */ | |
855 | ||
856 | #endif /* __CLEANUP_C */ | |
857 | ||
858 | #endif /* __CLEANUP_SEH */ | |
859 | ||
860 | /* | |
861 | * =============== | |
862 | * =============== | |
863 | * Methods | |
864 | * =============== | |
865 | * =============== | |
866 | */ | |
867 | ||
868 | /* | |
869 | * PThread Attribute Functions | |
870 | */ | |
871 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); | |
872 | ||
873 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); | |
874 | ||
875 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, | |
876 | int *detachstate); | |
877 | ||
878 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, | |
879 | void **stackaddr); | |
880 | ||
881 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, | |
882 | size_t * stacksize); | |
883 | ||
884 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, | |
885 | int detachstate); | |
886 | ||
887 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, | |
888 | void *stackaddr); | |
889 | ||
890 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, | |
891 | size_t stacksize); | |
892 | ||
893 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, | |
894 | struct sched_param *param); | |
895 | ||
896 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, | |
897 | const struct sched_param *param); | |
898 | ||
899 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, | |
900 | int); | |
901 | ||
902 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (pthread_attr_t *, | |
903 | int *); | |
904 | ||
905 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, | |
906 | int inheritsched); | |
907 | ||
908 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(pthread_attr_t * attr, | |
909 | int * inheritsched); | |
910 | ||
911 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, | |
912 | int); | |
913 | ||
914 | PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, | |
915 | int *); | |
916 | ||
917 | /* | |
918 | * PThread Functions | |
919 | */ | |
920 | PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, | |
921 | const pthread_attr_t * attr, | |
922 | void *(*start) (void *), | |
923 | void *arg); | |
924 | ||
925 | PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); | |
926 | ||
927 | PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, | |
928 | pthread_t t2); | |
929 | ||
930 | PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); | |
931 | ||
932 | PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, | |
933 | void **value_ptr); | |
934 | ||
935 | PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); | |
936 | ||
937 | PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); | |
938 | ||
939 | PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, | |
940 | int *oldstate); | |
941 | ||
942 | PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, | |
943 | int *oldtype); | |
944 | ||
945 | PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); | |
946 | ||
947 | PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, | |
948 | void (*init_routine) (void)); | |
949 | ||
950 | #if PTW32_LEVEL >= PTW32_LEVEL_MAX | |
951 | PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); | |
952 | ||
953 | PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, | |
954 | void (*routine) (void *), | |
955 | void *arg); | |
956 | #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ | |
957 | ||
958 | /* | |
959 | * Thread Specific Data Functions | |
960 | */ | |
961 | PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, | |
962 | void (*destructor) (void *)); | |
963 | ||
964 | PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); | |
965 | ||
966 | PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, | |
967 | const void *value); | |
968 | ||
969 | PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); | |
970 | ||
971 | ||
972 | /* | |
973 | * Mutex Attribute Functions | |
974 | */ | |
975 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); | |
976 | ||
977 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); | |
978 | ||
979 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t | |
980 | * attr, | |
981 | int *pshared); | |
982 | ||
983 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, | |
984 | int pshared); | |
985 | ||
986 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); | |
987 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind); | |
988 | ||
989 | /* | |
990 | * Barrier Attribute Functions | |
991 | */ | |
992 | PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); | |
993 | ||
994 | PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); | |
995 | ||
996 | PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t | |
997 | * attr, | |
998 | int *pshared); | |
999 | ||
1000 | PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, | |
1001 | int pshared); | |
1002 | ||
1003 | /* | |
1004 | * Mutex Functions | |
1005 | */ | |
1006 | PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, | |
1007 | const pthread_mutexattr_t * attr); | |
1008 | ||
1009 | PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); | |
1010 | ||
1011 | PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); | |
1012 | ||
1013 | PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t *mutex, | |
1014 | const struct timespec *abstime); | |
1015 | ||
1016 | PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); | |
1017 | ||
1018 | PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); | |
1019 | ||
1020 | /* | |
1021 | * Spinlock Functions | |
1022 | */ | |
1023 | PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); | |
1024 | ||
1025 | PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); | |
1026 | ||
1027 | PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); | |
1028 | ||
1029 | PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); | |
1030 | ||
1031 | PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); | |
1032 | ||
1033 | /* | |
1034 | * Barrier Functions | |
1035 | */ | |
1036 | PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, | |
1037 | const pthread_barrierattr_t * attr, | |
1038 | unsigned int count); | |
1039 | ||
1040 | PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); | |
1041 | ||
1042 | PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); | |
1043 | ||
1044 | /* | |
1045 | * Condition Variable Attribute Functions | |
1046 | */ | |
1047 | PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); | |
1048 | ||
1049 | PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); | |
1050 | ||
1051 | PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, | |
1052 | int *pshared); | |
1053 | ||
1054 | PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, | |
1055 | int pshared); | |
1056 | ||
1057 | /* | |
1058 | * Condition Variable Functions | |
1059 | */ | |
1060 | PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, | |
1061 | const pthread_condattr_t * attr); | |
1062 | ||
1063 | PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); | |
1064 | ||
1065 | PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, | |
1066 | pthread_mutex_t * mutex); | |
1067 | ||
1068 | PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, | |
1069 | pthread_mutex_t * mutex, | |
1070 | const struct timespec *abstime); | |
1071 | ||
1072 | PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); | |
1073 | ||
1074 | PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); | |
1075 | ||
1076 | /* | |
1077 | * Scheduling | |
1078 | */ | |
1079 | PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, | |
1080 | int policy, | |
1081 | const struct sched_param *param); | |
1082 | ||
1083 | PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, | |
1084 | int *policy, | |
1085 | struct sched_param *param); | |
1086 | ||
1087 | PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); | |
1088 | ||
1089 | PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); | |
1090 | ||
1091 | /* | |
1092 | * Read-Write Lock Functions | |
1093 | */ | |
1094 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, | |
1095 | const pthread_rwlockattr_t *attr); | |
1096 | ||
1097 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); | |
1098 | ||
1099 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); | |
1100 | ||
1101 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); | |
1102 | ||
1103 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); | |
1104 | ||
1105 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, | |
1106 | const struct timespec *abstime); | |
1107 | ||
1108 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); | |
1109 | ||
1110 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, | |
1111 | const struct timespec *abstime); | |
1112 | ||
1113 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); | |
1114 | ||
1115 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); | |
1116 | ||
1117 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); | |
1118 | ||
1119 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, | |
1120 | int *pshared); | |
1121 | ||
1122 | PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, | |
1123 | int pshared); | |
1124 | ||
1125 | #if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 | |
1126 | ||
1127 | /* | |
1128 | * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32 | |
1129 | * already have signal.h that don't define these. | |
1130 | */ | |
1131 | PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); | |
1132 | ||
1133 | /* | |
1134 | * Non-portable functions | |
1135 | */ | |
1136 | ||
1137 | /* | |
1138 | * Compatibility with Linux. | |
1139 | */ | |
1140 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, | |
1141 | int kind); | |
1142 | PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, | |
1143 | int *kind); | |
1144 | ||
1145 | /* | |
1146 | * Possibly supported by other POSIX threads implementations | |
1147 | */ | |
1148 | PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); | |
1149 | PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); | |
1150 | ||
1151 | /* | |
1152 | * Useful if an application wants to statically link | |
1153 | * the lib rather than load the DLL at run-time. | |
1154 | */ | |
1155 | PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); | |
1156 | PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); | |
1157 | PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); | |
1158 | PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); | |
1159 | ||
1160 | /* | |
1161 | * Features that are auto-detected at load/run time. | |
1162 | */ | |
1163 | PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); | |
1164 | enum ptw32_features { | |
1165 | PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ | |
1166 | PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ | |
1167 | }; | |
1168 | ||
1169 | /* | |
1170 | * Register a system time change with the library. | |
1171 | * Causes the library to perform various functions | |
1172 | * in response to the change. Should be called whenever | |
1173 | * the application's top level window receives a | |
1174 | * WM_TIMECHANGE message. It can be passed directly to | |
1175 | * pthread_create() as a new thread if desired. | |
1176 | */ | |
1177 | PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); | |
1178 | ||
1179 | #endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ | |
1180 | ||
1181 | #if PTW32_LEVEL >= PTW32_LEVEL_MAX | |
1182 | ||
1183 | /* | |
1184 | * Returns the Win32 HANDLE for the POSIX thread. | |
1185 | */ | |
1186 | PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); | |
1187 | ||
1188 | ||
1189 | /* | |
1190 | * Protected Methods | |
1191 | * | |
1192 | * This function blocks until the given WIN32 handle | |
1193 | * is signaled or pthread_cancel had been called. | |
1194 | * This function allows the caller to hook into the | |
1195 | * PThreads cancel mechanism. It is implemented using | |
1196 | * | |
1197 | * WaitForMultipleObjects | |
1198 | * | |
1199 | * on 'waitHandle' and a manually reset WIN32 Event | |
1200 | * used to implement pthread_cancel. The 'timeout' | |
1201 | * argument to TimedWait is simply passed to | |
1202 | * WaitForMultipleObjects. | |
1203 | */ | |
1204 | PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); | |
1205 | PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, | |
1206 | DWORD timeout); | |
1207 | ||
1208 | #endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ | |
1209 | ||
1210 | /* | |
1211 | * Thread-Safe C Runtime Library Mappings. | |
1212 | */ | |
1213 | #ifndef _UWIN | |
1214 | # if defined(NEED_ERRNO) | |
1215 | PTW32_DLLPORT int * PTW32_CDECL _errno( void ); | |
1216 | # else | |
1217 | # ifndef errno | |
1218 | # if (defined(_MT) || defined(_DLL)) | |
1219 | __declspec(dllimport) extern int * __cdecl _errno(void); | |
1220 | # define errno (*_errno()) | |
1221 | # endif | |
1222 | # endif | |
1223 | # endif | |
1224 | #endif | |
1225 | ||
1226 | /* | |
1227 | * WIN32 C runtime library had been made thread-safe | |
1228 | * without affecting the user interface. Provide | |
1229 | * mappings from the UNIX thread-safe versions to | |
1230 | * the standard C runtime library calls. | |
1231 | * Only provide function mappings for functions that | |
1232 | * actually exist on WIN32. | |
1233 | */ | |
1234 | ||
1235 | #if !defined(__MINGW32__) | |
1236 | #define strtok_r( _s, _sep, _lasts ) \ | |
1237 | ( *(_lasts) = strtok( (_s), (_sep) ) ) | |
1238 | #endif /* !__MINGW32__ */ | |
1239 | ||
1240 | #define asctime_r( _tm, _buf ) \ | |
1241 | ( strcpy( (_buf), asctime( (_tm) ) ), \ | |
1242 | (_buf) ) | |
1243 | ||
1244 | #define ctime_r( _clock, _buf ) \ | |
1245 | ( strcpy( (_buf), ctime( (_clock) ) ), \ | |
1246 | (_buf) ) | |
1247 | ||
1248 | #define gmtime_r( _clock, _result ) \ | |
1249 | ( *(_result) = *gmtime( (_clock) ), \ | |
1250 | (_result) ) | |
1251 | ||
1252 | #define localtime_r( _clock, _result ) \ | |
1253 | ( *(_result) = *localtime( (_clock) ), \ | |
1254 | (_result) ) | |
1255 | ||
1256 | #define rand_r( _seed ) \ | |
1257 | ( _seed == _seed? rand() : rand() ) | |
1258 | ||
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 | #ifdef __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 | #ifndef PTW32_BUILD | |
1290 | ||
1291 | #ifdef __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 | #ifdef __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 | #ifdef _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 | #ifndef 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(" #ifdef 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 | #ifdef __cplusplus | |
1353 | } /* End of extern "C" */ | |
1354 | #endif /* __cplusplus */ | |
1355 | ||
1356 | #ifdef PTW32__HANDLE_DEF | |
1357 | # undef HANDLE | |
1358 | #endif | |
1359 | #ifdef 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 */ |