Hamlib  4.7~git
winpthreads.h
1 /*
2  * Posix Threads library for Microsoft Windows
3  *
4  * Use at own risk, there is no implied warranty to this code.
5  * It uses undocumented features of Microsoft Windows that can change
6  * at any time in the future.
7  *
8  * (C) 2010 Lockless Inc.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  *
15  * * Redistributions of source code must retain the above copyright notice,
16  * this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright notice,
18  * this list of conditions and the following disclaimer in the documentation
19  * and/or other materials provided with the distribution.
20  * * Neither the name of Lockless Inc. nor the names of its contributors may be
21  * used to endorse or promote products derived from this software without
22  * specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /*
37  * You may want to use the MingW64 winpthreads library instead.
38  * It is based on this, but adds error checking.
39  */
40 
41 /*
42  * Version 1.0.1 Released 2 Feb 2012
43  * Fixes pthread_barrier_destroy() to wait for threads to exit the barrier.
44  */
45 
46 #ifndef WIN_PTHREADS
47 #define WIN_PTHREADS
48 
49 
50 #include <windows.h>
51 #include <setjmp.h>
52 #include <errno.h>
53 #include <sys/timeb.h>
54 #include <process.h>
55 
56 //#define ETIMEDOUT 110
57 //#define ENOTSUP 134
58 
59 
60 #define PTHREAD_CANCEL_DISABLE 0
61 #define PTHREAD_CANCEL_ENABLE 0x01
62 
63 #define PTHREAD_CANCEL_DEFERRED 0
64 #define PTHREAD_CANCEL_ASYNCHRONOUS 0x02
65 
66 #define PTHREAD_CREATE_JOINABLE 0
67 #define PTHREAD_CREATE_DETACHED 0x04
68 
69 #define PTHREAD_EXPLICT_SCHED 0
70 #define PTHREAD_INHERIT_SCHED 0x08
71 
72 #define PTHREAD_SCOPE_PROCESS 0
73 #define PTHREAD_SCOPE_SYSTEM 0x10
74 
75 #define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)
76 
77 //#define PTHREAD_CANCELED ((void *) (unsigned long)0xDEADBEEF)
78 
79 #define PTHREAD_ONCE_INIT 0
80 #define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
81 #define PTHREAD_RWLOCK_INITIALIZER {0}
82 #define PTHREAD_COND_INITIALIZER {0}
83 #define PTHREAD_BARRIER_INITIALIZER \
84  {0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
85 #define PTHREAD_SPINLOCK_INITIALIZER 0
86 
87 #define PTHREAD_DESTRUCTOR_ITERATIONS 256
88 #define PTHREAD_KEYS_MAX (1<<20)
89 
90 #define PTHREAD_MUTEX_NORMAL 0
91 #define PTHREAD_MUTEX_ERRORCHECK 1
92 #define PTHREAD_MUTEX_RECURSIVE 2
93 #define PTHREAD_MUTEX_DEFAULT 3
94 #define PTHREAD_MUTEX_SHARED 4
95 #define PTHREAD_MUTEX_PRIVATE 0
96 #define PTHREAD_PRIO_NONE 0
97 #define PTHREAD_PRIO_INHERIT 8
98 #define PTHREAD_PRIO_PROTECT 16
99 #define PTHREAD_PRIO_MULT 32
100 #define PTHREAD_PROCESS_SHARED 0
101 #define PTHREAD_PROCESS_PRIVATE 1
102 
103 #define PTHREAD_BARRIER_SERIAL_THREAD 1
104 
105 
106 #if 0
107 /* Windows doesn't have this, so declare it ourselves. */
108 struct timespec
109 {
110  /* long long in windows is the same as long in unix for 64bit */
111  long long tv_sec;
112  long long tv_nsec;
113 };
114 #endif
115 typedef struct _pthread_cleanup _pthread_cleanup;
117 {
118  void (*func)(void *);
119  void *arg;
120  _pthread_cleanup *next;
121 };
122 
124 {
125  void *ret_arg;
126  void *(* func)(void *);
127  _pthread_cleanup *clean;
128  HANDLE h;
129  int cancelled;
130  unsigned p_state;
131  unsigned keymax;
132  void **keyval;
133 
134  jmp_buf jb;
135 };
136 
137 typedef struct _pthread_v *pthread_t;
138 
139 typedef struct pthread_barrier_t pthread_barrier_t;
141 {
142  int count;
143  int total;
144  CRITICAL_SECTION m;
145  CONDITION_VARIABLE cv;
146 };
147 
148 typedef struct pthread_attr_t pthread_attr_t;
150 {
151  unsigned p_state;
152  void *stack;
153  size_t s_size;
154 };
155 
156 typedef long pthread_once_t;
157 typedef unsigned pthread_mutexattr_t;
158 typedef SRWLOCK pthread_rwlock_t;
159 typedef CRITICAL_SECTION pthread_mutex_t;
160 typedef unsigned pthread_key_t;
161 typedef void *pthread_barrierattr_t;
162 typedef long pthread_spinlock_t;
163 typedef int pthread_condattr_t;
164 typedef CONDITION_VARIABLE pthread_cond_t;
165 typedef int pthread_rwlockattr_t;
166 
167 volatile long _pthread_cancelling;
168 
169 int _pthread_concur;
170 
171 /* Will default to zero as needed */
172 pthread_once_t _pthread_tls_once;
173 DWORD _pthread_tls;
174 
175 /* Note initializer is zero, so this works */
176 pthread_rwlock_t _pthread_key_lock;
177 unsigned _pthread_key_max;
178 unsigned _pthread_key_sch;
179 void (**_pthread_key_dest)(void*);
180 
181 
182 #if 0
183 #define pthread_cleanup_push(F, A)\
184 {\
185  const _pthread_cleanup _pthread_cup = {(F), (A), pthread_self()->clean};\
186  _ReadWriteBarrier();\
187  pthread_self()->clean = (_pthread_cleanup *) &_pthread_cup;
188 _ReadWriteBarrier(); }
189 #endif
190 /* Note that if async cancelling is used, then there is a race here */
191 #define pthread_cleanup_pop(E)\
192 {\
193  (pthread_self()->clean = _pthread_cup.next, (E?_pthread_cup.func(_pthread_cup.arg):0));}
194 
195 static void _pthread_once_cleanup(pthread_once_t *o)
196 {
197  *o = 0;
198 }
199 
200 static pthread_t pthread_self(void);
201 static int pthread_once(pthread_once_t *o, void (*func)(void))
202 {
203  long state = *o;
204 
205  _ReadWriteBarrier();
206 
207  while (state != 1)
208  {
209  if (!state)
210  {
211  if (!_InterlockedCompareExchange(o, 2, 0))
212  {
213  /* Success */
214  //pthread_cleanup_push((void**)(void*))_pthread_once_cleanup, o);
215  //pthread_cleanup_push((void*)_pthread_once_cleanup, o);
216  /*
217  {
218  static const _pthread_cleanup _pthread_cup = { ((void*)_pthread_once_cleanup), ((void*)o), pthread_self()->clean };
219  _ReadWriteBarrier();
220  pthread_self()->clean = (_pthread_cleanup*)&_pthread_cup;
221  _ReadWriteBarrier(); }
222  func();
223  pthread_cleanup_pop(0);
224  */
225  /* Mark as done */
226  *o = 1;
227 
228  return 0;
229  }
230  }
231 
232  YieldProcessor();
233 
234  _ReadWriteBarrier();
235 
236  state = *o;
237  }
238 
239  /* Done */
240  return 0;
241 }
242 
243 static int _pthread_once_raw(pthread_once_t *o, void (*func)(void))
244 {
245  long state = *o;
246 
247  _ReadWriteBarrier();
248 
249  while (state != 1)
250  {
251  if (!state)
252  {
253  if (!_InterlockedCompareExchange(o, 2, 0))
254  {
255  /* Success */
256  func();
257 
258  /* Mark as done */
259  *o = 1;
260 
261  return 0;
262  }
263  }
264 
265  YieldProcessor();
266 
267  _ReadWriteBarrier();
268 
269  state = *o;
270  }
271 
272  /* Done */
273  return 0;
274 }
275 
276 static int pthread_mutex_lock(pthread_mutex_t *m)
277 {
278  EnterCriticalSection(m);
279  return 0;
280 }
281 
282 static int pthread_mutex_unlock(pthread_mutex_t *m)
283 {
284  LeaveCriticalSection(m);
285  return 0;
286 }
287 
288 static int pthread_mutex_trylock(pthread_mutex_t *m)
289 {
290  return TryEnterCriticalSection(m) ? 0 : EBUSY;
291 }
292 
293 static int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a)
294 {
295  (void) a;
296  InitializeCriticalSection(m);
297 
298  return 0;
299 }
300 
301 static int pthread_mutex_destroy(pthread_mutex_t *m)
302 {
303  DeleteCriticalSection(m);
304  return 0;
305 }
306 
307 #define pthread_mutex_getprioceiling(M, P) ENOTSUP
308 #define pthread_mutex_setprioceiling(M, P) ENOTSUP
309 
310 static int pthread_equal(pthread_t t1, pthread_t t2)
311 {
312  return t1 == t2;
313 }
314 
315 static void pthread_testcancel(void);
316 
317 static int pthread_rwlock_init(pthread_rwlock_t *l, pthread_rwlockattr_t *a)
318 {
319  (void) a;
320  InitializeSRWLock(l);
321 
322  return 0;
323 }
324 
325 static int pthread_rwlock_destroy(pthread_rwlock_t *l)
326 {
327  (void) *l;
328  return 0;
329 }
330 
331 static int pthread_rwlock_rdlock(pthread_rwlock_t *l)
332 {
333  pthread_testcancel();
334  AcquireSRWLockShared(l);
335 
336  return 0;
337 }
338 
339 static int pthread_rwlock_wrlock(pthread_rwlock_t *l)
340 {
341  pthread_testcancel();
342  AcquireSRWLockExclusive(l);
343 
344  return 0;
345 }
346 
347 static void pthread_tls_init(void)
348 {
349  _pthread_tls = TlsAlloc();
350 
351  /* Cannot continue if out of indexes */
352  if (_pthread_tls == TLS_OUT_OF_INDEXES) abort();
353 }
354 
355 static int pthread_rwlock_unlock(pthread_rwlock_t* l)
356 {
357  void* state = *(void**)l;
358 
359  if (state == (void*)1)
360  {
361  /* Known to be an exclusive lock */
362  ReleaseSRWLockExclusive(l);
363  }
364  else
365  {
366  /* A shared unlock will work */
367  ReleaseSRWLockShared(l);
368  }
369 
370  return 0;
371 }
372 
373 
374 static void _pthread_cleanup_dest(pthread_t t)
375 {
376  unsigned i, j;
377 
378  for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++)
379  {
380  int flag = 0;
381 
382  for (i = 0; i < t->keymax; i++)
383  {
384  void *val = t->keyval[i];
385 
386  if (val)
387  {
388  pthread_rwlock_rdlock(&_pthread_key_lock);
389  if ((uintptr_t) _pthread_key_dest[i] > 1)
390  {
391  /* Call destructor */
392  t->keyval[i] = NULL;
393  _pthread_key_dest[i](val);
394  flag = 1;
395  }
396  pthread_rwlock_unlock(&_pthread_key_lock);
397  }
398  }
399 
400  /* Nothing to do? */
401  if (!flag) return;
402  }
403 }
404 
405 static pthread_t pthread_self(void)
406 {
407  pthread_t t;
408 
409  _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);
410 
411  t = (pthread_t)TlsGetValue(_pthread_tls);
412  t->ret_arg = NULL;
413  /* Main thread? */
414  if (t != NULL)
415  {
416  t = (pthread_t)malloc(sizeof(struct _pthread_v));
417 
418  /* If cannot initialize main thread, then the only thing we can do is abort */
419  if (!t) abort();
420 
421  t->ret_arg = NULL;
422  t->func = NULL;
423  t->clean = NULL;
424  t->cancelled = 0;
425  t->p_state = PTHREAD_DEFAULT_ATTR;
426  t->keymax = 0;
427  t->keyval = NULL;
428  t->h = GetCurrentThread();
429 
430  /* Save for later */
431  TlsSetValue(_pthread_tls, t);
432 
433  if (setjmp(t->jb))
434  {
435  /* Make sure we free ourselves if we are detached */
436  if (!t->h) free(t);
437 
438  /* Time to die */
439  _endthreadex(0);
440  }
441  }
442  return t;
443 }
444 
445 
446 
447 static int pthread_rwlock_tryrdlock(pthread_rwlock_t *l)
448 {
449  /* Get the current state of the lock */
450  void *state = *(void **) l;
451 
452  if (!state)
453  {
454  /* Unlocked to locked */
455  if (!InterlockedCompareExchangePointer((volatile PVOID *) l, (void *)0x11, NULL)) return 0;
456  return EBUSY;
457  }
458 
459  /* A single writer exists */
460  if (state == (void *) 1) return EBUSY;
461 
462  /* Multiple writers exist? */
463  if ((uintptr_t) state & 14) return EBUSY;
464 
465  if (InterlockedCompareExchangePointer((volatile PVOID *) l, (void *) ((uintptr_t)state + 16), state) == state) return 0;
466 
467  return EBUSY;
468 }
469 
470 static int pthread_rwlock_trywrlock(pthread_rwlock_t *l)
471 {
472  /* Try to grab lock if it has no users */
473  if (!InterlockedCompareExchangePointer((volatile PVOID*) l, (void *)1, NULL)) return 0;
474 
475  return EBUSY;
476 }
477 
478 static unsigned long long _pthread_time_in_ms(void)
479 {
480  struct __timeb64 tb;
481 
482  _ftime64_s(&tb);
483 
484  return tb.time * 1000 + tb.millitm;
485 }
486 
487 static unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts)
488 {
489  unsigned long long t = ts->tv_sec * 1000;
490  t += ts->tv_nsec / 1000000;
491 
492  return t;
493 }
494 
495 static unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts)
496 {
497  unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts);
498  unsigned long long t2 = _pthread_time_in_ms();
499 
500  /* Prevent underflow */
501  if (t1 < t2) return 0;
502  return t1 - t2;
503 }
504 
505 static int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts)
506 {
507  unsigned long long ct = _pthread_time_in_ms();
508  unsigned long long t = _pthread_time_in_ms_from_timespec(ts);
509 
510  pthread_testcancel();
511 
512  /* Use a busy-loop */
513  while (1)
514  {
515  /* Try to grab lock */
516  if (!pthread_rwlock_tryrdlock(l)) return 0;
517 
518  /* Get current time */
519  ct = _pthread_time_in_ms();
520 
521  /* Have we waited long enough? */
522  if (ct > t) return ETIMEDOUT;
523  }
524 }
525 
526 static int pthread_rwlock_timedwrlock(pthread_rwlock_t *l, const struct timespec *ts)
527 {
528  unsigned long long ct = _pthread_time_in_ms();
529  unsigned long long t = _pthread_time_in_ms_from_timespec(ts);
530 
531  pthread_testcancel();
532 
533  /* Use a busy-loop */
534  while (1)
535  {
536  /* Try to grab lock */
537  if (!pthread_rwlock_trywrlock(l)) return 0;
538 
539  /* Get current time */
540  ct = _pthread_time_in_ms();
541 
542  /* Have we waited long enough? */
543  if (ct > t) return ETIMEDOUT;
544  }
545 }
546 
547 static int pthread_get_concurrency(int *val)
548 {
549  *val = _pthread_concur;
550  return 0;
551 }
552 
553 static int pthread_set_concurrency(int val)
554 {
555  _pthread_concur = val;
556  return 0;
557 }
558 
559 #define pthread_getschedparam(T, P, S) ENOTSUP
560 #define pthread_setschedparam(T, P, S) ENOTSUP
561 #define pthread_getcpuclockid(T, C) ENOTSUP
562 
563 static int pthread_exit(void *res)
564 {
565  pthread_t t = pthread_self();
566 
567  t->ret_arg = res;
568 
569  _pthread_cleanup_dest(t);
570 
571  longjmp(t->jb, 1);
572 }
573 
574 
575 static void _pthread_invoke_cancel(void)
576 {
577  _pthread_cleanup *pcup;
578 
579  _InterlockedDecrement(&_pthread_cancelling);
580 
581  /* Call cancel queue */
582  for (pcup = pthread_self()->clean; pcup; pcup = pcup->next)
583  {
584  pcup->func(pcup->arg);
585  }
586  void *p = NULL;
587  pthread_exit(p);
588 }
589 
590 static void pthread_testcancel(void)
591 {
592  if (_pthread_cancelling)
593  {
594  pthread_t t = pthread_self();
595 
596  if (t->cancelled && (t->p_state & PTHREAD_CANCEL_ENABLE))
597  {
598  _pthread_invoke_cancel();
599  }
600  }
601 }
602 
603 
604 static int pthread_cancel(pthread_t t)
605 {
606  if (t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS)
607  {
608  /* Dangerous asynchronous cancelling */
609  CONTEXT ctxt;
610 
611  /* Already done? */
612  if (t->cancelled) return ESRCH;
613 
614  ctxt.ContextFlags = CONTEXT_CONTROL;
615 
616  SuspendThread(t->h);
617  GetThreadContext(t->h, &ctxt);
618 #ifdef _M_X64
619  ctxt.Rip = (uintptr_t) _pthread_invoke_cancel;
620 #else
621  ctxt.Eip = (uintptr_t) _pthread_invoke_cancel;
622 #endif
623  SetThreadContext(t->h, &ctxt);
624 
625  /* Also try deferred Cancelling */
626  t->cancelled = 1;
627 
628  /* Notify everyone to look */
629  _InterlockedIncrement(&_pthread_cancelling);
630 
631  ResumeThread(t->h);
632  }
633  else
634  {
635  /* Safe deferred Cancelling */
636  t->cancelled = 1;
637 
638  /* Notify everyone to look */
639  _InterlockedIncrement(&_pthread_cancelling);
640  }
641 
642  return 0;
643 }
644 
645 static unsigned _pthread_get_state(pthread_attr_t *attr, unsigned flag)
646 {
647  return attr->p_state & flag;
648 }
649 
650 static int _pthread_set_state(pthread_attr_t *attr, unsigned flag, unsigned val)
651 {
652  if (~flag & val) return EINVAL;
653  attr->p_state &= ~flag;
654  attr->p_state |= val;
655 
656  return 0;
657 }
658 
659 static int pthread_attr_init(pthread_attr_t *attr)
660 {
661  attr->p_state = PTHREAD_DEFAULT_ATTR;
662  attr->stack = NULL;
663  attr->s_size = 0;
664  return 0;
665 }
666 
667 static int pthread_attr_destroy(pthread_attr_t *attr)
668 {
669  /* No need to do anything */
670  return 0;
671 }
672 
673 
674 static int pthread_attr_setdetachstate(pthread_attr_t *a, int flag)
675 {
676  return _pthread_set_state(a, PTHREAD_CREATE_DETACHED, flag);
677 }
678 
679 static int pthread_attr_getdetachstate(pthread_attr_t *a, int *flag)
680 {
681  *flag = _pthread_get_state(a, PTHREAD_CREATE_DETACHED);
682  return 0;
683 }
684 
685 static int pthread_attr_setinheritsched(pthread_attr_t *a, int flag)
686 {
687  return _pthread_set_state(a, PTHREAD_INHERIT_SCHED, flag);
688 }
689 
690 static int pthread_attr_getinheritsched(pthread_attr_t *a, int *flag)
691 {
692  *flag = _pthread_get_state(a, PTHREAD_INHERIT_SCHED);
693  return 0;
694 }
695 
696 static int pthread_attr_setscope(pthread_attr_t *a, int flag)
697 {
698  return _pthread_set_state(a, PTHREAD_SCOPE_SYSTEM, flag);
699 }
700 
701 static int pthread_attr_getscope(pthread_attr_t *a, int *flag)
702 {
703  *flag = _pthread_get_state(a, PTHREAD_SCOPE_SYSTEM);
704  return 0;
705 }
706 
707 static int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack)
708 {
709  *stack = attr->stack;
710  return 0;
711 }
712 
713 static int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack)
714 {
715  attr->stack = stack;
716  return 0;
717 }
718 
719 static int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *size)
720 {
721  *size = attr->s_size;
722  return 0;
723 }
724 
725 static int pthread_attr_setstacksize(pthread_attr_t *attr, size_t size)
726 {
727  attr->s_size = size;
728  return 0;
729 }
730 
731 #define pthread_attr_getguardsize(A, S) ENOTSUP
732 #define pthread_attr_setgaurdsize(A, S) ENOTSUP
733 #define pthread_attr_getschedparam(A, S) ENOTSUP
734 #define pthread_attr_setschedparam(A, S) ENOTSUP
735 #define pthread_attr_getschedpolicy(A, S) ENOTSUP
736 #define pthread_attr_setschedpolicy(A, S) ENOTSUP
737 
738 
739 static int pthread_setcancelstate(int state, int *oldstate)
740 {
741  pthread_t t = pthread_self();
742 
743  if ((state & PTHREAD_CANCEL_ENABLE) != state) return EINVAL;
744  if (oldstate) *oldstate = t->p_state & PTHREAD_CANCEL_ENABLE;
745  t->p_state &= ~PTHREAD_CANCEL_ENABLE;
746  t->p_state |= state;
747 
748  return 0;
749 }
750 
751 static int pthread_setcanceltype(int type, int *oldtype)
752 {
753  pthread_t t = pthread_self();
754 
755  if ((type & PTHREAD_CANCEL_ASYNCHRONOUS) != type) return EINVAL;
756  if (oldtype) *oldtype = t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS;
757  t->p_state &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
758  t->p_state |= type;
759 
760  return 0;
761 }
762 
763 static int pthread_create_wrapper(void *args)
764 {
765  struct _pthread_v *tv = (struct _pthread_v*)args;
766 
767  _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);
768 
769  TlsSetValue(_pthread_tls, tv);
770 
771  if (!setjmp(tv->jb))
772  {
773  /* Call function and save return value */
774  tv->ret_arg = tv->func(tv->ret_arg);
775 
776  /* Clean up destructors */
777  _pthread_cleanup_dest(tv);
778  }
779 
780  /* If we exit too early, then we can race with create */
781  while (tv->h == (HANDLE) -1)
782  {
783  YieldProcessor();
784  _ReadWriteBarrier();
785  }
786 
787  /* Make sure we free ourselves if we are detached */
788  if (!tv->h) free(tv);
789 
790  return 0;
791 }
792 
793 static int pthread_create(pthread_t *th, pthread_attr_t *attr, void *(* func)(void *), void *arg)
794 {
795  struct _pthread_v *tv = (struct _pthread_v *)malloc(sizeof(struct _pthread_v));
796  unsigned ssize = 0;
797 
798  if (!tv) return 1;
799 
800  *th = tv;
801 
802  /* Save data in pthread_t */
803  tv->ret_arg = arg;
804  tv->func = func;
805  tv->clean = NULL;
806  tv->cancelled = 0;
807  tv->p_state = PTHREAD_DEFAULT_ATTR;
808  tv->keymax = 0;
809  tv->keyval = NULL;
810  tv->h = (HANDLE) -1;
811 
812  if (attr)
813  {
814  tv->p_state = attr->p_state;
815  ssize = (unsigned int)attr->s_size;
816  }
817 
818  /* Make sure tv->h has value of -1 */
819  _ReadWriteBarrier();
820 
821  tv->h = (HANDLE) _beginthreadex(NULL, ssize, (_beginthreadex_proc_type)pthread_create_wrapper, tv, 0, NULL);
822 
823  /* Failed */
824  if (!tv->h) return 1;
825 
826  if (tv->p_state & PTHREAD_CREATE_DETACHED)
827  {
828  CloseHandle(tv->h);
829  _ReadWriteBarrier();
830  tv->h = 0;
831  }
832 
833  return 0;
834 }
835 
836 static int pthread_join(pthread_t t, void **res)
837 {
838  struct _pthread_v *tv = t;
839 
840  pthread_testcancel();
841 
842  WaitForSingleObject(tv->h, INFINITE);
843  CloseHandle(tv->h);
844 
845  /* Obtain return value */
846  if (res) *res = tv->ret_arg;
847 
848  free(tv);
849 
850  return 0;
851 }
852 
853 static int pthread_detach(pthread_t t)
854 {
855  struct _pthread_v *tv = t;
856 
857  /*
858  * This can't race with thread exit because
859  * our call would be undefined if called on a dead thread.
860  */
861 
862  CloseHandle(tv->h);
863  _ReadWriteBarrier();
864  tv->h = 0;
865 
866  return 0;
867 }
868 
869 static int pthread_mutexattr_init(pthread_mutexattr_t *a)
870 {
871  *a = 0;
872  return 0;
873 }
874 
875 static int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
876 {
877  (void) a;
878  return 0;
879 }
880 
881 static int pthread_mutexattr_gettype(pthread_mutexattr_t *a, int *type)
882 {
883  *type = *a & 3;
884 
885  return 0;
886 }
887 
888 static int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
889 {
890  if ((unsigned) type > 3) return EINVAL;
891  *a &= ~3;
892  *a |= type;
893 
894  return 0;
895 }
896 
897 static int pthread_mutexattr_getpshared(pthread_mutexattr_t *a, int *type)
898 {
899  *type = *a & 4;
900 
901  return 0;
902 }
903 
904 static int pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type)
905 {
906  if ((type & 4) != type) return EINVAL;
907 
908  *a &= ~4;
909  *a |= type;
910 
911  return 0;
912 }
913 
914 static int pthread_mutexattr_getprotocol(pthread_mutexattr_t *a, int *type)
915 {
916  *type = *a & (8 + 16);
917 
918  return 0;
919 }
920 
921 static int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type)
922 {
923  if ((type & (8 + 16)) != 8 + 16) return EINVAL;
924 
925  *a &= ~(8 + 16);
926  *a |= type;
927 
928  return 0;
929 }
930 
931 static int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *a, int * prio)
932 {
933  *prio = *a / PTHREAD_PRIO_MULT;
934  return 0;
935 }
936 
937 static int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio)
938 {
939  *a &= (PTHREAD_PRIO_MULT - 1);
940  *a += prio * PTHREAD_PRIO_MULT;
941 
942  return 0;
943 }
944 
945 static int pthread_mutex_timedlock(pthread_mutex_t *m, struct timespec *ts)
946 {
947  unsigned long long t, ct;
948 
949  struct _pthread_crit_t
950  {
951  void *debug;
952  LONG count;
953  LONG r_count;
954  HANDLE owner;
955  HANDLE sem;
956  ULONG_PTR spin;
957  };
958 
959  /* Try to lock it without waiting */
960  if (!pthread_mutex_trylock(m)) return 0;
961 
962  ct = (DWORD)_pthread_time_in_ms();
963  t = (DWORD)_pthread_time_in_ms_from_timespec(ts);
964 
965  while (1)
966  {
967  /* Have we waited long enough? */
968  if (ct > t) return ETIMEDOUT;
969 
970  /* Wait on semaphore within critical section */
971  WaitForSingleObject(((struct _pthread_crit_t *)m)->sem, (DWORD)(t - ct));
972 
973  /* Try to grab lock */
974  if (!pthread_mutex_trylock(m)) return 0;
975 
976  /* Get current time */
977  ct = _pthread_time_in_ms();
978  }
979 }
980 
981 #define _PTHREAD_BARRIER_FLAG (1<<30)
982 
983 static int pthread_barrier_destroy(pthread_barrier_t *b)
984 {
985  EnterCriticalSection(&b->m);
986 
987  while (b->total > _PTHREAD_BARRIER_FLAG)
988  {
989  /* Wait until everyone exits the barrier */
990  SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
991  }
992 
993  LeaveCriticalSection(&b->m);
994 
995  DeleteCriticalSection(&b->m);
996 
997  return 0;
998 }
999 
1000 static int pthread_barrier_init(pthread_barrier_t *b, void *attr, int count)
1001 {
1002  /* Ignore attr */
1003  (void) attr;
1004 
1005  b->count = count;
1006  b->total = 0;
1007 
1008  InitializeCriticalSection(&b->m);
1009  InitializeConditionVariable(&b->cv);
1010 
1011  return 0;
1012 }
1013 
1014 static int pthread_barrier_wait(pthread_barrier_t *b)
1015 {
1016  EnterCriticalSection(&b->m);
1017 
1018  while (b->total > _PTHREAD_BARRIER_FLAG)
1019  {
1020  /* Wait until everyone exits the barrier */
1021  SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
1022  }
1023 
1024  /* Are we the first to enter? */
1025  if (b->total == _PTHREAD_BARRIER_FLAG) b->total = 0;
1026 
1027  b->total++;
1028 
1029  if (b->total == b->count)
1030  {
1031  b->total += _PTHREAD_BARRIER_FLAG - 1;
1032  WakeAllConditionVariable(&b->cv);
1033 
1034  LeaveCriticalSection(&b->m);
1035 
1036  return 1;
1037  }
1038  else
1039  {
1040  while (b->total < _PTHREAD_BARRIER_FLAG)
1041  {
1042  /* Wait until enough threads enter the barrier */
1043  SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
1044  }
1045 
1046  b->total--;
1047 
1048  /* Get entering threads to wake up */
1049  if (b->total == _PTHREAD_BARRIER_FLAG) WakeAllConditionVariable(&b->cv);
1050 
1051  LeaveCriticalSection(&b->m);
1052 
1053  return 0;
1054  }
1055 }
1056 
1057 static int pthread_barrierattr_init(void **attr)
1058 {
1059  *attr = NULL;
1060  return 0;
1061 }
1062 
1063 static int pthread_barrierattr_destroy(void **attr)
1064 {
1065  /* Ignore attr */
1066  (void) attr;
1067 
1068  return 0;
1069 }
1070 
1071 /*
1072 static int pthread_barrierattr_setpshared(void **attr, int s)
1073 {
1074  *attr = (void *) s;
1075  return 0;
1076 }
1077 
1078 static int pthread_barrierattr_getpshared(void **attr, int *s)
1079 {
1080  *s = (int) (size_t) *attr;
1081 
1082  return 0;
1083 }
1084 */
1085 
1086 static int pthread_key_create(pthread_key_t *key, void (* dest)(void *))
1087 {
1088  unsigned i;
1089  long nmax;
1090  void (**d)(void *);
1091 
1092  if (!key) return EINVAL;
1093 
1094  pthread_rwlock_wrlock(&_pthread_key_lock);
1095 
1096  for (i = _pthread_key_sch; i < _pthread_key_max; i++)
1097  {
1098  if (!_pthread_key_dest[i])
1099  {
1100  *key = i;
1101  if (dest)
1102  {
1103  _pthread_key_dest[i] = dest;
1104  }
1105  else
1106  {
1107  _pthread_key_dest[i] = (void(*)(void *))1;
1108  }
1109  pthread_rwlock_unlock(&_pthread_key_lock);
1110 
1111  return 0;
1112  }
1113  }
1114 
1115  for (i = 0; i < _pthread_key_sch; i++)
1116  {
1117  if (!_pthread_key_dest[i])
1118  {
1119  *key = i;
1120  if (dest)
1121  {
1122  _pthread_key_dest[i] = dest;
1123  }
1124  else
1125  {
1126  _pthread_key_dest[i] = (void(*)(void *))1;
1127  }
1128  pthread_rwlock_unlock(&_pthread_key_lock);
1129 
1130  return 0;
1131  }
1132  }
1133 
1134  if (!_pthread_key_max) _pthread_key_max = 1;
1135  if (_pthread_key_max == PTHREAD_KEYS_MAX)
1136  {
1137  pthread_rwlock_unlock(&_pthread_key_lock);
1138 
1139  return ENOMEM;
1140  }
1141 
1142  nmax = _pthread_key_max * 2;
1143  if (nmax > PTHREAD_KEYS_MAX) nmax = PTHREAD_KEYS_MAX;
1144 
1145  /* No spare room anywhere */
1146  d = (void (**)(void*))realloc(_pthread_key_dest, nmax * sizeof(*d));
1147  if (!d)
1148  {
1149  pthread_rwlock_unlock(&_pthread_key_lock);
1150 
1151  return ENOMEM;
1152  }
1153 
1154  /* Clear new region */
1155  memset((void *) &d[_pthread_key_max], 0, (nmax-_pthread_key_max)*sizeof(void *));
1156 
1157  /* Use new region */
1158  _pthread_key_dest = d;
1159  _pthread_key_sch = _pthread_key_max + 1;
1160  *key = _pthread_key_max;
1161  _pthread_key_max = nmax;
1162 
1163  if (dest)
1164  {
1165  _pthread_key_dest[*key] = dest;
1166  }
1167  else
1168  {
1169  _pthread_key_dest[*key] = (void(*)(void *))1;
1170  }
1171 
1172  pthread_rwlock_unlock(&_pthread_key_lock);
1173 
1174  return 0;
1175 }
1176 
1177 static int pthread_key_delete(pthread_key_t key)
1178 {
1179  if (key > _pthread_key_max) return EINVAL;
1180  if (!_pthread_key_dest) return EINVAL;
1181 
1182  pthread_rwlock_wrlock(&_pthread_key_lock);
1183  _pthread_key_dest[key] = NULL;
1184 
1185  /* Start next search from our location */
1186  if (_pthread_key_sch > key) _pthread_key_sch = key;
1187 
1188  pthread_rwlock_unlock(&_pthread_key_lock);
1189 
1190  return 0;
1191 }
1192 
1193 static void *pthread_getspecific(pthread_key_t key)
1194 {
1195  pthread_t t = pthread_self();
1196 
1197  if (key >= t->keymax) return NULL;
1198 
1199  return t->keyval[key];
1200 
1201 }
1202 
1203 static int pthread_setspecific(pthread_key_t key, const void *value)
1204 {
1205  pthread_t t = pthread_self();
1206 
1207  if (key > t->keymax)
1208  {
1209  int keymax = (key + 1) * 2;
1210  void **kv = (void**)realloc(t->keyval, keymax * sizeof(void *));
1211 
1212  if (!kv) return ENOMEM;
1213 
1214  /* Clear new region */
1215  memset(&kv[t->keymax], 0, (keymax - t->keymax)*sizeof(void*));
1216 
1217  t->keyval = kv;
1218  t->keymax = keymax;
1219  }
1220 
1221  t->keyval[key] = (void *) value;
1222 
1223  return 0;
1224 }
1225 
1226 
1227 static int pthread_spin_init(pthread_spinlock_t *l, int pshared)
1228 {
1229  (void) pshared;
1230 
1231  *l = 0;
1232  return 0;
1233 }
1234 
1235 static int pthread_spin_destroy(pthread_spinlock_t *l)
1236 {
1237  (void) l;
1238  return 0;
1239 }
1240 
1241 /* No-fair spinlock due to lack of knowledge of thread number */
1242 static int pthread_spin_lock(pthread_spinlock_t *l)
1243 {
1244  while (_InterlockedExchange(l, EBUSY))
1245  {
1246  /* Don't lock the bus whilst waiting */
1247  while (*l)
1248  {
1249  YieldProcessor();
1250 
1251  /* Compiler barrier. Prevent caching of *l */
1252  _ReadWriteBarrier();
1253  }
1254  }
1255 
1256  return 0;
1257 }
1258 
1259 static int pthread_spin_trylock(pthread_spinlock_t *l)
1260 {
1261  return _InterlockedExchange(l, EBUSY);
1262 }
1263 
1264 static int pthread_spin_unlock(pthread_spinlock_t *l)
1265 {
1266  /* Compiler barrier. The store below acts with release symmantics */
1267  _ReadWriteBarrier();
1268 
1269  *l = 0;
1270 
1271  return 0;
1272 }
1273 
1274 static int pthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a)
1275 {
1276  (void) a;
1277 
1278  InitializeConditionVariable(c);
1279  return 0;
1280 }
1281 
1282 static int pthread_cond_signal(pthread_cond_t *c)
1283 {
1284  WakeConditionVariable(c);
1285  return 0;
1286 }
1287 
1288 static int pthread_cond_broadcast(pthread_cond_t *c)
1289 {
1290  WakeAllConditionVariable(c);
1291  return 0;
1292 }
1293 
1294 static int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)
1295 {
1296  pthread_testcancel();
1297  SleepConditionVariableCS(c, m, INFINITE);
1298  return 0;
1299 }
1300 
1301 static int pthread_cond_destroy(pthread_cond_t *c)
1302 {
1303  (void) c;
1304  return 0;
1305 }
1306 
1307 static int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, struct timespec *t)
1308 {
1309  unsigned long long tm = _pthread_rel_time_in_ms(t);
1310 
1311  pthread_testcancel();
1312 
1313  if (!SleepConditionVariableCS(c, m, (DWORD)tm)) return ETIMEDOUT;
1314 
1315  /* We can have a spurious wakeup after the timeout */
1316  if (!_pthread_rel_time_in_ms(t)) return ETIMEDOUT;
1317 
1318  return 0;
1319 }
1320 
1321 static int pthread_condattr_destroy(pthread_condattr_t *a)
1322 {
1323  (void) a;
1324  return 0;
1325 }
1326 
1327 #define pthread_condattr_getclock(A, C) ENOTSUP
1328 #define pthread_condattr_setclock(A, C) ENOTSUP
1329 
1330 static int pthread_condattr_init(pthread_condattr_t *a)
1331 {
1332  *a = 0;
1333  return 0;
1334 }
1335 
1336 static int pthread_condattr_getpshared(pthread_condattr_t *a, int *s)
1337 {
1338  *s = *a;
1339  return 0;
1340 }
1341 
1342 static int pthread_condattr_setpshared(pthread_condattr_t *a, int s)
1343 {
1344  *a = s;
1345  return 0;
1346 }
1347 
1348 static int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
1349 {
1350  (void) a;
1351  return 0;
1352 }
1353 
1354 static int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
1355 {
1356  *a = 0;
1357 }
1358 
1359 static int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s)
1360 {
1361  *s = *a;
1362  return 0;
1363 }
1364 
1365 static int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s)
1366 {
1367  *a = s;
1368  return 0;
1369 }
1370 
1371 
1372 /* No fork() in windows - so ignore this */
1373 #define pthread_atfork(F1,F2,F3) 0
1374 
1375 /* Windows has rudimentary signals support */
1376 #define pthread_kill(T, S) 0
1377 #define pthread_sigmask(H, S1, S2) 0
1378 
1379 
1380 /* Wrap cancellation points */
1381 #define accept(...) (pthread_testcancel(), accept(__VA_ARGS__))
1382 #define aio_suspend(...) (pthread_testcancel(), aio_suspend(__VA_ARGS__))
1383 #define clock_nanosleep(...) (pthread_testcancel(), clock_nanosleep(__VA_ARGS__))
1384 #define close(...) (pthread_testcancel(), close(__VA_ARGS__))
1385 #define connect(...) (pthread_testcancel(), connect(__VA_ARGS__))
1386 #define creat(...) (pthread_testcancel(), creat(__VA_ARGS__))
1387 #define fcntl(...) (pthread_testcancel(), fcntl(__VA_ARGS__))
1388 #define fdatasync(...) (pthread_testcancel(), fdatasync(__VA_ARGS__))
1389 #define fsync(...) (pthread_testcancel(), fsync(__VA_ARGS__))
1390 #define getmsg(...) (pthread_testcancel(), getmsg(__VA_ARGS__))
1391 #define getpmsg(...) (pthread_testcancel(), getpmsg(__VA_ARGS__))
1392 #define lockf(...) (pthread_testcancel(), lockf(__VA_ARGS__))
1393 #define mg_receive(...) (pthread_testcancel(), mg_receive(__VA_ARGS__))
1394 #define mg_send(...) (pthread_testcancel(), mg_send(__VA_ARGS__))
1395 #define mg_timedreceive(...) (pthread_testcancel(), mg_timedreceive(__VA_ARGS__))
1396 #define mg_timessend(...) (pthread_testcancel(), mg_timedsend(__VA_ARGS__))
1397 #define msgrcv(...) (pthread_testcancel(), msgrecv(__VA_ARGS__))
1398 #define msgsnd(...) (pthread_testcancel(), msgsnd(__VA_ARGS__))
1399 #define msync(...) (pthread_testcancel(), msync(__VA_ARGS__))
1400 #define nanosleep(...) (pthread_testcancel(), nanosleep(__VA_ARGS__))
1401 #define open(...) (pthread_testcancel(), open(__VA_ARGS__))
1402 #define pause(...) (pthread_testcancel(), pause(__VA_ARGS__))
1403 #define poll(...) (pthread_testcancel(), poll(__VA_ARGS__))
1404 #define pread(...) (pthread_testcancel(), pread(__VA_ARGS__))
1405 #define pselect(...) (pthread_testcancel(), pselect(__VA_ARGS__))
1406 #define putmsg(...) (pthread_testcancel(), putmsg(__VA_ARGS__))
1407 #define putpmsg(...) (pthread_testcancel(), putpmsg(__VA_ARGS__))
1408 #define pwrite(...) (pthread_testcancel(), pwrite(__VA_ARGS__))
1409 #define read(...) (pthread_testcancel(), read(__VA_ARGS__))
1410 #define readv(...) (pthread_testcancel(), readv(__VA_ARGS__))
1411 #define recv(...) (pthread_testcancel(), recv(__VA_ARGS__))
1412 #define recvfrom(...) (pthread_testcancel(), recvfrom(__VA_ARGS__))
1413 #define recvmsg(...) (pthread_testcancel(), recvmsg(__VA_ARGS__))
1414 #define select(...) (pthread_testcancel(), select(__VA_ARGS__))
1415 #define sem_timedwait(...) (pthread_testcancel(), sem_timedwait(__VA_ARGS__))
1416 #define sem_wait(...) (pthread_testcancel(), sem_wait(__VA_ARGS__))
1417 #define send(...) (pthread_testcancel(), send(__VA_ARGS__))
1418 #define sendmsg(...) (pthread_testcancel(), sendmsg(__VA_ARGS__))
1419 #define sendto(...) (pthread_testcancel(), sendto(__VA_ARGS__))
1420 #define sigpause(...) (pthread_testcancel(), sigpause(__VA_ARGS__))
1421 #define sigsuspend(...) (pthread_testcancel(), sigsuspend(__VA_ARGS__))
1422 #define sigwait(...) (pthread_testcancel(), sigwait(__VA_ARGS__))
1423 #define sigwaitinfo(...) (pthread_testcancel(), sigwaitinfo(__VA_ARGS__))
1424 #define sleep(...) (pthread_testcancel(), sleep(__VA_ARGS__))
1425 #define system(...) (pthread_testcancel(), system(__VA_ARGS__))
1426 
1427 
1428 #define access(...) (pthread_testcancel(), access(__VA_ARGS__))
1429 #define asctime(...) (pthread_testcancel(), asctime(__VA_ARGS__))
1430 #define asctime_r(...) (pthread_testcancel(), asctime_r(__VA_ARGS__))
1431 #define catclose(...) (pthread_testcancel(), catclose(__VA_ARGS__))
1432 #define catgets(...) (pthread_testcancel(), catgets(__VA_ARGS__))
1433 #define catopen(...) (pthread_testcancel(), catopen(__VA_ARGS__))
1434 #define closedir(...) (pthread_testcancel(), closedir(__VA_ARGS__))
1435 #define closelog(...) (pthread_testcancel(), closelog(__VA_ARGS__))
1436 #define ctermid(...) (pthread_testcancel(), ctermid(__VA_ARGS__))
1437 #define ctime(...) (pthread_testcancel(), ctime(__VA_ARGS__))
1438 #define ctime_r(...) (pthread_testcancel(), ctime_r(__VA_ARGS__))
1439 #define dbm_close(...) (pthread_testcancel(), dbm_close(__VA_ARGS__))
1440 #define dbm_delete(...) (pthread_testcancel(), dbm_delete(__VA_ARGS__))
1441 #define dbm_fetch(...) (pthread_testcancel(), dbm_fetch(__VA_ARGS__))
1442 #define dbm_nextkey(...) (pthread_testcancel(), dbm_nextkey(__VA_ARGS__))
1443 #define dbm_open(...) (pthread_testcancel(), dbm_open(__VA_ARGS__))
1444 #define dbm_store(...) (pthread_testcancel(), dbm_store(__VA_ARGS__))
1445 #define dlclose(...) (pthread_testcancel(), dlclose(__VA_ARGS__))
1446 #define dlopen(...) (pthread_testcancel(), dlopen(__VA_ARGS__))
1447 #define endgrent(...) (pthread_testcancel(), endgrent(__VA_ARGS__))
1448 #define endhostent(...) (pthread_testcancel(), endhostent(__VA_ARGS__))
1449 #define endnetent(...) (pthread_testcancel(), endnetent(__VA_ARGS__))
1450 #define endprotoent(...) (pthread_testcancel(), endprotoend(__VA_ARGS__))
1451 #define endpwent(...) (pthread_testcancel(), endpwent(__VA_ARGS__))
1452 #define endservent(...) (pthread_testcancel(), endservent(__VA_ARGS__))
1453 #define endutxent(...) (pthread_testcancel(), endutxent(__VA_ARGS__))
1454 #define fclose(...) (pthread_testcancel(), fclose(__VA_ARGS__))
1455 #define fflush(...) (pthread_testcancel(), fflush(__VA_ARGS__))
1456 #define fgetc(...) (pthread_testcancel(), fgetc(__VA_ARGS__))
1457 #define fgetpos(...) (pthread_testcancel(), fgetpos(__VA_ARGS__))
1458 #define fgets(...) (pthread_testcancel(), fgets(__VA_ARGS__))
1459 #define fgetwc(...) (pthread_testcancel(), fgetwc(__VA_ARGS__))
1460 #define fgetws(...) (pthread_testcancel(), fgetws(__VA_ARGS__))
1461 #define fmtmsg(...) (pthread_testcancel(), fmtmsg(__VA_ARGS__))
1462 #define fopen(...) (pthread_testcancel(), fopen(__VA_ARGS__))
1463 #define fpathconf(...) (pthread_testcancel(), fpathconf(__VA_ARGS__))
1464 #define fprintf(...) (pthread_testcancel(), fprintf(__VA_ARGS__))
1465 #define fputc(...) (pthread_testcancel(), fputc(__VA_ARGS__))
1466 #define fputs(...) (pthread_testcancel(), fputs(__VA_ARGS__))
1467 #define fputwc(...) (pthread_testcancel(), fputwc(__VA_ARGS__))
1468 #define fputws(...) (pthread_testcancel(), fputws(__VA_ARGS__))
1469 #define fread(...) (pthread_testcancel(), fread(__VA_ARGS__))
1470 #define freopen(...) (pthread_testcancel(), freopen(__VA_ARGS__))
1471 #define fscanf(...) (pthread_testcancel(), fscanf(__VA_ARGS__))
1472 #define fseek(...) (pthread_testcancel(), fseek(__VA_ARGS__))
1473 #define fseeko(...) (pthread_testcancel(), fseeko(__VA_ARGS__))
1474 #define fsetpos(...) (pthread_testcancel(), fsetpos(__VA_ARGS__))
1475 #define fstat(...) (pthread_testcancel(), fstat(__VA_ARGS__))
1476 #define ftell(...) (pthread_testcancel(), ftell(__VA_ARGS__))
1477 #define ftello(...) (pthread_testcancel(), ftello(__VA_ARGS__))
1478 #define ftw(...) (pthread_testcancel(), ftw(__VA_ARGS__))
1479 #define fwprintf(...) (pthread_testcancel(), fwprintf(__VA_ARGS__))
1480 #define fwrite(...) (pthread_testcancel(), fwrite(__VA_ARGS__))
1481 #define fwscanf(...) (pthread_testcancel(), fwscanf(__VA_ARGS__))
1482 #define getaddrinfo(...) (pthread_testcancel(), getaddrinfo(__VA_ARGS__))
1483 #define getc(...) (pthread_testcancel(), getc(__VA_ARGS__))
1484 #define getc_unlocked(...) (pthread_testcancel(), getc_unlocked(__VA_ARGS__))
1485 #define getchar(...) (pthread_testcancel(), getchar(__VA_ARGS__))
1486 #define getchar_unlocked(...) (pthread_testcancel(), getchar_unlocked(__VA_ARGS__))
1487 #define getcwd(...) (pthread_testcancel(), getcwd(__VA_ARGS__))
1488 #define getdate(...) (pthread_testcancel(), getdate(__VA_ARGS__))
1489 #define getgrent(...) (pthread_testcancel(), getgrent(__VA_ARGS__))
1490 #define getgrgid(...) (pthread_testcancel(), getgrgid(__VA_ARGS__))
1491 #define getgrgid_r(...) (pthread_testcancel(), getgrgid_r(__VA_ARGS__))
1492 #define gergrnam(...) (pthread_testcancel(), getgrnam(__VA_ARGS__))
1493 #define getgrnam_r(...) (pthread_testcancel(), getgrnam_r(__VA_ARGS__))
1494 #define gethostbyaddr(...) (pthread_testcancel(), gethostbyaddr(__VA_ARGS__))
1495 #define gethostbyname(...) (pthread_testcancel(), gethostbyname(__VA_ARGS__))
1496 #define gethostent(...) (pthread_testcancel(), gethostent(__VA_ARGS__))
1497 #define gethostid(...) (pthread_testcancel(), gethostid(__VA_ARGS__))
1498 #define gethostname(...) (pthread_testcancel(), gethostname(__VA_ARGS__))
1499 #define getlogin(...) (pthread_testcancel(), getlogin(__VA_ARGS__))
1500 #define getlogin_r(...) (pthread_testcancel(), getlogin_r(__VA_ARGS__))
1501 #define getnameinfo(...) (pthread_testcancel(), getnameinfo(__VA_ARGS__))
1502 #define getnetbyaddr(...) (pthread_testcancel(), getnetbyaddr(__VA_ARGS__))
1503 #define getnetbyname(...) (pthread_testcancel(), getnetbyname(__VA_ARGS__))
1504 #define getnetent(...) (pthread_testcancel(), getnetent(__VA_ARGS__))
1505 #define getopt(...) (pthread_testcancel(), getopt(__VA_ARGS__))
1506 #define getprotobyname(...) (pthread_testcancel(), getprotobyname(__VA_ARGS__))
1507 #define getprotobynumber(...) (pthread_testcancel(), getprotobynumber(__VA_ARGS__))
1508 #define getprotoent(...) (pthread_testcancel(), getprotoent(__VA_ARGS__))
1509 #define getpwent(...) (pthread_testcancel(), getpwent(__VA_ARGS__))
1510 #define getpwnam(...) (pthread_testcancel(), getpwnam(__VA_ARGS__))
1511 #define getpwnam_r(...) (pthread_testcancel(), getpwnam_r(__VA_ARGS__))
1512 #define getpwuid(...) (pthread_testcancel(), getpwuid(__VA_ARGS__))
1513 #define getpwuid_r(...) (pthread_testcancel(), getpwuid_r(__VA_ARGS__))
1514 #define gets(...) (pthread_testcancel(), gets(__VA_ARGS__))
1515 #define getservbyname(...) (pthread_testcancel(), getservbyname(__VA_ARGS__))
1516 #define getservbyport(...) (pthread_testcancel(), getservbyport(__VA_ARGS__))
1517 #define getservent(...) (pthread_testcancel(), getservent(__VA_ARGS__))
1518 #define getutxent(...) (pthread_testcancel(), getutxent(__VA_ARGS__))
1519 #define getutxid(...) (pthread_testcancel(), getutxid(__VA_ARGS__))
1520 #define getutxline(...) (pthread_testcancel(), getutxline(__VA_ARGS__))
1521 #undef getwc
1522 #define getwc(...) (pthread_testcancel(), getwc(__VA_ARGS__))
1523 #undef getwchar
1524 #define getwchar(...) (pthread_testcancel(), getwchar(__VA_ARGS__))
1525 #define getwd(...) (pthread_testcancel(), getwd(__VA_ARGS__))
1526 #define glob(...) (pthread_testcancel(), glob(__VA_ARGS__))
1527 #define iconv_close(...) (pthread_testcancel(), iconv_close(__VA_ARGS__))
1528 #define iconv_open(...) (pthread_testcancel(), iconv_open(__VA_ARGS__))
1529 #define ioctl(...) (pthread_testcancel(), ioctl(__VA_ARGS__))
1530 #define link(...) (pthread_testcancel(), link(__VA_ARGS__))
1531 #define localtime(...) (pthread_testcancel(), localtime(__VA_ARGS__))
1532 #define localtime_r(...) (pthread_testcancel(), localtime_r(__VA_ARGS__))
1533 #define lseek(...) (pthread_testcancel(), lseek(__VA_ARGS__))
1534 #define lstat(...) (pthread_testcancel(), lstat(__VA_ARGS__))
1535 #define mkstemp(...) (pthread_testcancel(), mkstemp(__VA_ARGS__))
1536 #define nftw(...) (pthread_testcancel(), nftw(__VA_ARGS__))
1537 #define opendir(...) (pthread_testcancel(), opendir(__VA_ARGS__))
1538 #define openlog(...) (pthread_testcancel(), openlog(__VA_ARGS__))
1539 #define pathconf(...) (pthread_testcancel(), pathconf(__VA_ARGS__))
1540 #define pclose(...) (pthread_testcancel(), pclose(__VA_ARGS__))
1541 #define perror(...) (pthread_testcancel(), perror(__VA_ARGS__))
1542 #define popen(...) (pthread_testcancel(), popen(__VA_ARGS__))
1543 #define posix_fadvise(...) (pthread_testcancel(), posix_fadvise(__VA_ARGS__))
1544 #define posix_fallocate(...) (pthread_testcancel(), posix_fallocate(__VA_ARGS__))
1545 #define posix_madvise(...) (pthread_testcancel(), posix_madvise(__VA_ARGS__))
1546 #define posix_openpt(...) (pthread_testcancel(), posix_openpt(__VA_ARGS__))
1547 #define posix_spawn(...) (pthread_testcancel(), posix_spawn(__VA_ARGS__))
1548 #define posix_spawnp(...) (pthread_testcancel(), posix_spawnp(__VA_ARGS__))
1549 #define posix_trace_clear(...) (pthread_testcancel(), posix_trace_clear(__VA_ARGS__))
1550 #define posix_trace_close(...) (pthread_testcancel(), posix_trace_close(__VA_ARGS__))
1551 #define posix_trace_create(...) (pthread_testcancel(), posix_trace_create(__VA_ARGS__))
1552 #define posix_trace_create_withlog(...) (pthread_testcancel(), posix_trace_create_withlog(__VA_ARGS__))
1553 #define posix_trace_eventtypelist_getne(...) (pthread_testcancel(), posix_trace_eventtypelist_getne(__VA_ARGS__))
1554 #define posix_trace_eventtypelist_rewin(...) (pthread_testcancel(), posix_trace_eventtypelist_rewin(__VA_ARGS__))
1555 #define posix_trace_flush(...) (pthread_testcancel(), posix_trace_flush(__VA_ARGS__))
1556 #define posix_trace_get_attr(...) (pthread_testcancel(), posix_trace_get_attr(__VA_ARGS__))
1557 #define posix_trace_get_filter(...) (pthread_testcancel(), posix_trace_get_filter(__VA_ARGS__))
1558 #define posix_trace_get_status(...) (pthread_testcancel(), posix_trace_get_status(__VA_ARGS__))
1559 #define posix_trace_getnext_event(...) (pthread_testcancel(), posix_trace_getnext_event(__VA_ARGS__))
1560 #define posix_trace_open(...) (pthread_testcancel(), posix_trace_open(__VA_ARGS__))
1561 #define posix_trace_rewind(...) (pthread_testcancel(), posix_trace_rewind(__VA_ARGS__))
1562 #define posix_trace_setfilter(...) (pthread_testcancel(), posix_trace_setfilter(__VA_ARGS__))
1563 #define posix_trace_shutdown(...) (pthread_testcancel(), posix_trace_shutdown(__VA_ARGS__))
1564 #define posix_trace_timedgetnext_event(...) (pthread_testcancel(), posix_trace_timedgetnext_event(__VA_ARGS__))
1565 #define posix_typed_mem_open(...) (pthread_testcancel(), posix_typed_mem_open(__VA_ARGS__))
1566 #define printf(...) (pthread_testcancel(), printf(__VA_ARGS__))
1567 #define putc(...) (pthread_testcancel(), putc(__VA_ARGS__))
1568 #define putc_unlocked(...) (pthread_testcancel(), putc_unlocked(__VA_ARGS__))
1569 #define putchar(...) (pthread_testcancel(), putchar(__VA_ARGS__))
1570 #define putchar_unlocked(...) (pthread_testcancel(), putchar_unlocked(__VA_ARGS__))
1571 #define puts(...) (pthread_testcancel(), puts(__VA_ARGS__))
1572 #define pututxline(...) (pthread_testcancel(), pututxline(__VA_ARGS__))
1573 #undef putwc
1574 #define putwc(...) (pthread_testcancel(), putwc(__VA_ARGS__))
1575 #undef putwchar
1576 #define putwchar(...) (pthread_testcancel(), putwchar(__VA_ARGS__))
1577 #define readdir(...) (pthread_testcancel(), readdir(__VA_ARSG__))
1578 #define readdir_r(...) (pthread_testcancel(), readdir_r(__VA_ARGS__))
1579 #define remove(...) (pthread_testcancel(), remove(__VA_ARGS__))
1580 #define rename(...) (pthread_testcancel(), rename(__VA_ARGS__))
1581 #define rewind(...) (pthread_testcancel(), rewind(__VA_ARGS__))
1582 #define rewinddir(...) (pthread_testcancel(), rewinddir(__VA_ARGS__))
1583 #define scanf(...) (pthread_testcancel(), scanf(__VA_ARGS__))
1584 #define seekdir(...) (pthread_testcancel(), seekdir(__VA_ARGS__))
1585 #define semop(...) (pthread_testcancel(), semop(__VA_ARGS__))
1586 #define setgrent(...) (pthread_testcancel(), setgrent(__VA_ARGS__))
1587 #define sethostent(...) (pthread_testcancel(), sethostemt(__VA_ARGS__))
1588 #define setnetent(...) (pthread_testcancel(), setnetent(__VA_ARGS__))
1589 #define setprotoent(...) (pthread_testcancel(), setprotoent(__VA_ARGS__))
1590 #define setpwent(...) (pthread_testcancel(), setpwent(__VA_ARGS__))
1591 #define setservent(...) (pthread_testcancel(), setservent(__VA_ARGS__))
1592 #define setutxent(...) (pthread_testcancel(), setutxent(__VA_ARGS__))
1593 #define stat(...) (pthread_testcancel(), stat(__VA_ARGS__))
1594 #define strerror(...) (pthread_testcancel(), strerror(__VA_ARGS__))
1595 #define strerror_r(...) (pthread_testcancel(), strerror_r(__VA_ARGS__))
1596 #define strftime(...) (pthread_testcancel(), strftime(__VA_ARGS__))
1597 #define symlink(...) (pthread_testcancel(), symlink(__VA_ARGS__))
1598 #define sync(...) (pthread_testcancel(), sync(__VA_ARGS__))
1599 #define syslog(...) (pthread_testcancel(), syslog(__VA_ARGS__))
1600 #define tmpfile(...) (pthread_testcancel(), tmpfile(__VA_ARGS__))
1601 #define tmpnam(...) (pthread_testcancel(), tmpnam(__VA_ARGS__))
1602 #define ttyname(...) (pthread_testcancel(), ttyname(__VA_ARGS__))
1603 #define ttyname_r(...) (pthread_testcancel(), ttyname_r(__VA_ARGS__))
1604 #define tzset(...) (pthread_testcancel(), tzset(__VA_ARGS__))
1605 #define ungetc(...) (pthread_testcancel(), ungetc(__VA_ARGS__))
1606 #define ungetwc(...) (pthread_testcancel(), ungetwc(__VA_ARGS__))
1607 #define unlink(...) (pthread_testcancel(), unlink(__VA_ARGS__))
1608 #define vfprintf(...) (pthread_testcancel(), vfprintf(__VA_ARGS__))
1609 #define vfwprintf(...) (pthread_testcancel(), vfwprintf(__VA_ARGS__))
1610 #define vprintf(...) (pthread_testcancel(), vprintf(__VA_ARGS__))
1611 #define vwprintf(...) (pthread_testcancel(), vwprintf(__VA_ARGS__))
1612 #define wcsftime(...) (pthread_testcancel(), wcsftime(__VA_ARGS__))
1613 #define wordexp(...) (pthread_testcancel(), wordexp(__VA_ARGS__))
1614 #define wprintf(...) (pthread_testcancel(), wprintf(__VA_ARGS__))
1615 #define wscanf(...) (pthread_testcancel(), wscanf(__VA_ARGS__))
1616 
1617 #endif /* WIN_PTHREADS */
Definition: winpthreads.h:116
Definition: winpthreads.h:123
Definition: winpthreads.h:149
Definition: winpthreads.h:140