OSDN Git Service

* exceptions.cc (set_signal_mask): Remove useless debugging output.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / thread.cc
1 /* thread.cc: Locking and threading module functions
2
3    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4    2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
5
6 This file is part of Cygwin.
7
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
10 details. */
11
12 /* Implementation overview and caveats:
13
14    Win32 puts some contraints on what can and cannot be implemented.  Where
15    possible we work around those contrainsts.  Where we cannot work around
16    the constraints we either pretend to be conformant, or return an error
17    code.
18
19    Some caveats: PROCESS_SHARED objects, while they pretend to be process
20    shared, may not actually work.  Some test cases are needed to determine
21    win32's behaviour.  My suspicion is that the win32 handle needs to be
22    opened with different flags for proper operation.
23
24    R.Collins, April 2001.  */
25
26 #include "winsup.h"
27 #include "miscfuncs.h"
28 #include "path.h"
29 #include <stdlib.h>
30 #include "pinfo.h"
31 #include "sigproc.h"
32 #include "perprocess.h"
33 #include "cygtls.h"
34 #include "fhandler.h"
35 #include "dtable.h"
36 #include "cygheap.h"
37 #include "ntdll.h"
38 #include "miscfuncs.h"
39
40 extern "C" void __fp_lock_all ();
41 extern "C" void __fp_unlock_all ();
42 extern "C" int valid_sched_parameters(const struct sched_param *);
43 extern "C" int sched_set_thread_priority(HANDLE thread, int priority);
44 static inline verifyable_object_state
45   verifyable_object_isvalid (void const * objectptr, thread_magic_t magic,
46                              void *static_ptr1 = NULL,
47                              void *static_ptr2 = NULL,
48                              void *static_ptr3 = NULL);
49
50 extern int threadsafe;
51
52 const pthread_t pthread_mutex::_new_mutex = (pthread_t) 1;
53 const pthread_t pthread_mutex::_unlocked_mutex = (pthread_t) 2;
54 const pthread_t pthread_mutex::_destroyed_mutex = (pthread_t) 3;
55
56 inline bool
57 pthread_mutex::no_owner()
58 {
59     int res;
60     if (!owner)
61       {
62         debug_printf ("NULL owner value");
63         res = 1;
64       }
65     else if (owner == _destroyed_mutex)
66       {
67         paranoid_printf ("attempt to use destroyed mutex");
68         res = 1;
69       }
70     else if (owner == _new_mutex || owner == _unlocked_mutex)
71       res = 1;
72     else
73       res = 0;
74     return res;
75 }
76
77 #undef __getreent
78 extern "C" struct _reent *
79 __getreent ()
80 {
81   return &_my_tls.local_clib;
82 }
83
84 extern "C" void
85 __cygwin_lock_init (_LOCK_T *lock)
86 {
87   *lock = _LOCK_T_INITIALIZER;
88 }
89
90 extern "C" void
91 __cygwin_lock_init_recursive (_LOCK_T *lock)
92 {
93   *lock = _LOCK_T_RECURSIVE_INITIALIZER;
94 }
95
96 extern "C" void
97 __cygwin_lock_fini (_LOCK_T *lock)
98 {
99   pthread_mutex_destroy ((pthread_mutex_t*) lock);
100 }
101
102 extern "C" void
103 __cygwin_lock_lock (_LOCK_T *lock)
104 {
105   paranoid_printf ("threadcount %d.  locking", MT_INTERFACE->threadcount);
106   pthread_mutex_lock ((pthread_mutex_t*) lock);
107 }
108
109 extern "C" int
110 __cygwin_lock_trylock (_LOCK_T *lock)
111 {
112   return pthread_mutex_trylock ((pthread_mutex_t*) lock);
113 }
114
115
116 extern "C" void
117 __cygwin_lock_unlock (_LOCK_T *lock)
118 {
119   pthread_mutex_unlock ((pthread_mutex_t*) lock);
120   paranoid_printf ("threadcount %d.  unlocked", MT_INTERFACE->threadcount);
121 }
122
123 static inline verifyable_object_state
124 verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
125                            void *static_ptr2, void *static_ptr3)
126 {
127   myfault efault;
128   if (efault.faulted (objectptr))
129     return INVALID_OBJECT;
130
131   verifyable_object **object = (verifyable_object **) objectptr;
132
133   if ((static_ptr1 && *object == static_ptr1) ||
134       (static_ptr2 && *object == static_ptr2) ||
135       (static_ptr3 && *object == static_ptr3))
136     return VALID_STATIC_OBJECT;
137   if ((*object)->magic != magic)
138     return INVALID_OBJECT;
139   return VALID_OBJECT;
140 }
141
142 /* static members */
143 inline bool
144 pthread_attr::is_good_object (pthread_attr_t const *attr)
145 {
146   if (verifyable_object_isvalid (attr, PTHREAD_ATTR_MAGIC) != VALID_OBJECT)
147     return false;
148   return true;
149 }
150
151 inline bool
152 pthread_condattr::is_good_object (pthread_condattr_t const *attr)
153 {
154   if (verifyable_object_isvalid (attr, PTHREAD_CONDATTR_MAGIC) != VALID_OBJECT)
155     return false;
156   return true;
157 }
158
159 inline bool
160 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t const *attr)
161 {
162   if (verifyable_object_isvalid (attr, PTHREAD_RWLOCKATTR_MAGIC) != VALID_OBJECT)
163     return false;
164   return true;
165 }
166
167 inline bool
168 pthread_key::is_good_object (pthread_key_t const *key)
169 {
170   if (verifyable_object_isvalid (key, PTHREAD_KEY_MAGIC) != VALID_OBJECT)
171     return false;
172   return true;
173 }
174
175 inline bool
176 pthread_spinlock::is_good_object (pthread_spinlock_t const *mutex)
177 {
178   if (verifyable_object_isvalid (mutex, PTHREAD_SPINLOCK_MAGIC) != VALID_OBJECT)
179     return false;
180   return true;
181 }
182
183 inline bool
184 pthread_mutex::is_good_object (pthread_mutex_t const *mutex)
185 {
186   if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
187     return false;
188   return true;
189 }
190
191 inline bool
192 pthread_mutex::is_initializer (pthread_mutex_t const *mutex)
193 {
194   if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
195                                  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
196                                  PTHREAD_NORMAL_MUTEX_INITIALIZER_NP,
197                                  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) != VALID_STATIC_OBJECT)
198     return false;
199   return true;
200 }
201
202 inline bool
203 pthread_mutex::is_initializer_or_object (pthread_mutex_t const *mutex)
204 {
205   if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC,
206                                  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
207                                  PTHREAD_NORMAL_MUTEX_INITIALIZER_NP,
208                                  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) == INVALID_OBJECT)
209     return false;
210   return true;
211 }
212
213 /* FIXME: Accommodate PTHREAD_MUTEX_ERRORCHECK */
214 inline bool
215 pthread_mutex::can_be_unlocked ()
216 {
217   pthread_t self = pthread::self ();
218   /* Check if the mutex is owned by the current thread and can be unlocked.
219    * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
220   bool res = type == PTHREAD_MUTEX_NORMAL || no_owner ()
221              || (recursion_counter == 1 && pthread::equal (owner, self));
222   pthread_printf ("recursion_counter %d res %d", recursion_counter, res);
223   return res;
224 }
225
226 inline bool
227 pthread_mutexattr::is_good_object (pthread_mutexattr_t const * attr)
228 {
229   if (verifyable_object_isvalid (attr, PTHREAD_MUTEXATTR_MAGIC) != VALID_OBJECT)
230     return false;
231   return true;
232 }
233
234 inline bool __attribute__ ((used))
235 pthread::is_good_object (pthread_t const *thread)
236 {
237   if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
238     return false;
239   return true;
240 }
241
242 /* Thread synchronisation */
243 inline bool
244 pthread_cond::is_good_object (pthread_cond_t const *cond)
245 {
246   if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC) != VALID_OBJECT)
247     return false;
248   return true;
249 }
250
251 inline bool
252 pthread_cond::is_initializer (pthread_cond_t const *cond)
253 {
254   if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) != VALID_STATIC_OBJECT)
255     return false;
256   return true;
257 }
258
259 inline bool
260 pthread_cond::is_initializer_or_object (pthread_cond_t const *cond)
261 {
262   if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) == INVALID_OBJECT)
263     return false;
264   return true;
265 }
266
267 /* RW locks */
268 inline bool
269 pthread_rwlock::is_good_object (pthread_rwlock_t const *rwlock)
270 {
271   if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC) != VALID_OBJECT)
272     return false;
273   return true;
274 }
275
276 inline bool
277 pthread_rwlock::is_initializer (pthread_rwlock_t const *rwlock)
278 {
279   if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) != VALID_STATIC_OBJECT)
280     return false;
281   return true;
282 }
283
284 inline bool
285 pthread_rwlock::is_initializer_or_object (pthread_rwlock_t const *rwlock)
286 {
287   if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) == INVALID_OBJECT)
288     return false;
289   return true;
290 }
291
292 inline bool
293 semaphore::is_good_object (sem_t const * sem)
294 {
295   if (verifyable_object_isvalid (sem, SEM_MAGIC) != VALID_OBJECT)
296     return false;
297   return true;
298 }
299
300 void
301 MTinterface::Init ()
302 {
303   pthread_mutex::init_mutex ();
304   pthread_cond::init_mutex ();
305   pthread_rwlock::init_mutex ();
306 }
307
308 void
309 MTinterface::fixup_before_fork ()
310 {
311   pthread_key::fixup_before_fork ();
312 }
313
314 /* This function is called from a single threaded process */
315 void
316 MTinterface::fixup_after_fork ()
317 {
318   pthread_key::fixup_after_fork ();
319
320   threadcount = 0;
321   pthread::init_mainthread ();
322
323   pthread::fixup_after_fork ();
324   pthread_mutex::fixup_after_fork ();
325   pthread_cond::fixup_after_fork ();
326   pthread_rwlock::fixup_after_fork ();
327   semaphore::fixup_after_fork ();
328 }
329
330 /* pthread calls */
331
332 /* static methods */
333 void
334 pthread::init_mainthread ()
335 {
336   pthread *thread = _my_tls.tid;
337   if (!thread)
338     {
339       thread = new pthread ();
340       if (!thread)
341         api_fatal ("failed to create mainthread object");
342     }
343
344   set_tls_self_pointer (thread);
345   thread->thread_id = GetCurrentThreadId ();
346   if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
347                         GetCurrentProcess (), &thread->win32_obj_id,
348                         0, FALSE, DUPLICATE_SAME_ACCESS))
349     api_fatal ("failed to create mainthread handle");
350   if (!thread->create_cancel_event ())
351     api_fatal ("couldn't create cancel event for main thread");
352   VerifyHandle (thread->win32_obj_id);
353   thread->postcreate ();
354 }
355
356 pthread *
357 pthread::self ()
358 {
359   pthread *thread = _my_tls.tid;
360   if (!thread)
361     {
362       thread = pthread_null::get_null_pthread ();
363       set_tls_self_pointer (thread);
364     }
365   return thread;
366 }
367
368 void
369 pthread::set_tls_self_pointer (pthread *thread)
370 {
371   thread->cygtls = &_my_tls;
372   _my_tls.tid = thread;
373 }
374
375 List<pthread> pthread::threads;
376
377 /* member methods */
378 pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
379                     valid (false), suspended (false), canceled (false),
380                     cancelstate (0), canceltype (0), cancel_event (0),
381                     joiner (NULL), next (NULL), cleanup_stack (NULL)
382 {
383   if (this != pthread_null::get_null_pthread ())
384     threads.insert (this);
385   sigprocmask (SIG_SETMASK, NULL, &parent_sigmask);
386 }
387
388 pthread::~pthread ()
389 {
390   if (win32_obj_id)
391     CloseHandle (win32_obj_id);
392   if (cancel_event)
393     CloseHandle (cancel_event);
394
395   if (this != pthread_null::get_null_pthread ())
396     threads.remove (this);
397 }
398
399 bool
400 pthread::create_cancel_event ()
401 {
402   cancel_event = ::CreateEvent (&sec_none_nih, true, false, NULL);
403   if (!cancel_event)
404     {
405       system_printf ("couldn't create cancel event, %E");
406       /* we need the event for correct behaviour */
407       return false;
408     }
409   return true;
410 }
411
412 void
413 pthread::precreate (pthread_attr *newattr)
414 {
415   pthread_mutex *verifyable_mutex_obj = &mutex;
416
417   /* already running ? */
418   if (win32_obj_id)
419     return;
420
421   if (newattr)
422     {
423       attr.joinable = newattr->joinable;
424       attr.contentionscope = newattr->contentionscope;
425       attr.inheritsched = newattr->inheritsched;
426       attr.stackaddr = newattr->stackaddr;
427       attr.stacksize = newattr->stacksize;
428       attr.guardsize = newattr->guardsize;
429     }
430
431   if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
432     {
433       thread_printf ("New thread object access mutex is not valid. this %p",
434                      this);
435       magic = 0;
436       return;
437     }
438   /* Change the mutex type to NORMAL to speed up mutex operations */
439   mutex.set_type (PTHREAD_MUTEX_NORMAL);
440   if (!create_cancel_event ())
441     magic = 0;
442 }
443
444 bool
445 pthread::create (void *(*func) (void *), pthread_attr *newattr,
446                  void *threadarg)
447 {
448   bool retval;
449
450   precreate (newattr);
451   if (!magic)
452     return false;
453
454   function = func;
455   arg = threadarg;
456
457   mutex.lock ();
458   win32_obj_id = CygwinCreateThread (thread_init_wrapper, this,
459                                      attr.stackaddr, attr.stacksize,
460                                      attr.guardsize, 0, &thread_id);
461
462   if (!win32_obj_id)
463     {
464       thread_printf ("CreateThread failed: this %p, %E", this);
465       magic = 0;
466     }
467   else
468     {
469       postcreate ();
470       while (!cygtls)
471         yield ();
472     }
473   retval = magic;
474   mutex.unlock ();
475   return retval;
476 }
477
478 void
479 pthread::postcreate ()
480 {
481   valid = true;
482
483   InterlockedIncrement (&MT_INTERFACE->threadcount);
484   /* FIXME: set the priority appropriately for system contention scope */
485   if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
486     {
487       /* FIXME: set the scheduling settings for the new thread */
488       /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
489     }
490 }
491
492 void
493 pthread::exit (void *value_ptr)
494 {
495   class pthread *thread = this;
496
497   // run cleanup handlers
498   pop_all_cleanup_handlers ();
499
500   pthread_key::run_all_destructors ();
501
502   mutex.lock ();
503   // cleanup if thread is in detached state and not joined
504   if (equal (joiner, thread))
505     delete this;
506   else
507     {
508       valid = false;
509       return_ptr = value_ptr;
510       mutex.unlock ();
511     }
512
513   if (_my_tls.local_clib.__sdidinit < 0)
514     _my_tls.local_clib.__sdidinit = 0;
515   (_reclaim_reent) (_REENT);
516
517   if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
518     ::exit (0);
519   else
520     {
521       if (cygtls == _main_tls)
522         {
523           _cygtls *dummy = (_cygtls *) malloc (sizeof (_cygtls));
524           *dummy = *_main_tls;
525           _main_tls = dummy;
526           _main_tls->initialized = false;
527         }
528       ExitThread (0);
529     }
530 }
531
532 int
533 pthread::cancel ()
534 {
535   class pthread *thread = this;
536   class pthread *self = pthread::self ();
537
538   mutex.lock ();
539
540   if (!valid)
541     {
542       mutex.unlock ();
543       return 0;
544     }
545
546   if (canceltype == PTHREAD_CANCEL_DEFERRED ||
547       cancelstate == PTHREAD_CANCEL_DISABLE)
548     {
549       // cancel deferred
550       mutex.unlock ();
551       canceled = true;
552       SetEvent (cancel_event);
553       return 0;
554     }
555   else if (equal (thread, self))
556     {
557       mutex.unlock ();
558       cancel_self ();
559       return 0; // Never reached
560     }
561
562   // cancel asynchronous
563   SuspendThread (win32_obj_id);
564   if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
565     {
566       CONTEXT context;
567       context.ContextFlags = CONTEXT_CONTROL;
568       GetThreadContext (win32_obj_id, &context);
569       context.Eip = (DWORD) pthread::static_cancel_self;
570       SetThreadContext (win32_obj_id, &context);
571     }
572   mutex.unlock ();
573   ResumeThread (win32_obj_id);
574
575   return 0;
576 }
577
578 /* TODO: Insert pthread_testcancel into the required functions.
579
580    Here are the lists of required and optional functions per POSIX.1-2001
581    and POSIX.1-2008. A star (*) indicates that the Cygwin function already
582    is a cancellation point (aka "calls pthread_testcancel"), an o (o)
583    indicates that the function is not implemented in Cygwin.
584
585    Required cancellation points:
586
587     * accept ()
588     o aio_suspend ()
589     * clock_nanosleep ()
590     * close ()
591     * connect ()
592     * creat ()
593     * fcntl () F_SETLKW
594     * fdatasync ()
595     * fsync ()
596     o getmsg ()
597     o getpmsg ()
598     * lockf () F_LOCK
599     * mq_receive ()
600     * mq_send ()
601     * mq_timedreceive ()
602     * mq_timedsend ()
603       msgrcv ()
604       msgsnd ()
605     * msync ()
606     * nanosleep ()
607     * open ()
608     * openat ()
609     * pause ()
610     * poll ()
611     * pread ()
612     * pselect ()
613     * pthread_cond_timedwait ()
614     * pthread_cond_wait ()
615     * pthread_join ()
616     * pthread_testcancel ()
617     o putmsg ()
618     o putpmsg ()
619     * pwrite ()
620     * read ()
621     * readv ()
622     * recv ()
623     * recvfrom ()
624     * recvmsg ()
625     * select ()
626     * sem_timedwait ()
627     * sem_wait ()
628     * send ()
629     * sendmsg ()
630     * sendto ()
631     * sigpause ()
632     * sigsuspend ()
633     o sigtimedwait ()
634     * sigwait ()
635     * sigwaitinfo ()
636     * sleep ()
637     * system ()
638     * tcdrain ()
639     * usleep ()
640     * wait ()
641     * wait3()
642     o waitid ()
643     * waitpid ()
644     * write ()
645     * writev ()
646
647    Optional cancellation points:
648
649       access ()
650       asctime ()
651       asctime_r ()
652       catclose ()       Implemented externally: libcatgets
653       catgets ()        Implemented externally: libcatgets
654       catopen ()        Implemented externally: libcatgets
655       chmod ()
656       chown ()
657       closedir ()
658       closelog ()
659       ctermid ()
660       ctime ()
661       ctime_r ()
662       dbm_close ()      Implemented externally: libgdbm
663       dbm_delete ()     Implemented externally: libgdbm
664       dbm_fetch ()      Implemented externally: libgdbm
665       dbm_nextkey ()    Implemented externally: libgdbm
666       dbm_open ()       Implemented externally: libgdbm
667       dbm_store ()      Implemented externally: libgdbm
668       dlclose ()
669       dlopen ()
670       dprintf ()
671       endgrent ()
672       endhostent ()
673     o endnetent ()
674       endprotoent ()
675       endpwent ()
676       endservent ()
677       endutxent ()
678       faccessat ()
679       fchmod ()
680       fchmodat ()
681       fchown ()
682       fchownat ()
683     * fclose ()
684     * fcntl () (any value)
685       fflush ()
686       fgetc ()
687       fgetpos ()
688       fgets ()
689       fgetwc ()
690       fgetws ()
691     o fmtmsg ()
692       fopen ()
693       fpathconf ()
694       fprintf ()
695       fputc ()
696       fputs ()
697       fputwc ()
698       fputws ()
699       fread ()
700       freopen ()
701       fscanf ()
702       fseek ()
703       fseeko ()
704       fsetpos ()
705       fstat ()
706       fstatat ()
707       ftell ()
708       ftello ()
709       ftw ()
710       futimens ()
711       fwprintf ()
712       fwrite ()
713       fwscanf ()
714       getaddrinfo ()
715       getc ()
716       getc_unlocked ()
717       getchar ()
718       getchar_unlocked ()
719       getcwd ()
720     o getdate ()
721       getdelim ()
722       getgrent ()
723       getgrgid ()
724       getgrgid_r ()
725       getgrnam ()
726       getgrnam_r ()
727       gethostbyaddr ()
728       gethostbyname ()
729       gethostent ()
730       gethostid ()
731       gethostname ()
732       getline ()
733       getlogin ()
734       getlogin_r ()
735       getnameinfo ()
736     o getnetbyaddr ()
737     o getnetbyname ()
738     o getnetent ()
739       getopt () (if opterr is nonzero)
740       getprotobyname ()
741       getprotobynumber ()
742       getprotoent ()
743       getpwent ()
744     * getpwnam ()
745     * getpwnam_r ()
746     * getpwuid ()
747     * getpwuid_r ()
748       gets ()
749       getservbyname ()
750       getservbyport ()
751       getservent ()
752       getutxent ()
753       getutxid ()
754       getutxline ()
755       getwc ()
756       getwchar ()
757       getwd ()
758       glob ()
759       iconv_close ()    Implemented externally: libiconv
760       iconv_open ()     Implemented externally: libiconv
761       ioctl ()
762       link ()
763       linkat ()
764     o lio_listio ()
765       localtime ()
766       localtime_r ()
767     * lockf ()
768       lseek ()
769       lstat ()
770       mkdir ()
771       mkdirat ()
772       mkdtemp ()
773       mkfifo ()
774       mkfifoat ()
775       mknod ()
776       mknodat ()
777       mkstemp ()
778       mktime ()
779       nftw ()
780       opendir ()
781       openlog ()
782       pathconf ()
783       pclose ()
784       perror ()
785       popen ()
786       posix_fadvise ()
787       posix_fallocate ()
788       posix_madvise ()
789       posix_openpt ()
790     o posix_spawn ()
791     o posix_spawnp ()
792     o posix_trace_clear ()
793     o posix_trace_close ()
794     o posix_trace_create ()
795     o posix_trace_create_withlog ()
796     o posix_trace_eventtypelist_getnext_id ()
797     o posix_trace_eventtypelist_rewind ()
798     o posix_trace_flush ()
799     o posix_trace_get_attr ()
800     o posix_trace_get_filter ()
801     o posix_trace_get_status ()
802     o posix_trace_getnext_event ()
803     o posix_trace_open ()
804     o posix_trace_rewind ()
805     o posix_trace_set_filter ()
806     o posix_trace_shutdown ()
807     o posix_trace_timedgetnext_event ()
808     o posix_typed_mem_open ()
809       printf ()
810       psiginfo ()
811       psignal ()
812       pthread_rwlock_rdlock ()
813       pthread_rwlock_timedrdlock ()
814       pthread_rwlock_timedwrlock ()
815       pthread_rwlock_wrlock ()
816       putc ()
817       putc_unlocked ()
818       putchar ()
819       putchar_unlocked ()
820       puts ()
821       pututxline ()
822       putwc ()
823       putwchar ()
824       readdir ()
825       readdir_r ()
826       readlink ()
827       readlinkat ()
828       remove ()
829       rename ()
830       renameat ()
831       rewind ()
832       rewinddir ()
833       scandir ()
834       scanf ()
835       seekdir ()
836       semop ()
837       setgrent ()
838       sethostent ()
839     o setnetent ()
840       setprotoent ()
841       setpwent ()
842       setservent ()
843       setutxent ()
844       sigpause ()
845       stat ()
846       strerror ()
847       strerror_r ()
848       strftime ()
849       symlink ()
850       symlinkat ()
851       sync ()
852       syslog ()
853       tmpfile ()
854       tmpnam ()
855       ttyname ()
856       ttyname_r ()
857       tzset ()
858       ungetc ()
859       ungetwc ()
860       unlink ()
861       unlinkat ()
862       utime ()
863       utimensat ()
864       utimes ()
865       vdprintf ()
866       vfprintf ()
867       vfwprintf ()
868       vprintf ()
869       vwprintf ()
870       wcsftime ()
871       wordexp ()
872       wprintf ()
873       wscanf ()
874
875    An implementation may also mark other functions not specified in the
876    standard as cancellation points.  In particular, an implementation is
877    likely to mark any nonstandard function that may block as a
878    cancellation point. */
879
880 void
881 pthread::testcancel ()
882 {
883   if (cancelstate == PTHREAD_CANCEL_DISABLE)
884     return;
885
886   /* We check for the canceled flag first.  This allows to use the
887      pthread_testcancel function a lot without adding the overhead of
888      an OS call.  Only if the thread is marked as canceled, we wait for
889      cancel_event being really set, on the off-chance that pthread_cancel
890      gets interrupted before calling SetEvent. */
891   if (canceled)
892     {
893       WaitForSingleObject (cancel_event, INFINITE);
894       cancel_self ();
895     }
896 }
897
898 /* Return cancel event handle if it exists *and* cancel is not disabled.
899    This function is supposed to be used from other functions which are
900    cancelable and need the cancel event in a WFMO call. */
901 HANDLE
902 pthread::get_cancel_event ()
903 {
904   pthread_t thread = pthread::self ();
905
906   return (thread && thread->cancel_event
907           && thread->cancelstate != PTHREAD_CANCEL_DISABLE)
908           ? thread->cancel_event : NULL;
909 }
910
911 void
912 pthread::static_cancel_self ()
913 {
914   pthread::self ()->cancel_self ();
915 }
916
917 DWORD
918 cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
919                  const cw_cancel_action cancel_action,
920                  const enum cw_sig_wait sig_wait)
921 {
922   DWORD res;
923   DWORD num = 0;
924   HANDLE wait_objects[4];
925   pthread_t thread = pthread::self ();
926
927   /* Do not change the wait order.
928      The object must have higher priority than the cancel event,
929      because WaitForMultipleObjects will return the smallest index
930      if both objects are signaled. */
931   wait_objects[num++] = object;
932   DWORD cancel_n;
933   if (cancel_action == cw_no_cancel || !pthread::is_good_object (&thread) ||
934       thread->cancelstate == PTHREAD_CANCEL_DISABLE)
935     cancel_n = WAIT_TIMEOUT + 1;
936   else
937     {
938       cancel_n = WAIT_OBJECT_0 + num++;
939       wait_objects[cancel_n] = thread->cancel_event;
940     }
941
942   DWORD sig_n;
943   if (sig_wait == cw_sig_nosig)
944     sig_n = WAIT_TIMEOUT + 1;
945   else
946     {
947       sig_n = WAIT_OBJECT_0 + num++;
948       wait_objects[sig_n] = signal_arrived;
949     }
950
951   DWORD timeout_n;
952   if (!timeout)
953     timeout_n = WAIT_TIMEOUT + 1;
954   else
955     {
956       timeout_n = WAIT_OBJECT_0 + num++;
957       if (!_my_tls.locals.cw_timer)
958         NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
959                        NotificationTimer);
960       NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
961       wait_objects[timeout_n] = _my_tls.locals.cw_timer;
962     }
963
964   while (1)
965     {
966       res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
967       if (res == cancel_n)
968         {
969           if (cancel_action == cw_cancel_self)
970             pthread::static_cancel_self ();
971           res = WAIT_CANCELED;
972         }
973       else if (res == timeout_n)
974         res = WAIT_TIMEOUT;
975       else if (res != sig_n)
976         /* all set */;
977       else if (sig_wait == cw_sig_eintr)
978         res = WAIT_SIGNALED;
979       else
980         {
981           _my_tls.call_signal_handler ();
982           continue;
983         }
984       break;
985     }
986
987   if (timeout)
988     {
989       const size_t sizeof_tbi = sizeof (TIMER_BASIC_INFORMATION);
990       PTIMER_BASIC_INFORMATION tbi = (PTIMER_BASIC_INFORMATION) malloc (sizeof_tbi);
991
992       NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, tbi,
993                     sizeof_tbi, NULL);
994       /* if timer expired, TimeRemaining is negative and represents the
995           system uptime when signalled */
996       if (timeout->QuadPart < 0LL)
997         timeout->QuadPart = tbi->SignalState ? 0LL : tbi->TimeRemaining.QuadPart;
998       NtCancelTimer (_my_tls.locals.cw_timer, NULL);
999     }
1000
1001   return res;
1002 }
1003
1004 int
1005 pthread::setcancelstate (int state, int *oldstate)
1006 {
1007   int result = 0;
1008
1009   mutex.lock ();
1010
1011   if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
1012     result = EINVAL;
1013   else
1014     {
1015       if (oldstate)
1016         *oldstate = cancelstate;
1017       cancelstate = state;
1018     }
1019
1020   mutex.unlock ();
1021
1022   return result;
1023 }
1024
1025 int
1026 pthread::setcanceltype (int type, int *oldtype)
1027 {
1028   int result = 0;
1029
1030   mutex.lock ();
1031
1032   if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS)
1033     result = EINVAL;
1034   else
1035     {
1036       if (oldtype)
1037         *oldtype = canceltype;
1038       canceltype = type;
1039     }
1040
1041   mutex.unlock ();
1042
1043   return result;
1044 }
1045
1046 void
1047 pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
1048 {
1049   if (this != self ())
1050     // TODO: do it?
1051     api_fatal ("Attempt to push a cleanup handler across threads");
1052   handler->next = cleanup_stack;
1053   cleanup_stack = handler;
1054 }
1055
1056 void
1057 pthread::pop_cleanup_handler (int const execute)
1058 {
1059   if (this != self ())
1060     // TODO: send a signal or something to the thread ?
1061     api_fatal ("Attempt to execute a cleanup handler across threads");
1062
1063   mutex.lock ();
1064
1065   if (cleanup_stack != NULL)
1066     {
1067       __pthread_cleanup_handler *handler = cleanup_stack;
1068
1069       if (execute)
1070         (*handler->function) (handler->arg);
1071       cleanup_stack = handler->next;
1072     }
1073
1074   mutex.unlock ();
1075 }
1076
1077 void
1078 pthread::pop_all_cleanup_handlers ()
1079 {
1080   while (cleanup_stack != NULL)
1081     pop_cleanup_handler (1);
1082 }
1083
1084 void
1085 pthread::cancel_self ()
1086 {
1087   /* Can someone explain why the pthread:: is needed here?  g++ complains
1088      without it. */
1089   pthread::exit (PTHREAD_CANCELED);
1090 }
1091
1092 DWORD
1093 pthread::get_thread_id ()
1094 {
1095   return thread_id;
1096 }
1097
1098 void
1099 pthread::_fixup_after_fork ()
1100 {
1101   /* set thread to not running if it is not the forking thread */
1102   if (this != pthread::self ())
1103     {
1104       magic = 0;
1105       valid = false;
1106       win32_obj_id = NULL;
1107       canceled = false;
1108       cancel_event = NULL;
1109     }
1110 }
1111
1112 void
1113 pthread::suspend_except_self ()
1114 {
1115   if (valid && this != pthread::self ())
1116     SuspendThread (win32_obj_id);
1117 }
1118
1119 void
1120 pthread::resume ()
1121 {
1122   if (valid)
1123     ResumeThread (win32_obj_id);
1124 }
1125
1126 /* instance members */
1127
1128 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
1129 joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
1130 inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), stacksize (0),
1131 guardsize ((size_t) -1)
1132 {
1133   schedparam.sched_priority = 0;
1134 }
1135
1136 pthread_attr::~pthread_attr ()
1137 {
1138 }
1139
1140 pthread_condattr::pthread_condattr ():verifyable_object
1141   (PTHREAD_CONDATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE),
1142   clock_id (CLOCK_REALTIME)
1143 {
1144 }
1145
1146 pthread_condattr::~pthread_condattr ()
1147 {
1148 }
1149
1150 List<pthread_cond> pthread_cond::conds;
1151
1152 /* This is used for cond creation protection within a single process only */
1153 fast_mutex NO_COPY pthread_cond::cond_initialization_lock;
1154
1155 /* We can only be called once.
1156    TODO: (no rush) use a non copied memory section to
1157    hold an initialization flag.  */
1158 void
1159 pthread_cond::init_mutex ()
1160 {
1161   if (!cond_initialization_lock.init ())
1162     api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
1163 }
1164
1165 pthread_cond::pthread_cond (pthread_condattr *attr) :
1166   verifyable_object (PTHREAD_COND_MAGIC),
1167   shared (0), clock_id (CLOCK_REALTIME), waiting (0), pending (0),
1168   sem_wait (NULL), mtx_cond(NULL), next (NULL)
1169 {
1170   pthread_mutex *verifyable_mutex_obj;
1171
1172   if (attr)
1173     {
1174       clock_id = attr->clock_id;
1175
1176       if (attr->shared != PTHREAD_PROCESS_PRIVATE)
1177         {
1178           magic = 0;
1179           return;
1180         }
1181     }
1182
1183   verifyable_mutex_obj = &mtx_in;
1184   if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1185     {
1186       thread_printf ("Internal cond mutex is not valid. this %p", this);
1187       magic = 0;
1188       return;
1189     }
1190   /*
1191    * Change the mutex type to NORMAL.
1192    * This mutex MUST be of type normal
1193   */
1194   mtx_in.set_type (PTHREAD_MUTEX_NORMAL);
1195
1196   verifyable_mutex_obj = &mtx_out;
1197   if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1198     {
1199       thread_printf ("Internal cond mutex is not valid. this %p", this);
1200       magic = 0;
1201       return;
1202     }
1203   /* Change the mutex type to NORMAL to speed up mutex operations */
1204   mtx_out.set_type (PTHREAD_MUTEX_NORMAL);
1205
1206   sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
1207   if (!sem_wait)
1208     {
1209       pthread_printf ("CreateSemaphore failed. %E");
1210       magic = 0;
1211       return;
1212     }
1213
1214   conds.insert (this);
1215 }
1216
1217 pthread_cond::~pthread_cond ()
1218 {
1219   if (sem_wait)
1220     CloseHandle (sem_wait);
1221
1222   conds.remove (this);
1223 }
1224
1225 void
1226 pthread_cond::unblock (const bool all)
1227 {
1228   unsigned long releaseable;
1229
1230   /*
1231    * Block outgoing threads (and avoid simultanous unblocks)
1232    */
1233   mtx_out.lock ();
1234
1235   releaseable = waiting - pending;
1236   if (releaseable)
1237     {
1238       unsigned long released;
1239
1240       if (!pending)
1241         {
1242           /*
1243            * Block incoming threads until all waiting threads are released.
1244            */
1245           mtx_in.lock ();
1246
1247           /*
1248            * Calculate releaseable again because threads can enter until
1249            * the semaphore has been taken, but they can not leave, therefore pending
1250            * is unchanged and releaseable can only get higher
1251            */
1252           releaseable = waiting - pending;
1253         }
1254
1255       released = all ? releaseable : 1;
1256       pending += released;
1257       /*
1258        * Signal threads
1259        */
1260       ::ReleaseSemaphore (sem_wait, released, NULL);
1261     }
1262
1263   /*
1264    * And let the threads release.
1265    */
1266   mtx_out.unlock ();
1267 }
1268
1269 int
1270 pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout)
1271 {
1272   DWORD rv;
1273
1274   mtx_in.lock ();
1275   if (InterlockedIncrement ((long *)&waiting) == 1)
1276     mtx_cond = mutex;
1277   else if (mtx_cond != mutex)
1278     {
1279       InterlockedDecrement ((long *)&waiting);
1280       mtx_in.unlock ();
1281       return EINVAL;
1282     }
1283   mtx_in.unlock ();
1284
1285   /*
1286    * Release the mutex and wait on semaphore
1287    */
1288   ++mutex->condwaits;
1289   mutex->unlock ();
1290
1291   rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
1292
1293   mtx_out.lock ();
1294
1295   if (rv != WAIT_OBJECT_0)
1296     {
1297       /*
1298        * It might happen that a signal is sent while the thread got canceled
1299        * or timed out. Try to take one.
1300        * If the thread gets one than a signal|broadcast is in progress.
1301        */
1302       if (WaitForSingleObject (sem_wait, 0) == WAIT_OBJECT_0)
1303         /*
1304          * thread got cancelled ot timed out while a signalling is in progress.
1305          * Set wait result back to signaled
1306          */
1307         rv = WAIT_OBJECT_0;
1308     }
1309
1310   InterlockedDecrement ((long *)&waiting);
1311
1312   if (rv == WAIT_OBJECT_0 && --pending == 0)
1313     /*
1314      * All signaled threads are released,
1315      * new threads can enter Wait
1316      */
1317     mtx_in.unlock ();
1318
1319   mtx_out.unlock ();
1320
1321   mutex->lock ();
1322   --mutex->condwaits;
1323
1324   if (rv == WAIT_CANCELED)
1325     pthread::static_cancel_self ();
1326   else if (rv == WAIT_SIGNALED)
1327     /* SUSv3 states:  If a signal is delivered to a thread waiting for a
1328        condition variable, upon return from the signal handler the thread
1329        resumes waiting for the condition variable as if it was not
1330        interrupted, or it shall return zero due to spurious wakeup.
1331        We opt for the latter choice here. */
1332     return 0;
1333   else if (rv == WAIT_TIMEOUT)
1334     return ETIMEDOUT;
1335
1336   return 0;
1337 }
1338
1339 void
1340 pthread_cond::_fixup_after_fork ()
1341 {
1342   waiting = pending = 0;
1343   mtx_cond = NULL;
1344
1345   /* Unlock eventually locked mutexes */
1346   mtx_in.unlock ();
1347   mtx_out.unlock ();
1348
1349   sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
1350   if (!sem_wait)
1351     api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1352 }
1353
1354 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1355   (PTHREAD_RWLOCKATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
1356 {
1357 }
1358
1359 pthread_rwlockattr::~pthread_rwlockattr ()
1360 {
1361 }
1362
1363 List<pthread_rwlock> pthread_rwlock::rwlocks;
1364
1365 /* This is used for rwlock creation protection within a single process only */
1366 fast_mutex NO_COPY pthread_rwlock::rwlock_initialization_lock;
1367
1368 /* We can only be called once.
1369    TODO: (no rush) use a non copied memory section to
1370    hold an initialization flag.  */
1371 void
1372 pthread_rwlock::init_mutex ()
1373 {
1374   if (!rwlock_initialization_lock.init ())
1375     api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1376 }
1377
1378 pthread_rwlock::pthread_rwlock (pthread_rwlockattr *attr) :
1379   verifyable_object (PTHREAD_RWLOCK_MAGIC),
1380   shared (0), waiting_readers (0), waiting_writers (0), writer (NULL),
1381   readers (NULL), readers_mx (), mtx (NULL), cond_readers (NULL), cond_writers (NULL),
1382   next (NULL)
1383 {
1384   pthread_mutex *verifyable_mutex_obj = &mtx;
1385   pthread_cond *verifyable_cond_obj;
1386
1387   if (!readers_mx.init ())
1388     {
1389       thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1390       magic = 0;
1391       return;
1392     }
1393
1394   if (attr)
1395     if (attr->shared != PTHREAD_PROCESS_PRIVATE)
1396       {
1397         magic = 0;
1398         return;
1399       }
1400
1401   if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1402     {
1403       thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1404       magic = 0;
1405       return;
1406     }
1407   /* Change the mutex type to NORMAL to speed up mutex operations */
1408   mtx.set_type (PTHREAD_MUTEX_NORMAL);
1409
1410   verifyable_cond_obj = &cond_readers;
1411   if (!pthread_cond::is_good_object (&verifyable_cond_obj))
1412     {
1413       thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1414       magic = 0;
1415       return;
1416     }
1417
1418   verifyable_cond_obj = &cond_writers;
1419   if (!pthread_cond::is_good_object (&verifyable_cond_obj))
1420     {
1421       thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1422       magic = 0;
1423       return;
1424     }
1425
1426
1427   rwlocks.insert (this);
1428 }
1429
1430 pthread_rwlock::~pthread_rwlock ()
1431 {
1432   rwlocks.remove (this);
1433 }
1434
1435 int
1436 pthread_rwlock::rdlock ()
1437 {
1438   int result = 0;
1439   struct RWLOCK_READER *reader;
1440   pthread_t self = pthread::self ();
1441
1442   mtx.lock ();
1443
1444   reader = lookup_reader (self);
1445   if (reader)
1446     {
1447       if (reader->n < ULONG_MAX)
1448         ++reader->n;
1449       else
1450         errno = EAGAIN;
1451       goto DONE;
1452     }
1453
1454   reader = new struct RWLOCK_READER;
1455   if (!reader)
1456     {
1457       result = EAGAIN;
1458       goto DONE;
1459     }
1460
1461   while (writer || waiting_writers)
1462     {
1463       pthread_cleanup_push (pthread_rwlock::rdlock_cleanup, this);
1464
1465       ++waiting_readers;
1466       cond_readers.wait (&mtx);
1467       --waiting_readers;
1468
1469       pthread_cleanup_pop (0);
1470     }
1471
1472   reader->thread = self;
1473   reader->n = 1;
1474   add_reader (reader);
1475
1476  DONE:
1477   mtx.unlock ();
1478
1479   return result;
1480 }
1481
1482 int
1483 pthread_rwlock::tryrdlock ()
1484 {
1485   int result = 0;
1486   pthread_t self = pthread::self ();
1487
1488   mtx.lock ();
1489
1490   if (writer || waiting_writers || lookup_reader (self))
1491     result = EBUSY;
1492   else
1493     {
1494       struct RWLOCK_READER *reader;
1495
1496       reader = lookup_reader (self);
1497       if (reader && reader->n < ULONG_MAX)
1498         ++reader->n;
1499       else if ((reader = new struct RWLOCK_READER))
1500         {
1501           reader->thread = self;
1502           reader->n = 1;
1503           add_reader (reader);
1504         }
1505       else
1506         result = EAGAIN;
1507     }
1508
1509   mtx.unlock ();
1510
1511   return result;
1512 }
1513
1514 int
1515 pthread_rwlock::wrlock ()
1516 {
1517   int result = 0;
1518   pthread_t self = pthread::self ();
1519
1520   mtx.lock ();
1521
1522   if (writer == self || lookup_reader (self))
1523     {
1524       result = EDEADLK;
1525       goto DONE;
1526     }
1527
1528   while (writer || readers)
1529     {
1530       pthread_cleanup_push (pthread_rwlock::wrlock_cleanup, this);
1531
1532       ++waiting_writers;
1533       cond_writers.wait (&mtx);
1534       --waiting_writers;
1535
1536       pthread_cleanup_pop (0);
1537     }
1538
1539   writer = self;
1540
1541  DONE:
1542   mtx.unlock ();
1543
1544   return result;
1545 }
1546
1547 int
1548 pthread_rwlock::trywrlock ()
1549 {
1550   int result = 0;
1551   pthread_t self = pthread::self ();
1552
1553   mtx.lock ();
1554
1555   if (writer || readers)
1556     result = EBUSY;
1557   else
1558     writer = self;
1559
1560   mtx.unlock ();
1561
1562   return result;
1563 }
1564
1565 int
1566 pthread_rwlock::unlock ()
1567 {
1568   int result = 0;
1569   pthread_t self = pthread::self ();
1570
1571   mtx.lock ();
1572
1573   if (writer)
1574     {
1575       if (writer != self)
1576         {
1577           result = EPERM;
1578           goto DONE;
1579         }
1580
1581       writer = NULL;
1582     }
1583   else
1584     {
1585       struct RWLOCK_READER *reader = lookup_reader (self);
1586
1587       if (!reader)
1588         {
1589           result = EPERM;
1590           goto DONE;
1591         }
1592       if (--reader->n > 0)
1593         goto DONE;
1594
1595       remove_reader (reader);
1596       delete reader;
1597     }
1598
1599   release ();
1600
1601  DONE:
1602   mtx.unlock ();
1603
1604   return result;
1605 }
1606
1607 void
1608 pthread_rwlock::add_reader (struct RWLOCK_READER *rd)
1609 {
1610   List_insert (readers, rd);
1611 }
1612
1613 void
1614 pthread_rwlock::remove_reader (struct RWLOCK_READER *rd)
1615 {
1616   List_remove (readers_mx, readers, rd);
1617 }
1618
1619 struct pthread_rwlock::RWLOCK_READER *
1620 pthread_rwlock::lookup_reader (pthread_t thread)
1621 {
1622   readers_mx.lock ();
1623
1624   struct RWLOCK_READER *cur = readers;
1625
1626   while (cur && cur->thread != thread)
1627     cur = cur->next;
1628
1629   readers_mx.unlock ();
1630
1631   return cur;
1632 }
1633
1634 void
1635 pthread_rwlock::rdlock_cleanup (void *arg)
1636 {
1637   pthread_rwlock *rwlock = (pthread_rwlock *) arg;
1638
1639   --(rwlock->waiting_readers);
1640   rwlock->release ();
1641   rwlock->mtx.unlock ();
1642 }
1643
1644 void
1645 pthread_rwlock::wrlock_cleanup (void *arg)
1646 {
1647   pthread_rwlock *rwlock = (pthread_rwlock *) arg;
1648
1649   --(rwlock->waiting_writers);
1650   rwlock->release ();
1651   rwlock->mtx.unlock ();
1652 }
1653
1654 void
1655 pthread_rwlock::_fixup_after_fork ()
1656 {
1657   pthread_t self = pthread::self ();
1658   struct RWLOCK_READER **temp = &readers;
1659
1660   waiting_readers = 0;
1661   waiting_writers = 0;
1662
1663   if (!readers_mx.init ())
1664     api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1665
1666   /* Unlock eventually locked mutex */
1667   mtx.unlock ();
1668   /*
1669    * Remove all readers except self
1670    */
1671   while (*temp)
1672     {
1673       if ((*temp)->thread == self)
1674         temp = &((*temp)->next);
1675       else
1676         {
1677           struct RWLOCK_READER *cur = *temp;
1678           *temp = (*temp)->next;
1679           delete cur;
1680         }
1681     }
1682 }
1683
1684 /* pthread_key */
1685 /* static members */
1686 /* This stores pthread_key information across fork() boundaries */
1687 List<pthread_key> pthread_key::keys;
1688
1689 /* non-static members */
1690
1691 pthread_key::pthread_key (void (*aDestructor) (void *)):verifyable_object (PTHREAD_KEY_MAGIC), destructor (aDestructor)
1692 {
1693   tls_index = TlsAlloc ();
1694   if (tls_index == TLS_OUT_OF_INDEXES)
1695     magic = 0;
1696   else
1697     keys.insert (this);
1698 }
1699
1700 pthread_key::~pthread_key ()
1701 {
1702   /* We may need to make the list code lock the list during operations
1703    */
1704   if (magic != 0)
1705     {
1706       keys.remove (this);
1707       TlsFree (tls_index);
1708     }
1709 }
1710
1711 void
1712 pthread_key::_fixup_before_fork ()
1713 {
1714   fork_buf = get ();
1715 }
1716
1717 void
1718 pthread_key::_fixup_after_fork ()
1719 {
1720   tls_index = TlsAlloc ();
1721   if (tls_index == TLS_OUT_OF_INDEXES)
1722     api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1723   set (fork_buf);
1724 }
1725
1726 void
1727 pthread_key::run_destructor ()
1728 {
1729   if (destructor)
1730     {
1731       void *oldValue = get ();
1732       if (oldValue)
1733         {
1734           set (NULL);
1735           destructor (oldValue);
1736         }
1737     }
1738 }
1739
1740 /* pshared mutexs */
1741
1742 /* static members */
1743
1744 List<pthread_mutex> pthread_mutex::mutexes;
1745
1746 /* This is used for mutex creation protection within a single process only */
1747 fast_mutex NO_COPY pthread_mutex::mutex_initialization_lock;
1748
1749 void
1750 pthread_mutex::init_mutex ()
1751 {
1752   if (!mutex_initialization_lock.init ())
1753     api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1754 }
1755
1756 pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
1757   verifyable_object (0),        /* set magic to zero initially */
1758   lock_counter (0),
1759   win32_obj_id (NULL), owner (_new_mutex),
1760 #ifdef DEBUGGING
1761   tid (0),
1762 #endif
1763   recursion_counter (0), condwaits (0),
1764   type (PTHREAD_MUTEX_ERRORCHECK),
1765   pshared (PTHREAD_PROCESS_PRIVATE)
1766 {
1767   win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
1768   if (!win32_obj_id)
1769     return;
1770   /*attr checked in the C call */
1771   if (!attr)
1772     /* handled in the caller */;
1773   else if (attr->pshared != PTHREAD_PROCESS_SHARED)
1774     type = attr->mutextype;
1775   else
1776     return;             /* Not implemented */
1777
1778   magic = PTHREAD_MUTEX_MAGIC;
1779   mutexes.insert (this);
1780 }
1781
1782 pthread_mutex::~pthread_mutex ()
1783 {
1784   if (win32_obj_id)
1785     {
1786       CloseHandle (win32_obj_id);
1787       win32_obj_id = NULL;
1788     }
1789
1790   mutexes.remove (this);
1791   owner = _destroyed_mutex;
1792   magic = 0;
1793 }
1794
1795 int
1796 pthread_mutex::lock ()
1797 {
1798   pthread_t self = ::pthread_self ();
1799   int result = 0;
1800
1801   if (InterlockedIncrement ((long *) &lock_counter) == 1)
1802     set_owner (self);
1803   else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
1804            || !pthread::equal (owner, self))
1805     {
1806       cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
1807       set_owner (self);
1808     }
1809   else
1810     {
1811       InterlockedDecrement ((long *) &lock_counter);
1812       if (type == PTHREAD_MUTEX_RECURSIVE)
1813         result = lock_recursive ();
1814       else
1815         result = EDEADLK;
1816     }
1817
1818   pthread_printf ("mutex %p, self %p, owner %p, lock_counter %d, recursion_counter %d",
1819                   this, self, owner, lock_counter, recursion_counter);
1820   return result;
1821 }
1822
1823 int
1824 pthread_mutex::unlock ()
1825 {
1826   int res = 0;
1827   pthread_t self = ::pthread_self ();
1828   if (type == PTHREAD_MUTEX_NORMAL)
1829     /* no error checking */;
1830   else if (no_owner ())
1831     res = type == PTHREAD_MUTEX_ERRORCHECK ? EINVAL : 0;
1832   else if (!pthread::equal (owner, self))
1833     res = EPERM;
1834   if (!res && recursion_counter > 0 && --recursion_counter == 0)
1835     /* Don't try to unlock anything if recursion_counter == 0.
1836        This means the mutex was never locked or that we've forked. */
1837     {
1838       owner = (pthread_t) _unlocked_mutex;
1839 #ifdef DEBUGGING
1840       tid = 0;
1841 #endif
1842       if (InterlockedDecrement ((long *) &lock_counter))
1843         ::SetEvent (win32_obj_id); // Another thread is waiting
1844       res = 0;
1845     }
1846
1847   pthread_printf ("mutex %p, owner %p, self %p, lock_counter %d, recursion_counter %d, type %d, res %d",
1848                   this, owner, self, lock_counter, recursion_counter, type, res);
1849   return res;
1850 }
1851
1852 int
1853 pthread_mutex::trylock ()
1854 {
1855   pthread_t self = ::pthread_self ();
1856   int result = 0;
1857
1858   if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
1859     set_owner (self);
1860   else if (type == PTHREAD_MUTEX_RECURSIVE && pthread::equal (owner, self))
1861     result = lock_recursive ();
1862   else
1863     result = EBUSY;
1864
1865   return result;
1866 }
1867
1868 int
1869 pthread_mutex::destroy ()
1870 {
1871   if (condwaits || trylock ())
1872     // Do not destroy a condwaited or locked mutex
1873     return EBUSY;
1874   else if (recursion_counter > 1)
1875     {
1876       // Do not destroy a recursive locked mutex
1877       recursion_counter--;
1878       return EBUSY;
1879     }
1880
1881   delete this;
1882   return 0;
1883 }
1884
1885 void
1886 pthread_mutex::_fixup_after_fork ()
1887 {
1888   pthread_printf ("mutex %p", this);
1889   if (pshared != PTHREAD_PROCESS_PRIVATE)
1890     api_fatal ("pthread_mutex::_fixup_after_fork () doesn't understand PROCESS_SHARED mutex's");
1891
1892   /* All waiting threads are gone after a fork */
1893   recursion_counter = 0;
1894   lock_counter = 0;
1895   condwaits = 0;
1896 #ifdef DEBUGGING
1897   tid = 0xffffffff;     /* Don't know the tid after a fork */
1898 #endif
1899   win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
1900   if (!win32_obj_id)
1901     api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 event for mutex");
1902 }
1903
1904 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC),
1905 pshared (PTHREAD_PROCESS_PRIVATE), mutextype (PTHREAD_MUTEX_ERRORCHECK)
1906 {
1907 }
1908
1909 pthread_mutexattr::~pthread_mutexattr ()
1910 {
1911 }
1912
1913 /* pshared spinlocks
1914
1915    The infrastructure is provided by the underlying pthread_mutex class.
1916    The rest is a simplification implementing spin locking. */
1917
1918 pthread_spinlock::pthread_spinlock (int pshared) :
1919   pthread_mutex (NULL)
1920 {
1921   magic = PTHREAD_SPINLOCK_MAGIC;
1922   set_type (PTHREAD_MUTEX_NORMAL);
1923   set_shared (pshared);
1924 }
1925
1926 int
1927 pthread_spinlock::lock ()
1928 {
1929   pthread_t self = ::pthread_self ();
1930   int result = -1;
1931
1932   do
1933     {
1934       if (InterlockedExchange ((long *) &lock_counter, 1) == 0)
1935         {
1936           set_owner (self);
1937           result = 0;
1938         }
1939       else if (pthread::equal (owner, self))
1940         result = EDEADLK;
1941       else
1942         {
1943           /* Minimal timeout to minimize CPU usage while still spinning. */
1944           LARGE_INTEGER timeout;
1945           timeout.QuadPart = -10000LL;
1946           cancelable_wait (win32_obj_id, &timeout, cw_no_cancel, cw_sig_resume);
1947         }
1948     }
1949   while (result == -1);
1950   pthread_printf ("spinlock %p, self %p, owner %p", this, self, owner);
1951   return result;
1952 }
1953
1954 int
1955 pthread_spinlock::unlock ()
1956 {
1957   pthread_t self = ::pthread_self ();
1958   int result = 0;
1959
1960   if (!pthread::equal (owner, self))
1961     result = EPERM;
1962   else
1963     {
1964       owner = (pthread_t) _unlocked_mutex;
1965 #ifdef DEBUGGING
1966       tid = 0;
1967 #endif
1968       InterlockedExchange ((long *) &lock_counter, 0);
1969       ::SetEvent (win32_obj_id);
1970       result = 0;
1971     }
1972   pthread_printf ("spinlock %p, owner %p, self %p, res %d",
1973                   this, owner, self, result);
1974   return result;
1975 }
1976
1977 DWORD WINAPI
1978 pthread::thread_init_wrapper (void *arg)
1979 {
1980   pthread *thread = (pthread *) arg;
1981   set_tls_self_pointer (thread);
1982
1983   thread->mutex.lock ();
1984
1985   // if thread is detached force cleanup on exit
1986   if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
1987     thread->joiner = thread;
1988   _my_tls.sigmask = thread->parent_sigmask;
1989   thread->mutex.unlock ();
1990
1991   thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
1992                  _impure_ptr, thread, thread->function, thread->arg);
1993
1994   // call the user's thread
1995   void *ret = thread->function (thread->arg);
1996
1997   thread->exit (ret);
1998
1999   return 0;     // just for show.  Never returns.
2000 }
2001
2002 unsigned long
2003 pthread::getsequence_np ()
2004 {
2005   return get_thread_id ();
2006 }
2007
2008 int
2009 pthread::create (pthread_t *thread, const pthread_attr_t *attr,
2010                   void *(*start_routine) (void *), void *arg)
2011 {
2012   if (attr && !pthread_attr::is_good_object (attr))
2013     return EINVAL;
2014
2015   *thread = new pthread ();
2016   if (!(*thread)->create (start_routine, attr ? *attr : NULL, arg))
2017     {
2018       delete (*thread);
2019       *thread = NULL;
2020       return EAGAIN;
2021     }
2022
2023   return 0;
2024 }
2025
2026 int
2027 pthread::once (pthread_once_t *once_control, void (*init_routine) (void))
2028 {
2029   // already done ?
2030   if (once_control->state)
2031     return 0;
2032
2033   pthread_mutex_lock (&once_control->mutex);
2034   /* Here we must set a cancellation handler to unlock the mutex if needed */
2035   /* but a cancellation handler is not the right thing. We need this in the thread
2036    *cleanup routine. Assumption: a thread can only be in one pthread_once routine
2037    *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
2038    *on pthread_exit ();
2039    */
2040   if (!once_control->state)
2041     {
2042       init_routine ();
2043       once_control->state = 1;
2044     }
2045   /* Here we must remove our cancellation handler */
2046   pthread_mutex_unlock (&once_control->mutex);
2047   return 0;
2048 }
2049
2050 int
2051 pthread::cancel (pthread_t thread)
2052 {
2053   if (!is_good_object (&thread))
2054     return ESRCH;
2055
2056   return thread->cancel ();
2057 }
2058
2059 void
2060 pthread::atforkprepare ()
2061 {
2062   callback *cb = MT_INTERFACE->pthread_prepare;
2063   while (cb)
2064     {
2065       cb->cb ();
2066       cb = cb->next;
2067     }
2068
2069   __fp_lock_all ();
2070
2071   MT_INTERFACE->fixup_before_fork ();
2072 }
2073
2074 void
2075 pthread::atforkparent ()
2076 {
2077   __fp_unlock_all ();
2078
2079   callback *cb = MT_INTERFACE->pthread_parent;
2080   while (cb)
2081     {
2082       cb->cb ();
2083       cb = cb->next;
2084     }
2085 }
2086
2087 void
2088 pthread::atforkchild ()
2089 {
2090   MT_INTERFACE->fixup_after_fork ();
2091
2092   __fp_unlock_all ();
2093
2094   callback *cb = MT_INTERFACE->pthread_child;
2095   while (cb)
2096     {
2097       cb->cb ();
2098       cb = cb->next;
2099     }
2100 }
2101
2102 /* Register a set of functions to run before and after fork.
2103    prepare calls are called in LI-FC order.
2104    parent and child calls are called in FI-FC order.  */
2105 int
2106 pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void))
2107 {
2108   callback *prepcb = NULL, *parentcb = NULL, *childcb = NULL;
2109   if (prepare)
2110     {
2111       prepcb = new callback;
2112       if (!prepcb)
2113         return ENOMEM;
2114     }
2115   if (parent)
2116     {
2117       parentcb = new callback;
2118       if (!parentcb)
2119         {
2120           if (prepcb)
2121             delete prepcb;
2122           return ENOMEM;
2123         }
2124     }
2125   if (child)
2126     {
2127       childcb = new callback;
2128       if (!childcb)
2129         {
2130           if (prepcb)
2131             delete prepcb;
2132           if (parentcb)
2133             delete parentcb;
2134           return ENOMEM;
2135         }
2136     }
2137
2138   if (prepcb)
2139   {
2140     prepcb->cb = prepare;
2141     List_insert (MT_INTERFACE->pthread_prepare, prepcb);
2142   }
2143   if (parentcb)
2144   {
2145     parentcb->cb = parent;
2146     callback **t = &MT_INTERFACE->pthread_parent;
2147     while (*t)
2148       t = &(*t)->next;
2149     /* t = pointer to last next in the list */
2150     List_insert (*t, parentcb);
2151   }
2152   if (childcb)
2153   {
2154     childcb->cb = child;
2155     callback **t = &MT_INTERFACE->pthread_child;
2156     while (*t)
2157       t = &(*t)->next;
2158     /* t = pointer to last next in the list */
2159     List_insert (*t, childcb);
2160   }
2161   return 0;
2162 }
2163
2164 extern "C" int
2165 pthread_attr_init (pthread_attr_t *attr)
2166 {
2167   if (pthread_attr::is_good_object (attr))
2168     return EBUSY;
2169
2170   *attr = new pthread_attr;
2171   if (!pthread_attr::is_good_object (attr))
2172     {
2173       delete (*attr);
2174       *attr = NULL;
2175       return ENOMEM;
2176     }
2177   return 0;
2178 }
2179
2180 extern "C" int
2181 pthread_attr_getinheritsched (const pthread_attr_t *attr,
2182                                 int *inheritsched)
2183 {
2184   if (!pthread_attr::is_good_object (attr))
2185     return EINVAL;
2186   *inheritsched = (*attr)->inheritsched;
2187   return 0;
2188 }
2189
2190 extern "C" int
2191 pthread_attr_getschedparam (const pthread_attr_t *attr,
2192                               struct sched_param *param)
2193 {
2194   if (!pthread_attr::is_good_object (attr))
2195     return EINVAL;
2196   *param = (*attr)->schedparam;
2197   return 0;
2198 }
2199
2200 /* From a pure code point of view, this should call a helper in sched.cc,
2201    to allow for someone adding scheduler policy changes to win32 in the future.
2202    However that's extremely unlikely, so short and sweet will do us */
2203 extern "C" int
2204 pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy)
2205 {
2206   if (!pthread_attr::is_good_object (attr))
2207     return EINVAL;
2208   *policy = SCHED_FIFO;
2209   return 0;
2210 }
2211
2212
2213 extern "C" int
2214 pthread_attr_getscope (const pthread_attr_t *attr, int *contentionscope)
2215 {
2216   if (!pthread_attr::is_good_object (attr))
2217     return EINVAL;
2218   *contentionscope = (*attr)->contentionscope;
2219   return 0;
2220 }
2221
2222 extern "C" int
2223 pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
2224 {
2225   if (!pthread_attr::is_good_object (attr))
2226     return EINVAL;
2227   if (detachstate < 0 || detachstate > 1)
2228     return EINVAL;
2229   (*attr)->joinable = detachstate;
2230   return 0;
2231 }
2232
2233 extern "C" int
2234 pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstate)
2235 {
2236   if (!pthread_attr::is_good_object (attr))
2237     return EINVAL;
2238   *detachstate = (*attr)->joinable;
2239   return 0;
2240 }
2241
2242 extern "C" int
2243 pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched)
2244 {
2245   if (!pthread_attr::is_good_object (attr))
2246     return EINVAL;
2247   if (inheritsched != PTHREAD_INHERIT_SCHED
2248       && inheritsched != PTHREAD_EXPLICIT_SCHED)
2249     return ENOTSUP;
2250   (*attr)->inheritsched = inheritsched;
2251   return 0;
2252 }
2253
2254 extern "C" int
2255 pthread_attr_setschedparam (pthread_attr_t *attr,
2256                               const struct sched_param *param)
2257 {
2258   if (!pthread_attr::is_good_object (attr))
2259     return EINVAL;
2260   if (!valid_sched_parameters (param))
2261     return ENOTSUP;
2262   (*attr)->schedparam = *param;
2263   return 0;
2264 }
2265
2266 /* See __pthread_attr_getschedpolicy for some notes */
2267 extern "C" int
2268 pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)
2269 {
2270   if (!pthread_attr::is_good_object (attr))
2271     return EINVAL;
2272   if (policy != SCHED_FIFO)
2273     return ENOTSUP;
2274   return 0;
2275 }
2276
2277 extern "C" int
2278 pthread_attr_setscope (pthread_attr_t *attr, int contentionscope)
2279 {
2280   if (!pthread_attr::is_good_object (attr))
2281     return EINVAL;
2282   if (contentionscope != PTHREAD_SCOPE_SYSTEM
2283       && contentionscope != PTHREAD_SCOPE_PROCESS)
2284     return EINVAL;
2285   /* In future, we may be able to support system scope by escalating the thread
2286      priority to exceed the priority class. For now we only support PROCESS scope. */
2287   if (contentionscope != PTHREAD_SCOPE_PROCESS)
2288     return ENOTSUP;
2289   (*attr)->contentionscope = contentionscope;
2290   return 0;
2291 }
2292
2293 extern "C" int
2294 pthread_attr_setstack (pthread_attr_t *attr, void *addr, size_t size)
2295 {
2296   if (!pthread_attr::is_good_object (attr))
2297     return EINVAL;
2298   if (addr == NULL)
2299     return EINVAL;
2300   if (size < PTHREAD_STACK_MIN)
2301     return EINVAL;
2302   (*attr)->stackaddr = addr;
2303   (*attr)->stacksize = size;
2304   return 0;
2305 }
2306
2307 extern "C" int
2308 pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
2309 {
2310   if (!pthread_attr::is_good_object (attr))
2311     return EINVAL;
2312   /* uses lowest address of stack on all platforms */
2313   *addr = (void *)((int)(*attr)->stackaddr - (*attr)->stacksize);
2314   *size = (*attr)->stacksize;
2315   return 0;
2316 }
2317
2318 extern "C" int
2319 pthread_attr_setstackaddr (pthread_attr_t *attr, void *addr)
2320 {
2321   if (!pthread_attr::is_good_object (attr))
2322     return EINVAL;
2323   if (addr == NULL)
2324     return EINVAL;
2325   (*attr)->stackaddr = addr;
2326   return 0;
2327 }
2328
2329 extern "C" int
2330 pthread_attr_getstackaddr (const pthread_attr_t *attr, void **addr)
2331 {
2332   if (!pthread_attr::is_good_object (attr))
2333     return EINVAL;
2334   /* uses stack address, which is the higher address on platforms
2335      where the stack grows downwards, such as x86 */
2336   *addr = (*attr)->stackaddr;
2337   return 0;
2338 }
2339
2340 extern "C" int
2341 pthread_attr_setstacksize (pthread_attr_t *attr, size_t size)
2342 {
2343   if (!pthread_attr::is_good_object (attr))
2344     return EINVAL;
2345   if (size < PTHREAD_STACK_MIN)
2346     return EINVAL;
2347   (*attr)->stacksize = size;
2348   return 0;
2349 }
2350
2351 extern "C" int
2352 pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
2353 {
2354   if (!pthread_attr::is_good_object (attr))
2355     return EINVAL;
2356   *size = (*attr)->stacksize;
2357   return 0;
2358 }
2359
2360 extern "C" int
2361 pthread_attr_setguardsize (pthread_attr_t *attr, size_t size)
2362 {
2363   if (!pthread_attr::is_good_object (attr))
2364     return EINVAL;
2365   /* We don't support a guardsize of more than 1 Meg. */
2366   if (size > 1024 * 1024)
2367     return EINVAL;
2368   (*attr)->guardsize = size;
2369   return 0;
2370 }
2371
2372 extern "C" int
2373 pthread_attr_getguardsize (const pthread_attr_t *attr, size_t *size)
2374 {
2375   if (!pthread_attr::is_good_object (attr))
2376     return EINVAL;
2377   *size = (*attr)->guardsize;
2378   return 0;
2379 }
2380
2381 extern "C" int
2382 pthread_attr_destroy (pthread_attr_t *attr)
2383 {
2384   if (!pthread_attr::is_good_object (attr))
2385     return EINVAL;
2386   delete (*attr);
2387   *attr = NULL;
2388   return 0;
2389 }
2390
2391 int
2392 pthread::join (pthread_t *thread, void **return_val)
2393 {
2394    pthread_t joiner = self ();
2395
2396    joiner->testcancel ();
2397
2398    // Initialize return val with NULL
2399    if (return_val)
2400      *return_val = NULL;
2401
2402    if (!is_good_object (&joiner))
2403      return EINVAL;
2404
2405   if (!is_good_object (thread))
2406     return ESRCH;
2407
2408   if (equal (*thread,joiner))
2409     return EDEADLK;
2410
2411   (*thread)->mutex.lock ();
2412
2413   if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
2414     {
2415       (*thread)->mutex.unlock ();
2416       return EINVAL;
2417     }
2418   else
2419     {
2420       (*thread)->joiner = joiner;
2421       (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
2422       (*thread)->mutex.unlock ();
2423
2424       switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
2425         {
2426         case WAIT_OBJECT_0:
2427           if (return_val)
2428             *return_val = (*thread)->return_ptr;
2429           delete (*thread);
2430           break;
2431         case WAIT_CANCELED:
2432           // set joined thread back to joinable since we got canceled
2433           (*thread)->joiner = NULL;
2434           (*thread)->attr.joinable = PTHREAD_CREATE_JOINABLE;
2435           joiner->cancel_self ();
2436           // never reached
2437           break;
2438         default:
2439           // should never happen
2440           return EINVAL;
2441         }
2442     }
2443
2444   return 0;
2445 }
2446
2447 int
2448 pthread::detach (pthread_t *thread)
2449 {
2450   if (!is_good_object (thread))
2451     return ESRCH;
2452
2453   (*thread)->mutex.lock ();
2454   if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
2455     {
2456       (*thread)->mutex.unlock ();
2457       return EINVAL;
2458     }
2459
2460   // check if thread is still alive
2461   if ((*thread)->valid && WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT)
2462     {
2463       // force cleanup on exit
2464       (*thread)->joiner = *thread;
2465       (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
2466       (*thread)->mutex.unlock ();
2467     }
2468   else
2469     {
2470       // thread has already terminated.
2471       (*thread)->mutex.unlock ();
2472       delete (*thread);
2473     }
2474
2475   return 0;
2476 }
2477
2478 int
2479 pthread::suspend (pthread_t *thread)
2480 {
2481   if (!is_good_object (thread))
2482     return ESRCH;
2483
2484   if ((*thread)->suspended == false)
2485     {
2486       (*thread)->suspended = true;
2487       SuspendThread ((*thread)->win32_obj_id);
2488     }
2489
2490   return 0;
2491 }
2492
2493
2494 int
2495 pthread::resume (pthread_t *thread)
2496 {
2497   if (!is_good_object (thread))
2498     return ESRCH;
2499
2500   if ((*thread)->suspended == true)
2501     ResumeThread ((*thread)->win32_obj_id);
2502   (*thread)->suspended = false;
2503
2504   return 0;
2505 }
2506
2507 extern "C" int
2508 pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
2509 {
2510   const size_t sizeof_tbi = sizeof (THREAD_BASIC_INFORMATION);
2511   PTHREAD_BASIC_INFORMATION tbi;
2512   NTSTATUS ret;
2513
2514   if (!pthread::is_good_object (&thread))
2515     return ESRCH;
2516
2517   /* attr may not be pre-initialized */
2518   if (!pthread_attr::is_good_object (attr))
2519   {
2520     int rv = pthread_attr_init (attr);
2521     if (rv != 0)
2522       return rv;
2523   }
2524
2525   (*attr)->joinable = thread->attr.joinable;
2526   (*attr)->contentionscope = thread->attr.contentionscope;
2527   (*attr)->inheritsched = thread->attr.inheritsched;
2528   (*attr)->schedparam = thread->attr.schedparam;
2529   (*attr)->guardsize = thread->attr.guardsize;
2530
2531   tbi = (PTHREAD_BASIC_INFORMATION) malloc (sizeof_tbi);
2532   ret = NtQueryInformationThread (thread->win32_obj_id, ThreadBasicInformation,
2533                                   tbi, sizeof_tbi, NULL);
2534
2535   if (NT_SUCCESS (ret))
2536     {
2537       PNT_TIB tib = tbi->TebBaseAddress;
2538       (*attr)->stackaddr = tib->StackBase;
2539       /* stack grows downwards on x86 systems */
2540       (*attr)->stacksize = (int)tib->StackBase - (int)tib->StackLimit;
2541     }
2542   else
2543     {
2544       debug_printf ("NtQueryInformationThread(ThreadBasicInformation), "
2545                     "status %p", ret);
2546       (*attr)->stackaddr = thread->attr.stackaddr;
2547       (*attr)->stacksize = thread->attr.stacksize;
2548     }
2549
2550   return 0;
2551 }
2552
2553 /* provided for source level compatability.
2554    See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2555 */
2556 extern "C" int
2557 pthread_getconcurrency ()
2558 {
2559   return MT_INTERFACE->concurrency;
2560 }
2561
2562 extern "C" int
2563 pthread_getcpuclockid (pthread_t thread, clockid_t *clk_id)
2564 {
2565   if (!pthread::is_good_object (&thread))
2566     return (ESRCH);
2567   *clk_id = (clockid_t) THREADID_TO_CLOCKID (thread->getsequence_np ());
2568   return 0;
2569 }
2570
2571 /* keep this in sync with sched.cc */
2572 extern "C" int
2573 pthread_getschedparam (pthread_t thread, int *policy,
2574                          struct sched_param *param)
2575 {
2576   if (!pthread::is_good_object (&thread))
2577     return ESRCH;
2578   *policy = SCHED_FIFO;
2579   /* we don't return the current effective priority, we return the current
2580      requested priority */
2581   *param = thread->attr.schedparam;
2582   return 0;
2583 }
2584
2585 /* Thread Specific Data */
2586 extern "C" int
2587 pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
2588 {
2589   *key = new pthread_key (destructor);
2590
2591   if (!pthread_key::is_good_object (key))
2592     {
2593       delete (*key);
2594       *key = NULL;
2595       return EAGAIN;
2596     }
2597   return 0;
2598 }
2599
2600 extern "C" int
2601 pthread_key_delete (pthread_key_t key)
2602 {
2603   if (!pthread_key::is_good_object (&key))
2604     return EINVAL;
2605
2606   delete (key);
2607   return 0;
2608 }
2609
2610 /* provided for source level compatability.  See
2611 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2612 */
2613 extern "C" int
2614 pthread_setconcurrency (int new_level)
2615 {
2616   if (new_level < 0)
2617     return EINVAL;
2618   MT_INTERFACE->concurrency = new_level;
2619   return 0;
2620 }
2621
2622 /* keep syncronised with sched.cc */
2623 extern "C" int
2624 pthread_setschedparam (pthread_t thread, int policy,
2625                          const struct sched_param *param)
2626 {
2627   if (!pthread::is_good_object (&thread))
2628     return ESRCH;
2629   if (policy != SCHED_FIFO)
2630     return ENOTSUP;
2631   if (!param)
2632     return EINVAL;
2633   int rv =
2634     sched_set_thread_priority (thread->win32_obj_id, param->sched_priority);
2635   if (!rv)
2636     thread->attr.schedparam.sched_priority = param->sched_priority;
2637   return rv;
2638 }
2639
2640 extern "C" int
2641 pthread_setschedprio (pthread_t thread, int priority)
2642 {
2643   if (!pthread::is_good_object (&thread))
2644     return ESRCH;
2645   int rv =
2646     sched_set_thread_priority (thread->win32_obj_id, priority);
2647   if (!rv)
2648     thread->attr.schedparam.sched_priority = priority;
2649   return rv;
2650 }
2651
2652 extern "C" int
2653 pthread_setspecific (pthread_key_t key, const void *value)
2654 {
2655   if (!pthread_key::is_good_object (&key))
2656     return EINVAL;
2657   (key)->set (value);
2658   return 0;
2659 }
2660
2661 extern "C" void *
2662 pthread_getspecific (pthread_key_t key)
2663 {
2664   if (!pthread_key::is_good_object (&key))
2665     return NULL;
2666
2667   return (key)->get ();
2668
2669 }
2670
2671 extern "C" int
2672 pthread_cond_destroy (pthread_cond_t *cond)
2673 {
2674   if (pthread_cond::is_initializer (cond))
2675     return 0;
2676   if (!pthread_cond::is_good_object (cond))
2677     return EINVAL;
2678
2679   /* reads are atomic */
2680   if ((*cond)->waiting)
2681     return EBUSY;
2682
2683   delete (*cond);
2684   *cond = NULL;
2685
2686   return 0;
2687 }
2688
2689 int
2690 pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
2691 {
2692   pthread_cond_t new_cond;
2693
2694   if (attr && !pthread_condattr::is_good_object (attr))
2695     return EINVAL;
2696
2697   cond_initialization_lock.lock ();
2698
2699   new_cond = new pthread_cond (attr ? (*attr) : NULL);
2700   if (!is_good_object (&new_cond))
2701     {
2702       delete new_cond;
2703       cond_initialization_lock.unlock ();
2704       return EAGAIN;
2705     }
2706
2707   myfault efault;
2708   if (efault.faulted ())
2709     {
2710       delete new_cond;
2711       cond_initialization_lock.unlock ();
2712       return EINVAL;
2713     }
2714
2715   *cond = new_cond;
2716   cond_initialization_lock.unlock ();
2717
2718   return 0;
2719 }
2720
2721 extern "C" int
2722 pthread_cond_broadcast (pthread_cond_t *cond)
2723 {
2724   if (pthread_cond::is_initializer (cond))
2725     return 0;
2726   if (!pthread_cond::is_good_object (cond))
2727     return EINVAL;
2728
2729   (*cond)->unblock (true);
2730
2731   return 0;
2732 }
2733
2734 extern "C" int
2735 pthread_cond_signal (pthread_cond_t *cond)
2736 {
2737   if (pthread_cond::is_initializer (cond))
2738     return 0;
2739   if (!pthread_cond::is_good_object (cond))
2740     return EINVAL;
2741
2742   (*cond)->unblock (false);
2743
2744   return 0;
2745 }
2746
2747 static int
2748 __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2749                        PLARGE_INTEGER waitlength)
2750 {
2751   if (!pthread_mutex::is_good_object (mutex))
2752     return EINVAL;
2753   if (!(*mutex)->can_be_unlocked ())
2754     return EPERM;
2755
2756   if (pthread_cond::is_initializer (cond))
2757     pthread_cond::init (cond, NULL);
2758   if (!pthread_cond::is_good_object (cond))
2759     return EINVAL;
2760
2761   return (*cond)->wait (*mutex, waitlength);
2762 }
2763
2764 extern "C" int
2765 pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2766                         const struct timespec *abstime)
2767 {
2768   struct timespec tp;
2769   LARGE_INTEGER timeout;
2770
2771   myfault efault;
2772   if (efault.faulted ())
2773     return EINVAL;
2774
2775   pthread_testcancel ();
2776
2777   /* According to SUSv3, the abstime value must be checked for validity. */
2778   if (abstime->tv_sec < 0
2779       || abstime->tv_nsec < 0
2780       || abstime->tv_nsec > 999999999)
2781     return EINVAL;
2782
2783   clock_gettime ((*cond)->clock_id, &tp);
2784
2785   /* Check for immediate timeout before converting */
2786   if (tp.tv_sec > abstime->tv_sec
2787       || (tp.tv_sec == abstime->tv_sec
2788           && tp.tv_nsec > abstime->tv_nsec))
2789     return ETIMEDOUT;
2790
2791   timeout.QuadPart = abstime->tv_sec * NSPERSEC
2792                       + (abstime->tv_nsec + 99LL) / 100LL;
2793
2794   switch ((*cond)->clock_id)
2795     {
2796     case CLOCK_REALTIME:
2797       timeout.QuadPart += FACTOR;
2798       break;
2799     default:
2800       /* other clocks must be handled as relative timeout */
2801       timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
2802       timeout.QuadPart *= -1LL;
2803       break;
2804     }
2805   return __pthread_cond_dowait (cond, mutex, &timeout);
2806 }
2807
2808 extern "C" int
2809 pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
2810 {
2811   pthread_testcancel ();
2812
2813   return __pthread_cond_dowait (cond, mutex, NULL);
2814 }
2815
2816 extern "C" int
2817 pthread_condattr_init (pthread_condattr_t *condattr)
2818 {
2819   if (pthread_condattr::is_good_object (condattr))
2820     return EBUSY;
2821
2822   *condattr = new pthread_condattr;
2823   if (!pthread_condattr::is_good_object (condattr))
2824     {
2825       delete (*condattr);
2826       *condattr = NULL;
2827       return ENOMEM;
2828     }
2829   return 0;
2830 }
2831
2832 extern "C" int
2833 pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
2834 {
2835   if (!pthread_condattr::is_good_object (attr))
2836     return EINVAL;
2837   *pshared = (*attr)->shared;
2838   return 0;
2839 }
2840
2841 extern "C" int
2842 pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
2843 {
2844   if (!pthread_condattr::is_good_object (attr))
2845     return EINVAL;
2846   if ((pshared < 0) || (pshared > 1))
2847     return EINVAL;
2848   /* shared cond vars not currently supported */
2849   if (pshared != PTHREAD_PROCESS_PRIVATE)
2850     return EINVAL;
2851   (*attr)->shared = pshared;
2852   return 0;
2853 }
2854
2855 extern "C" int
2856 pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t *clock_id)
2857 {
2858   if (!pthread_condattr::is_good_object (attr))
2859     return EINVAL;
2860   *clock_id = (*attr)->clock_id;
2861   return 0;
2862 }
2863
2864 extern "C" int
2865 pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
2866 {
2867   if (!pthread_condattr::is_good_object (attr))
2868     return EINVAL;
2869   switch (clock_id)
2870     {
2871     case CLOCK_REALTIME:
2872     case CLOCK_MONOTONIC:
2873       break;
2874     default:
2875       return EINVAL;
2876     }
2877   (*attr)->clock_id = clock_id;
2878   return 0;
2879 }
2880
2881 extern "C" int
2882 pthread_condattr_destroy (pthread_condattr_t *condattr)
2883 {
2884   if (!pthread_condattr::is_good_object (condattr))
2885     return EINVAL;
2886   delete (*condattr);
2887   *condattr = NULL;
2888   return 0;
2889 }
2890
2891 extern "C" int
2892 pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
2893 {
2894   if (pthread_rwlock::is_initializer (rwlock))
2895     return 0;
2896   if (!pthread_rwlock::is_good_object (rwlock))
2897     return EINVAL;
2898
2899   if ((*rwlock)->writer || (*rwlock)->readers ||
2900       (*rwlock)->waiting_readers || (*rwlock)->waiting_writers)
2901     return EBUSY;
2902
2903   delete (*rwlock);
2904   *rwlock = NULL;
2905
2906   return 0;
2907 }
2908
2909 int
2910 pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
2911 {
2912   pthread_rwlock_t new_rwlock;
2913
2914   if (attr && !pthread_rwlockattr::is_good_object (attr))
2915     return EINVAL;
2916
2917   rwlock_initialization_lock.lock ();
2918
2919   new_rwlock = new pthread_rwlock (attr ? (*attr) : NULL);
2920   if (!is_good_object (&new_rwlock))
2921     {
2922       delete new_rwlock;
2923       rwlock_initialization_lock.unlock ();
2924       return EAGAIN;
2925     }
2926
2927   myfault efault;
2928   if (efault.faulted ())
2929     {
2930       delete new_rwlock;
2931       rwlock_initialization_lock.unlock ();
2932       return EINVAL;
2933     }
2934
2935   *rwlock = new_rwlock;
2936   rwlock_initialization_lock.unlock ();
2937
2938   return 0;
2939 }
2940
2941 extern "C" int
2942 pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
2943 {
2944   pthread_testcancel ();
2945
2946   if (pthread_rwlock::is_initializer (rwlock))
2947     pthread_rwlock::init (rwlock, NULL);
2948   if (!pthread_rwlock::is_good_object (rwlock))
2949     return EINVAL;
2950
2951   return (*rwlock)->rdlock ();
2952 }
2953
2954 extern "C" int
2955 pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
2956 {
2957   if (pthread_rwlock::is_initializer (rwlock))
2958     pthread_rwlock::init (rwlock, NULL);
2959   if (!pthread_rwlock::is_good_object (rwlock))
2960     return EINVAL;
2961
2962   return (*rwlock)->tryrdlock ();
2963 }
2964
2965 extern "C" int
2966 pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
2967 {
2968   pthread_testcancel ();
2969
2970   if (pthread_rwlock::is_initializer (rwlock))
2971     pthread_rwlock::init (rwlock, NULL);
2972   if (!pthread_rwlock::is_good_object (rwlock))
2973     return EINVAL;
2974
2975   return (*rwlock)->wrlock ();
2976 }
2977
2978 extern "C" int
2979 pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
2980 {
2981   if (pthread_rwlock::is_initializer (rwlock))
2982     pthread_rwlock::init (rwlock, NULL);
2983   if (!pthread_rwlock::is_good_object (rwlock))
2984     return EINVAL;
2985
2986   return (*rwlock)->trywrlock ();
2987 }
2988
2989 extern "C" int
2990 pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
2991 {
2992   if (pthread_rwlock::is_initializer (rwlock))
2993     return 0;
2994   if (!pthread_rwlock::is_good_object (rwlock))
2995     return EINVAL;
2996
2997   return (*rwlock)->unlock ();
2998 }
2999
3000 extern "C" int
3001 pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
3002 {
3003   if (pthread_rwlockattr::is_good_object (rwlockattr))
3004     return EBUSY;
3005
3006   *rwlockattr = new pthread_rwlockattr;
3007   if (!pthread_rwlockattr::is_good_object (rwlockattr))
3008     {
3009       delete (*rwlockattr);
3010       *rwlockattr = NULL;
3011       return ENOMEM;
3012     }
3013   return 0;
3014 }
3015
3016 extern "C" int
3017 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
3018 {
3019   if (!pthread_rwlockattr::is_good_object (attr))
3020     return EINVAL;
3021   *pshared = (*attr)->shared;
3022   return 0;
3023 }
3024
3025 extern "C" int
3026 pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
3027 {
3028   if (!pthread_rwlockattr::is_good_object (attr))
3029     return EINVAL;
3030   if ((pshared < 0) || (pshared > 1))
3031     return EINVAL;
3032   /* shared rwlock vars not currently supported */
3033   if (pshared != PTHREAD_PROCESS_PRIVATE)
3034     return EINVAL;
3035   (*attr)->shared = pshared;
3036   return 0;
3037 }
3038
3039 extern "C" int
3040 pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
3041 {
3042   if (!pthread_rwlockattr::is_good_object (rwlockattr))
3043     return EINVAL;
3044   delete (*rwlockattr);
3045   *rwlockattr = NULL;
3046   return 0;
3047 }
3048
3049 /* Thread signal */
3050 extern "C" int
3051 pthread_kill (pthread_t thread, int sig)
3052 {
3053   // lock myself, for the use of thread2signal
3054   // two different kills might clash: FIXME
3055
3056   if (!pthread::is_good_object (&thread))
3057     return EINVAL;
3058
3059   siginfo_t si = {0};
3060   si.si_signo = sig;
3061   si.si_code = SI_USER;
3062   si.si_pid = myself->pid;
3063   si.si_uid = myself->uid;
3064   int rval;
3065   if (!thread->valid)
3066     rval = ESRCH;
3067   else if (sig)
3068     {
3069       thread->cygtls->set_threadkill ();
3070       rval = sig_send (NULL, si, thread->cygtls);
3071     }
3072   else
3073     switch (WaitForSingleObject (thread->win32_obj_id, 0))
3074       {
3075       case WAIT_TIMEOUT:
3076         rval = 0;
3077         break;
3078       default:
3079         rval = ESRCH;
3080         break;
3081       }
3082
3083   // unlock myself
3084   return rval;
3085 }
3086
3087 extern "C" int
3088 pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
3089 {
3090   int res = handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
3091   syscall_printf ("%d = pthread_sigmask(%d, %p, %p)", operation, set, old_set);
3092   return res;
3093 }
3094
3095 /* ID */
3096
3097 extern "C" int
3098 pthread_equal (pthread_t t1, pthread_t t2)
3099 {
3100   return pthread::equal (t1, t2);
3101 }
3102
3103 /* Mutexes  */
3104
3105 int
3106 pthread_mutex::init (pthread_mutex_t *mutex,
3107                      const pthread_mutexattr_t *attr,
3108                      const pthread_mutex_t initializer)
3109 {
3110   if (attr && !pthread_mutexattr::is_good_object (attr))
3111     return EINVAL;
3112
3113   mutex_initialization_lock.lock ();
3114   if (initializer == NULL || pthread_mutex::is_initializer (mutex))
3115     {
3116       pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
3117       if (!is_good_object (&new_mutex))
3118         {
3119           delete new_mutex;
3120           mutex_initialization_lock.unlock ();
3121           return EAGAIN;
3122         }
3123
3124       if (!attr && initializer)
3125         {
3126           if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
3127             new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
3128           else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
3129             new_mutex->type = PTHREAD_MUTEX_NORMAL;
3130           else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
3131             new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
3132         }
3133
3134       myfault efault;
3135       if (efault.faulted ())
3136         {
3137           delete new_mutex;
3138           mutex_initialization_lock.unlock ();
3139           return EINVAL;
3140         }
3141
3142       *mutex = new_mutex;
3143     }
3144   mutex_initialization_lock.unlock ();
3145   pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
3146
3147   return 0;
3148 }
3149
3150 extern "C" int
3151 pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
3152                                 int *prioceiling)
3153 {
3154   /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
3155      mutex priorities.
3156
3157      We can support mutex priorities in the future though:
3158      Store a priority with each mutex.
3159      When the mutex is optained, set the thread priority as appropriate
3160      When the mutex is released, reset the thread priority.  */
3161   return ENOSYS;
3162 }
3163
3164 extern "C" int
3165 pthread_mutex_lock (pthread_mutex_t *mutex)
3166 {
3167   if (pthread_mutex::is_initializer (mutex))
3168     pthread_mutex::init (mutex, NULL, *mutex);
3169   if (!pthread_mutex::is_good_object (mutex))
3170     return EINVAL;
3171   return (*mutex)->lock ();
3172 }
3173
3174 extern "C" int
3175 pthread_mutex_trylock (pthread_mutex_t *mutex)
3176 {
3177   if (pthread_mutex::is_initializer (mutex))
3178     pthread_mutex::init (mutex, NULL, *mutex);
3179   if (!pthread_mutex::is_good_object (mutex))
3180     return EINVAL;
3181   return (*mutex)->trylock ();
3182 }
3183
3184 extern "C" int
3185 pthread_mutex_unlock (pthread_mutex_t *mutex)
3186 {
3187   if (pthread_mutex::is_initializer (mutex))
3188     return EPERM;
3189   if (!pthread_mutex::is_good_object (mutex))
3190     return EINVAL;
3191   return (*mutex)->unlock ();
3192 }
3193
3194 extern "C" int
3195 pthread_mutex_destroy (pthread_mutex_t *mutex)
3196 {
3197   int rv;
3198
3199   if (pthread_mutex::is_initializer (mutex))
3200     return 0;
3201   if (!pthread_mutex::is_good_object (mutex))
3202     return EINVAL;
3203
3204   rv = (*mutex)->destroy ();
3205   if (rv)
3206     return rv;
3207
3208   *mutex = NULL;
3209   return 0;
3210 }
3211
3212 extern "C" int
3213 pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
3214                                 int *old_ceiling)
3215 {
3216   return ENOSYS;
3217 }
3218
3219 /* Spinlocks  */
3220
3221 int
3222 pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
3223 {
3224   pthread_spinlock_t new_spinlock = new pthread_spinlock (pshared);
3225   if (!is_good_object (&new_spinlock))
3226     {
3227       delete new_spinlock;
3228       return EAGAIN;
3229     }
3230
3231   myfault efault;
3232   if (efault.faulted ())
3233     {
3234       delete new_spinlock;
3235       return EINVAL;
3236     }
3237
3238   *spinlock = new_spinlock;
3239   pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
3240
3241   return 0;
3242 }
3243
3244 extern "C" int
3245 pthread_spin_lock (pthread_spinlock_t *spinlock)
3246 {
3247   if (!pthread_spinlock::is_good_object (spinlock))
3248     return EINVAL;
3249   return (*spinlock)->lock ();
3250 }
3251
3252 extern "C" int
3253 pthread_spin_trylock (pthread_spinlock_t *spinlock)
3254 {
3255   if (!pthread_spinlock::is_good_object (spinlock))
3256     return EINVAL;
3257   return (*spinlock)->trylock ();
3258 }
3259
3260 extern "C" int
3261 pthread_spin_unlock (pthread_spinlock_t *spinlock)
3262 {
3263   if (!pthread_spinlock::is_good_object (spinlock))
3264     return EINVAL;
3265   return (*spinlock)->unlock ();
3266 }
3267
3268 extern "C" int
3269 pthread_spin_destroy (pthread_spinlock_t *spinlock)
3270 {
3271   if (!pthread_spinlock::is_good_object (spinlock))
3272     return EINVAL;
3273   return (*spinlock)->destroy ();
3274 }
3275
3276 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3277    for more detail */
3278 extern "C" int
3279 pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr,
3280                                  int *protocol)
3281 {
3282   if (!pthread_mutexattr::is_good_object (attr))
3283     return EINVAL;
3284   return ENOSYS;
3285 }
3286
3287 extern "C" int
3288 pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr,
3289                                 int *pshared)
3290 {
3291   if (!pthread_mutexattr::is_good_object (attr))
3292     return EINVAL;
3293   *pshared = (*attr)->pshared;
3294   return 0;
3295 }
3296
3297 extern "C" int
3298 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)
3299 {
3300   if (!pthread_mutexattr::is_good_object (attr))
3301     return EINVAL;
3302   *type = (*attr)->mutextype;
3303   return 0;
3304 }
3305
3306 /* FIXME: write and test process shared mutex's.  */
3307 extern "C" int
3308 pthread_mutexattr_init (pthread_mutexattr_t *attr)
3309 {
3310   if (pthread_mutexattr::is_good_object (attr))
3311     return EBUSY;
3312
3313   *attr = new pthread_mutexattr ();
3314   if (!pthread_mutexattr::is_good_object (attr))
3315     {
3316       delete (*attr);
3317       *attr = NULL;
3318       return ENOMEM;
3319     }
3320   return 0;
3321 }
3322
3323 extern "C" int
3324 pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
3325 {
3326   if (!pthread_mutexattr::is_good_object (attr))
3327     return EINVAL;
3328   delete (*attr);
3329   *attr = NULL;
3330   return 0;
3331 }
3332
3333
3334 /* Win32 doesn't support mutex priorities */
3335 extern "C" int
3336 pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol)
3337 {
3338   if (!pthread_mutexattr::is_good_object (attr))
3339     return EINVAL;
3340   return ENOSYS;
3341 }
3342
3343 /* Win32 doesn't support mutex priorities */
3344 extern "C" int
3345 pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr,
3346                                     int prioceiling)
3347 {
3348   if (!pthread_mutexattr::is_good_object (attr))
3349     return EINVAL;
3350   return ENOSYS;
3351 }
3352
3353 extern "C" int
3354 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,
3355                                     int *prioceiling)
3356 {
3357   if (!pthread_mutexattr::is_good_object (attr))
3358     return EINVAL;
3359   return ENOSYS;
3360 }
3361
3362 extern "C" int
3363 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
3364 {
3365   if (!pthread_mutexattr::is_good_object (attr))
3366     return EINVAL;
3367   /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3368    *functionality
3369    */
3370   if (pshared != PTHREAD_PROCESS_PRIVATE)
3371     return EINVAL;
3372   (*attr)->pshared = pshared;
3373   return 0;
3374 }
3375
3376 /* see pthread_mutex_gettype */
3377 extern "C" int
3378 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
3379 {
3380   if (!pthread_mutexattr::is_good_object (attr))
3381     return EINVAL;
3382
3383   switch (type)
3384     {
3385     case PTHREAD_MUTEX_ERRORCHECK:
3386     case PTHREAD_MUTEX_RECURSIVE:
3387     case PTHREAD_MUTEX_NORMAL:
3388       (*attr)->mutextype = type;
3389       break;
3390     default:
3391       return EINVAL;
3392     }
3393
3394   return 0;
3395 }
3396
3397 /* Semaphores */
3398
3399 List<semaphore> semaphore::semaphores;
3400
3401 semaphore::semaphore (int pshared, unsigned int value)
3402 : verifyable_object (SEM_MAGIC),
3403   shared (pshared),
3404   currentvalue (value),
3405   fd (-1),
3406   hash (0ULL),
3407   sem (NULL)
3408 {
3409   SECURITY_ATTRIBUTES sa = (pshared != PTHREAD_PROCESS_PRIVATE)
3410                            ? sec_all : sec_none_nih;
3411   this->win32_obj_id = ::CreateSemaphore (&sa, value, LONG_MAX, NULL);
3412   if (!this->win32_obj_id)
3413     magic = 0;
3414
3415   semaphores.insert (this);
3416 }
3417
3418 semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd,
3419                       sem_t *ssem, int oflag, mode_t mode, unsigned int value)
3420 : verifyable_object (SEM_MAGIC),
3421   shared (PTHREAD_PROCESS_SHARED),
3422   currentvalue (value),         /* Unused for named semaphores. */
3423   fd (sfd),
3424   hash (shash),
3425   luid (sluid),
3426   sem (ssem)
3427 {
3428   char name[MAX_PATH];
3429
3430   __small_sprintf (name, "semaphore/%016X%08x%08x",
3431                    hash, luid.HighPart, luid.LowPart);
3432   this->win32_obj_id = ::CreateSemaphore (&sec_all, value, LONG_MAX, name);
3433   if (!this->win32_obj_id)
3434     magic = 0;
3435   if (GetLastError () == ERROR_ALREADY_EXISTS && (oflag & O_EXCL))
3436     {
3437       __seterrno ();
3438       CloseHandle (this->win32_obj_id);
3439       magic = 0;
3440     }
3441
3442   semaphores.insert (this);
3443 }
3444
3445 semaphore::~semaphore ()
3446 {
3447   if (win32_obj_id)
3448     CloseHandle (win32_obj_id);
3449
3450   semaphores.remove (this);
3451 }
3452
3453 void
3454 semaphore::_post ()
3455 {
3456   if (ReleaseSemaphore (win32_obj_id, 1, &currentvalue))
3457     currentvalue++;
3458 }
3459
3460 int
3461 semaphore::_getvalue (int *sval)
3462 {
3463   long val;
3464
3465   switch (WaitForSingleObject (win32_obj_id, 0))
3466     {
3467       case WAIT_OBJECT_0:
3468         ReleaseSemaphore (win32_obj_id, 1, &val);
3469         *sval = val + 1;
3470         break;
3471       case WAIT_TIMEOUT:
3472         *sval = 0;
3473         break;
3474       default:
3475         set_errno (EAGAIN);
3476         return -1;
3477     }
3478   return 0;
3479 }
3480
3481 int
3482 semaphore::_trywait ()
3483 {
3484   /* FIXME: signals should be able to interrupt semaphores...
3485     We probably need WaitForMultipleObjects here.  */
3486   if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
3487     {
3488       set_errno (EAGAIN);
3489       return -1;
3490     }
3491   currentvalue--;
3492   return 0;
3493 }
3494
3495 int
3496 semaphore::_timedwait (const struct timespec *abstime)
3497 {
3498   LARGE_INTEGER timeout;
3499
3500   myfault efault;
3501   if (efault.faulted ())
3502     {
3503       /* According to SUSv3, abstime need not be checked for validity,
3504          if the semaphore can be locked immediately. */
3505       if (!_trywait ())
3506         return 0;
3507       set_errno (EINVAL);
3508       return -1;
3509     }
3510
3511   timeout.QuadPart = abstime->tv_sec * NSPERSEC
3512                      + (abstime->tv_nsec + 99) / 100 + FACTOR;
3513
3514   switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
3515     {
3516     case WAIT_OBJECT_0:
3517       currentvalue--;
3518       break;
3519     case WAIT_SIGNALED:
3520       set_errno (EINTR);
3521       return -1;
3522     case WAIT_TIMEOUT:
3523       set_errno (ETIMEDOUT);
3524       return -1;
3525     default:
3526       pthread_printf ("cancelable_wait failed. %E");
3527       __seterrno ();
3528       return -1;
3529     }
3530   return 0;
3531 }
3532
3533 int
3534 semaphore::_wait ()
3535 {
3536   switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
3537     {
3538     case WAIT_OBJECT_0:
3539       currentvalue--;
3540       break;
3541     case WAIT_SIGNALED:
3542       set_errno (EINTR);
3543       return -1;
3544     default:
3545       pthread_printf ("cancelable_wait failed. %E");
3546       break;
3547     }
3548   return 0;
3549 }
3550
3551 void
3552 semaphore::_fixup_after_fork ()
3553 {
3554   if (shared == PTHREAD_PROCESS_PRIVATE)
3555     {
3556       pthread_printf ("sem %x", this);
3557       /* FIXME: duplicate code here and in the constructor. */
3558       this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue,
3559                                               LONG_MAX, NULL);
3560       if (!win32_obj_id)
3561         api_fatal ("failed to create new win32 semaphore, error %d");
3562     }
3563 }
3564
3565 void
3566 semaphore::_terminate ()
3567 {
3568   int _sem_close (sem_t *, bool);
3569
3570   if (sem)
3571     _sem_close (sem, false);
3572 }
3573
3574 /* static members */
3575
3576 int
3577 semaphore::init (sem_t *sem, int pshared, unsigned int value)
3578 {
3579   /*
3580      We can't tell the difference between reinitialising an
3581      existing semaphore and initialising a semaphore who's
3582      contents happen to be a valid pointer
3583    */
3584   if (is_good_object (sem))
3585     {
3586       paranoid_printf ("potential attempt to reinitialise a semaphore");
3587     }
3588
3589   if (value > SEM_VALUE_MAX)
3590     {
3591       set_errno(EINVAL);
3592       return -1;
3593     }
3594
3595   *sem = new semaphore (pshared, value);
3596
3597   if (!is_good_object (sem))
3598     {
3599       delete (*sem);
3600       *sem = NULL;
3601       set_errno(EAGAIN);
3602       return -1;
3603     }
3604   return 0;
3605 }
3606
3607 int
3608 semaphore::destroy (sem_t *sem)
3609 {
3610   if (!is_good_object (sem))
3611     {
3612       set_errno(EINVAL);
3613       return -1;
3614     }
3615
3616   /* It's invalid to destroy a semaphore not opened with sem_init. */
3617   if ((*sem)->fd != -1)
3618     {
3619       set_errno(EINVAL);
3620       return -1;
3621     }
3622
3623   /* FIXME - new feature - test for busy against threads... */
3624
3625   delete (*sem);
3626   *sem = NULL;
3627   return 0;
3628 }
3629
3630 int
3631 semaphore::close (sem_t *sem)
3632 {
3633   if (!is_good_object (sem))
3634     {
3635       set_errno(EINVAL);
3636       return -1;
3637     }
3638
3639   /* It's invalid to close a semaphore not opened with sem_open. */
3640   if ((*sem)->fd == -1)
3641     {
3642       set_errno(EINVAL);
3643       return -1;
3644     }
3645
3646   delete (*sem);
3647   delete sem;
3648   return 0;
3649 }
3650
3651 sem_t *
3652 semaphore::open (unsigned long long hash, LUID luid, int fd, int oflag,
3653                  mode_t mode, unsigned int value, bool &wasopen)
3654 {
3655   if (value > SEM_VALUE_MAX)
3656     {
3657       set_errno (EINVAL);
3658       return NULL;
3659     }
3660
3661   /* sem_open is supposed to return the same pointer, if the same named
3662      semaphore is opened multiple times in the same process, as long as
3663      the semaphore hasn't been closed or unlinked in the meantime. */
3664   semaphores.mx.lock ();
3665   for (semaphore *sema = semaphores.head; sema; sema = sema->next)
3666     if (sema->fd >= 0 && sema->hash == hash
3667         && sema->luid.HighPart == luid.HighPart
3668         && sema->luid.LowPart == sema->luid.LowPart)
3669       {
3670         wasopen = true;
3671         semaphores.mx.unlock ();
3672         return sema->sem;
3673       }
3674   semaphores.mx.unlock ();
3675
3676   wasopen = false;
3677   sem_t *sem = new sem_t;
3678   if (!sem)
3679     {
3680       set_errno (ENOMEM);
3681       return NULL;
3682     }
3683
3684   *sem = new semaphore (hash, luid, fd, sem, oflag, mode, value);
3685
3686   if (!is_good_object (sem))
3687     {
3688       delete *sem;
3689       delete sem;
3690       return NULL;
3691     }
3692   return sem;
3693 }
3694
3695 int
3696 semaphore::wait (sem_t *sem)
3697 {
3698   pthread_testcancel ();
3699
3700   if (!is_good_object (sem))
3701     {
3702       set_errno (EINVAL);
3703       return -1;
3704     }
3705
3706   return (*sem)->_wait ();
3707 }
3708
3709 int
3710 semaphore::trywait (sem_t *sem)
3711 {
3712   if (!is_good_object (sem))
3713     {
3714       set_errno (EINVAL);
3715       return -1;
3716     }
3717
3718   return (*sem)->_trywait ();
3719 }
3720
3721 int
3722 semaphore::timedwait (sem_t *sem, const struct timespec *abstime)
3723 {
3724   if (!is_good_object (sem))
3725     {
3726       set_errno (EINVAL);
3727       return -1;
3728     }
3729
3730   return (*sem)->_timedwait (abstime);
3731 }
3732
3733 int
3734 semaphore::post (sem_t *sem)
3735 {
3736   if (!is_good_object (sem))
3737     {
3738       set_errno (EINVAL);
3739       return -1;
3740     }
3741
3742   (*sem)->_post ();
3743   return 0;
3744 }
3745
3746 int
3747 semaphore::getvalue (sem_t *sem, int *sval)
3748 {
3749   myfault efault;
3750   if (efault.faulted () || !is_good_object (sem))
3751     {
3752       set_errno (EINVAL);
3753       return -1;
3754     }
3755
3756   return (*sem)->_getvalue (sval);
3757 }
3758
3759 int
3760 semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
3761                         LUID *sluid, unsigned int *sval)
3762 {
3763   myfault efault;
3764   if (efault.faulted () || !is_good_object (sem))
3765     {
3766       set_errno (EINVAL);
3767       return -1;
3768     }
3769   if ((*sfd = (*sem)->fd) < 0)
3770     {
3771       set_errno (EINVAL);
3772       return -1;
3773     }
3774   *shash = (*sem)->hash;
3775   *sluid = (*sem)->luid;
3776   /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3777      the sem_getvalue gets a pointer to int to return the value.  Go figure! */
3778   return (*sem)->_getvalue ((int *)sval);
3779 }
3780
3781 /* pthread_null */
3782 pthread *
3783 pthread_null::get_null_pthread ()
3784 {
3785   /* because of weird entry points */
3786   _instance.magic = 0;
3787   return &_instance;
3788 }
3789
3790 pthread_null::pthread_null ()
3791 {
3792   attr.joinable = PTHREAD_CREATE_DETACHED;
3793   /* Mark ourselves as invalid */
3794   magic = 0;
3795 }
3796
3797 pthread_null::~pthread_null ()
3798 {
3799 }
3800
3801 bool
3802 pthread_null::create (void *(*)(void *), pthread_attr *, void *)
3803 {
3804   return true;
3805 }
3806
3807 void
3808 pthread_null::exit (void *value_ptr)
3809 {
3810   _my_tls.remove (INFINITE);
3811   ExitThread (0);
3812 }
3813
3814 int
3815 pthread_null::cancel ()
3816 {
3817   return 0;
3818 }
3819
3820 void
3821 pthread_null::testcancel ()
3822 {
3823 }
3824
3825 int
3826 pthread_null::setcancelstate (int state, int *oldstate)
3827 {
3828   return EINVAL;
3829 }
3830
3831 int
3832 pthread_null::setcanceltype (int type, int *oldtype)
3833 {
3834   return EINVAL;
3835 }
3836
3837 void
3838 pthread_null::push_cleanup_handler (__pthread_cleanup_handler *handler)
3839 {
3840 }
3841
3842 void
3843 pthread_null::pop_cleanup_handler (int const execute)
3844 {
3845 }
3846
3847 unsigned long
3848 pthread_null::getsequence_np ()
3849 {
3850   return 0;
3851 }
3852
3853 pthread_null pthread_null::_instance;