OSDN Git Service

* select.cc (select_stuff::wait): Temporarily disallow APCS.
[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   return handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
3091 }
3092
3093 /* ID */
3094
3095 extern "C" int
3096 pthread_equal (pthread_t t1, pthread_t t2)
3097 {
3098   return pthread::equal (t1, t2);
3099 }
3100
3101 /* Mutexes  */
3102
3103 int
3104 pthread_mutex::init (pthread_mutex_t *mutex,
3105                      const pthread_mutexattr_t *attr,
3106                      const pthread_mutex_t initializer)
3107 {
3108   if (attr && !pthread_mutexattr::is_good_object (attr))
3109     return EINVAL;
3110
3111   mutex_initialization_lock.lock ();
3112   if (initializer == NULL || pthread_mutex::is_initializer (mutex))
3113     {
3114       pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
3115       if (!is_good_object (&new_mutex))
3116         {
3117           delete new_mutex;
3118           mutex_initialization_lock.unlock ();
3119           return EAGAIN;
3120         }
3121
3122       if (!attr && initializer)
3123         {
3124           if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
3125             new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
3126           else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
3127             new_mutex->type = PTHREAD_MUTEX_NORMAL;
3128           else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
3129             new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
3130         }
3131
3132       myfault efault;
3133       if (efault.faulted ())
3134         {
3135           delete new_mutex;
3136           mutex_initialization_lock.unlock ();
3137           return EINVAL;
3138         }
3139
3140       *mutex = new_mutex;
3141     }
3142   mutex_initialization_lock.unlock ();
3143   pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
3144
3145   return 0;
3146 }
3147
3148 extern "C" int
3149 pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
3150                                 int *prioceiling)
3151 {
3152   /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
3153      mutex priorities.
3154
3155      We can support mutex priorities in the future though:
3156      Store a priority with each mutex.
3157      When the mutex is optained, set the thread priority as appropriate
3158      When the mutex is released, reset the thread priority.  */
3159   return ENOSYS;
3160 }
3161
3162 extern "C" int
3163 pthread_mutex_lock (pthread_mutex_t *mutex)
3164 {
3165   if (pthread_mutex::is_initializer (mutex))
3166     pthread_mutex::init (mutex, NULL, *mutex);
3167   if (!pthread_mutex::is_good_object (mutex))
3168     return EINVAL;
3169   return (*mutex)->lock ();
3170 }
3171
3172 extern "C" int
3173 pthread_mutex_trylock (pthread_mutex_t *mutex)
3174 {
3175   if (pthread_mutex::is_initializer (mutex))
3176     pthread_mutex::init (mutex, NULL, *mutex);
3177   if (!pthread_mutex::is_good_object (mutex))
3178     return EINVAL;
3179   return (*mutex)->trylock ();
3180 }
3181
3182 extern "C" int
3183 pthread_mutex_unlock (pthread_mutex_t *mutex)
3184 {
3185   if (pthread_mutex::is_initializer (mutex))
3186     return EPERM;
3187   if (!pthread_mutex::is_good_object (mutex))
3188     return EINVAL;
3189   return (*mutex)->unlock ();
3190 }
3191
3192 extern "C" int
3193 pthread_mutex_destroy (pthread_mutex_t *mutex)
3194 {
3195   int rv;
3196
3197   if (pthread_mutex::is_initializer (mutex))
3198     return 0;
3199   if (!pthread_mutex::is_good_object (mutex))
3200     return EINVAL;
3201
3202   rv = (*mutex)->destroy ();
3203   if (rv)
3204     return rv;
3205
3206   *mutex = NULL;
3207   return 0;
3208 }
3209
3210 extern "C" int
3211 pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
3212                                 int *old_ceiling)
3213 {
3214   return ENOSYS;
3215 }
3216
3217 /* Spinlocks  */
3218
3219 int
3220 pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
3221 {
3222   pthread_spinlock_t new_spinlock = new pthread_spinlock (pshared);
3223   if (!is_good_object (&new_spinlock))
3224     {
3225       delete new_spinlock;
3226       return EAGAIN;
3227     }
3228
3229   myfault efault;
3230   if (efault.faulted ())
3231     {
3232       delete new_spinlock;
3233       return EINVAL;
3234     }
3235
3236   *spinlock = new_spinlock;
3237   pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
3238
3239   return 0;
3240 }
3241
3242 extern "C" int
3243 pthread_spin_lock (pthread_spinlock_t *spinlock)
3244 {
3245   if (!pthread_spinlock::is_good_object (spinlock))
3246     return EINVAL;
3247   return (*spinlock)->lock ();
3248 }
3249
3250 extern "C" int
3251 pthread_spin_trylock (pthread_spinlock_t *spinlock)
3252 {
3253   if (!pthread_spinlock::is_good_object (spinlock))
3254     return EINVAL;
3255   return (*spinlock)->trylock ();
3256 }
3257
3258 extern "C" int
3259 pthread_spin_unlock (pthread_spinlock_t *spinlock)
3260 {
3261   if (!pthread_spinlock::is_good_object (spinlock))
3262     return EINVAL;
3263   return (*spinlock)->unlock ();
3264 }
3265
3266 extern "C" int
3267 pthread_spin_destroy (pthread_spinlock_t *spinlock)
3268 {
3269   if (!pthread_spinlock::is_good_object (spinlock))
3270     return EINVAL;
3271   return (*spinlock)->destroy ();
3272 }
3273
3274 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3275    for more detail */
3276 extern "C" int
3277 pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr,
3278                                  int *protocol)
3279 {
3280   if (!pthread_mutexattr::is_good_object (attr))
3281     return EINVAL;
3282   return ENOSYS;
3283 }
3284
3285 extern "C" int
3286 pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr,
3287                                 int *pshared)
3288 {
3289   if (!pthread_mutexattr::is_good_object (attr))
3290     return EINVAL;
3291   *pshared = (*attr)->pshared;
3292   return 0;
3293 }
3294
3295 extern "C" int
3296 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)
3297 {
3298   if (!pthread_mutexattr::is_good_object (attr))
3299     return EINVAL;
3300   *type = (*attr)->mutextype;
3301   return 0;
3302 }
3303
3304 /* FIXME: write and test process shared mutex's.  */
3305 extern "C" int
3306 pthread_mutexattr_init (pthread_mutexattr_t *attr)
3307 {
3308   if (pthread_mutexattr::is_good_object (attr))
3309     return EBUSY;
3310
3311   *attr = new pthread_mutexattr ();
3312   if (!pthread_mutexattr::is_good_object (attr))
3313     {
3314       delete (*attr);
3315       *attr = NULL;
3316       return ENOMEM;
3317     }
3318   return 0;
3319 }
3320
3321 extern "C" int
3322 pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
3323 {
3324   if (!pthread_mutexattr::is_good_object (attr))
3325     return EINVAL;
3326   delete (*attr);
3327   *attr = NULL;
3328   return 0;
3329 }
3330
3331
3332 /* Win32 doesn't support mutex priorities */
3333 extern "C" int
3334 pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol)
3335 {
3336   if (!pthread_mutexattr::is_good_object (attr))
3337     return EINVAL;
3338   return ENOSYS;
3339 }
3340
3341 /* Win32 doesn't support mutex priorities */
3342 extern "C" int
3343 pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr,
3344                                     int prioceiling)
3345 {
3346   if (!pthread_mutexattr::is_good_object (attr))
3347     return EINVAL;
3348   return ENOSYS;
3349 }
3350
3351 extern "C" int
3352 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,
3353                                     int *prioceiling)
3354 {
3355   if (!pthread_mutexattr::is_good_object (attr))
3356     return EINVAL;
3357   return ENOSYS;
3358 }
3359
3360 extern "C" int
3361 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
3362 {
3363   if (!pthread_mutexattr::is_good_object (attr))
3364     return EINVAL;
3365   /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3366    *functionality
3367    */
3368   if (pshared != PTHREAD_PROCESS_PRIVATE)
3369     return EINVAL;
3370   (*attr)->pshared = pshared;
3371   return 0;
3372 }
3373
3374 /* see pthread_mutex_gettype */
3375 extern "C" int
3376 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
3377 {
3378   if (!pthread_mutexattr::is_good_object (attr))
3379     return EINVAL;
3380
3381   switch (type)
3382     {
3383     case PTHREAD_MUTEX_ERRORCHECK:
3384     case PTHREAD_MUTEX_RECURSIVE:
3385     case PTHREAD_MUTEX_NORMAL:
3386       (*attr)->mutextype = type;
3387       break;
3388     default:
3389       return EINVAL;
3390     }
3391
3392   return 0;
3393 }
3394
3395 /* Semaphores */
3396
3397 List<semaphore> semaphore::semaphores;
3398
3399 semaphore::semaphore (int pshared, unsigned int value)
3400 : verifyable_object (SEM_MAGIC),
3401   shared (pshared),
3402   currentvalue (value),
3403   fd (-1),
3404   hash (0ULL),
3405   sem (NULL)
3406 {
3407   SECURITY_ATTRIBUTES sa = (pshared != PTHREAD_PROCESS_PRIVATE)
3408                            ? sec_all : sec_none_nih;
3409   this->win32_obj_id = ::CreateSemaphore (&sa, value, LONG_MAX, NULL);
3410   if (!this->win32_obj_id)
3411     magic = 0;
3412
3413   semaphores.insert (this);
3414 }
3415
3416 semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd,
3417                       sem_t *ssem, int oflag, mode_t mode, unsigned int value)
3418 : verifyable_object (SEM_MAGIC),
3419   shared (PTHREAD_PROCESS_SHARED),
3420   currentvalue (value),         /* Unused for named semaphores. */
3421   fd (sfd),
3422   hash (shash),
3423   luid (sluid),
3424   sem (ssem)
3425 {
3426   char name[MAX_PATH];
3427
3428   __small_sprintf (name, "semaphore/%016X%08x%08x",
3429                    hash, luid.HighPart, luid.LowPart);
3430   this->win32_obj_id = ::CreateSemaphore (&sec_all, value, LONG_MAX, name);
3431   if (!this->win32_obj_id)
3432     magic = 0;
3433   if (GetLastError () == ERROR_ALREADY_EXISTS && (oflag & O_EXCL))
3434     {
3435       __seterrno ();
3436       CloseHandle (this->win32_obj_id);
3437       magic = 0;
3438     }
3439
3440   semaphores.insert (this);
3441 }
3442
3443 semaphore::~semaphore ()
3444 {
3445   if (win32_obj_id)
3446     CloseHandle (win32_obj_id);
3447
3448   semaphores.remove (this);
3449 }
3450
3451 void
3452 semaphore::_post ()
3453 {
3454   if (ReleaseSemaphore (win32_obj_id, 1, &currentvalue))
3455     currentvalue++;
3456 }
3457
3458 int
3459 semaphore::_getvalue (int *sval)
3460 {
3461   long val;
3462
3463   switch (WaitForSingleObject (win32_obj_id, 0))
3464     {
3465       case WAIT_OBJECT_0:
3466         ReleaseSemaphore (win32_obj_id, 1, &val);
3467         *sval = val + 1;
3468         break;
3469       case WAIT_TIMEOUT:
3470         *sval = 0;
3471         break;
3472       default:
3473         set_errno (EAGAIN);
3474         return -1;
3475     }
3476   return 0;
3477 }
3478
3479 int
3480 semaphore::_trywait ()
3481 {
3482   /* FIXME: signals should be able to interrupt semaphores...
3483     We probably need WaitForMultipleObjects here.  */
3484   if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
3485     {
3486       set_errno (EAGAIN);
3487       return -1;
3488     }
3489   currentvalue--;
3490   return 0;
3491 }
3492
3493 int
3494 semaphore::_timedwait (const struct timespec *abstime)
3495 {
3496   LARGE_INTEGER timeout;
3497
3498   myfault efault;
3499   if (efault.faulted ())
3500     {
3501       /* According to SUSv3, abstime need not be checked for validity,
3502          if the semaphore can be locked immediately. */
3503       if (!_trywait ())
3504         return 0;
3505       set_errno (EINVAL);
3506       return -1;
3507     }
3508
3509   timeout.QuadPart = abstime->tv_sec * NSPERSEC
3510                      + (abstime->tv_nsec + 99) / 100 + FACTOR;
3511
3512   switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
3513     {
3514     case WAIT_OBJECT_0:
3515       currentvalue--;
3516       break;
3517     case WAIT_SIGNALED:
3518       set_errno (EINTR);
3519       return -1;
3520     case WAIT_TIMEOUT:
3521       set_errno (ETIMEDOUT);
3522       return -1;
3523     default:
3524       pthread_printf ("cancelable_wait failed. %E");
3525       __seterrno ();
3526       return -1;
3527     }
3528   return 0;
3529 }
3530
3531 int
3532 semaphore::_wait ()
3533 {
3534   switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
3535     {
3536     case WAIT_OBJECT_0:
3537       currentvalue--;
3538       break;
3539     case WAIT_SIGNALED:
3540       set_errno (EINTR);
3541       return -1;
3542     default:
3543       pthread_printf ("cancelable_wait failed. %E");
3544       break;
3545     }
3546   return 0;
3547 }
3548
3549 void
3550 semaphore::_fixup_after_fork ()
3551 {
3552   if (shared == PTHREAD_PROCESS_PRIVATE)
3553     {
3554       pthread_printf ("sem %x", this);
3555       /* FIXME: duplicate code here and in the constructor. */
3556       this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue,
3557                                               LONG_MAX, NULL);
3558       if (!win32_obj_id)
3559         api_fatal ("failed to create new win32 semaphore, error %d");
3560     }
3561 }
3562
3563 void
3564 semaphore::_terminate ()
3565 {
3566   int _sem_close (sem_t *, bool);
3567
3568   if (sem)
3569     _sem_close (sem, false);
3570 }
3571
3572 /* static members */
3573
3574 int
3575 semaphore::init (sem_t *sem, int pshared, unsigned int value)
3576 {
3577   /*
3578      We can't tell the difference between reinitialising an
3579      existing semaphore and initialising a semaphore who's
3580      contents happen to be a valid pointer
3581    */
3582   if (is_good_object (sem))
3583     {
3584       paranoid_printf ("potential attempt to reinitialise a semaphore");
3585     }
3586
3587   if (value > SEM_VALUE_MAX)
3588     {
3589       set_errno(EINVAL);
3590       return -1;
3591     }
3592
3593   *sem = new semaphore (pshared, value);
3594
3595   if (!is_good_object (sem))
3596     {
3597       delete (*sem);
3598       *sem = NULL;
3599       set_errno(EAGAIN);
3600       return -1;
3601     }
3602   return 0;
3603 }
3604
3605 int
3606 semaphore::destroy (sem_t *sem)
3607 {
3608   if (!is_good_object (sem))
3609     {
3610       set_errno(EINVAL);
3611       return -1;
3612     }
3613
3614   /* It's invalid to destroy a semaphore not opened with sem_init. */
3615   if ((*sem)->fd != -1)
3616     {
3617       set_errno(EINVAL);
3618       return -1;
3619     }
3620
3621   /* FIXME - new feature - test for busy against threads... */
3622
3623   delete (*sem);
3624   *sem = NULL;
3625   return 0;
3626 }
3627
3628 int
3629 semaphore::close (sem_t *sem)
3630 {
3631   if (!is_good_object (sem))
3632     {
3633       set_errno(EINVAL);
3634       return -1;
3635     }
3636
3637   /* It's invalid to close a semaphore not opened with sem_open. */
3638   if ((*sem)->fd == -1)
3639     {
3640       set_errno(EINVAL);
3641       return -1;
3642     }
3643
3644   delete (*sem);
3645   delete sem;
3646   return 0;
3647 }
3648
3649 sem_t *
3650 semaphore::open (unsigned long long hash, LUID luid, int fd, int oflag,
3651                  mode_t mode, unsigned int value, bool &wasopen)
3652 {
3653   if (value > SEM_VALUE_MAX)
3654     {
3655       set_errno (EINVAL);
3656       return NULL;
3657     }
3658
3659   /* sem_open is supposed to return the same pointer, if the same named
3660      semaphore is opened multiple times in the same process, as long as
3661      the semaphore hasn't been closed or unlinked in the meantime. */
3662   semaphores.mx.lock ();
3663   for (semaphore *sema = semaphores.head; sema; sema = sema->next)
3664     if (sema->fd >= 0 && sema->hash == hash
3665         && sema->luid.HighPart == luid.HighPart
3666         && sema->luid.LowPart == sema->luid.LowPart)
3667       {
3668         wasopen = true;
3669         semaphores.mx.unlock ();
3670         return sema->sem;
3671       }
3672   semaphores.mx.unlock ();
3673
3674   wasopen = false;
3675   sem_t *sem = new sem_t;
3676   if (!sem)
3677     {
3678       set_errno (ENOMEM);
3679       return NULL;
3680     }
3681
3682   *sem = new semaphore (hash, luid, fd, sem, oflag, mode, value);
3683
3684   if (!is_good_object (sem))
3685     {
3686       delete *sem;
3687       delete sem;
3688       return NULL;
3689     }
3690   return sem;
3691 }
3692
3693 int
3694 semaphore::wait (sem_t *sem)
3695 {
3696   pthread_testcancel ();
3697
3698   if (!is_good_object (sem))
3699     {
3700       set_errno (EINVAL);
3701       return -1;
3702     }
3703
3704   return (*sem)->_wait ();
3705 }
3706
3707 int
3708 semaphore::trywait (sem_t *sem)
3709 {
3710   if (!is_good_object (sem))
3711     {
3712       set_errno (EINVAL);
3713       return -1;
3714     }
3715
3716   return (*sem)->_trywait ();
3717 }
3718
3719 int
3720 semaphore::timedwait (sem_t *sem, const struct timespec *abstime)
3721 {
3722   if (!is_good_object (sem))
3723     {
3724       set_errno (EINVAL);
3725       return -1;
3726     }
3727
3728   return (*sem)->_timedwait (abstime);
3729 }
3730
3731 int
3732 semaphore::post (sem_t *sem)
3733 {
3734   if (!is_good_object (sem))
3735     {
3736       set_errno (EINVAL);
3737       return -1;
3738     }
3739
3740   (*sem)->_post ();
3741   return 0;
3742 }
3743
3744 int
3745 semaphore::getvalue (sem_t *sem, int *sval)
3746 {
3747   myfault efault;
3748   if (efault.faulted () || !is_good_object (sem))
3749     {
3750       set_errno (EINVAL);
3751       return -1;
3752     }
3753
3754   return (*sem)->_getvalue (sval);
3755 }
3756
3757 int
3758 semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
3759                         LUID *sluid, unsigned int *sval)
3760 {
3761   myfault efault;
3762   if (efault.faulted () || !is_good_object (sem))
3763     {
3764       set_errno (EINVAL);
3765       return -1;
3766     }
3767   if ((*sfd = (*sem)->fd) < 0)
3768     {
3769       set_errno (EINVAL);
3770       return -1;
3771     }
3772   *shash = (*sem)->hash;
3773   *sluid = (*sem)->luid;
3774   /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3775      the sem_getvalue gets a pointer to int to return the value.  Go figure! */
3776   return (*sem)->_getvalue ((int *)sval);
3777 }
3778
3779 /* pthread_null */
3780 pthread *
3781 pthread_null::get_null_pthread ()
3782 {
3783   /* because of weird entry points */
3784   _instance.magic = 0;
3785   return &_instance;
3786 }
3787
3788 pthread_null::pthread_null ()
3789 {
3790   attr.joinable = PTHREAD_CREATE_DETACHED;
3791   /* Mark ourselves as invalid */
3792   magic = 0;
3793 }
3794
3795 pthread_null::~pthread_null ()
3796 {
3797 }
3798
3799 bool
3800 pthread_null::create (void *(*)(void *), pthread_attr *, void *)
3801 {
3802   return true;
3803 }
3804
3805 void
3806 pthread_null::exit (void *value_ptr)
3807 {
3808   _my_tls.remove (INFINITE);
3809   ExitThread (0);
3810 }
3811
3812 int
3813 pthread_null::cancel ()
3814 {
3815   return 0;
3816 }
3817
3818 void
3819 pthread_null::testcancel ()
3820 {
3821 }
3822
3823 int
3824 pthread_null::setcancelstate (int state, int *oldstate)
3825 {
3826   return EINVAL;
3827 }
3828
3829 int
3830 pthread_null::setcanceltype (int type, int *oldtype)
3831 {
3832   return EINVAL;
3833 }
3834
3835 void
3836 pthread_null::push_cleanup_handler (__pthread_cleanup_handler *handler)
3837 {
3838 }
3839
3840 void
3841 pthread_null::pop_cleanup_handler (int const execute)
3842 {
3843 }
3844
3845 unsigned long
3846 pthread_null::getsequence_np ()
3847 {
3848   return 0;
3849 }
3850
3851 pthread_null pthread_null::_instance;