OSDN Git Service

2012-01-06 Chris Sutcliffe <ir0nh34d@users.sf.net>
[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     o pthread_rwlock_timedrdlock ()
814     o 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 status;
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   status = NtQueryInformationThread (thread->win32_obj_id,
2533                                      ThreadBasicInformation,
2534                                      tbi, sizeof_tbi, NULL);
2535   if (NT_SUCCESS (status))
2536     {
2537       PNT_TIB tib = tbi->TebBaseAddress;
2538       (*attr)->stackaddr = tib->StackBase;
2539       /* stack grows downwards on x86 systems */
2540       (*attr)->stacksize = (uintptr_t) tib->StackBase
2541                            - (uintptr_t) tib->StackLimit;
2542     }
2543   else
2544     {
2545       debug_printf ("NtQueryInformationThread(ThreadBasicInformation), "
2546                     "status %p", status);
2547       (*attr)->stackaddr = thread->attr.stackaddr;
2548       (*attr)->stacksize = thread->attr.stacksize;
2549     }
2550
2551   return 0;
2552 }
2553
2554 /* provided for source level compatability.
2555    See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2556 */
2557 extern "C" int
2558 pthread_getconcurrency ()
2559 {
2560   return MT_INTERFACE->concurrency;
2561 }
2562
2563 extern "C" int
2564 pthread_getcpuclockid (pthread_t thread, clockid_t *clk_id)
2565 {
2566   if (!pthread::is_good_object (&thread))
2567     return (ESRCH);
2568   *clk_id = (clockid_t) THREADID_TO_CLOCKID (thread->getsequence_np ());
2569   return 0;
2570 }
2571
2572 /* keep this in sync with sched.cc */
2573 extern "C" int
2574 pthread_getschedparam (pthread_t thread, int *policy,
2575                          struct sched_param *param)
2576 {
2577   if (!pthread::is_good_object (&thread))
2578     return ESRCH;
2579   *policy = SCHED_FIFO;
2580   /* we don't return the current effective priority, we return the current
2581      requested priority */
2582   *param = thread->attr.schedparam;
2583   return 0;
2584 }
2585
2586 /* Thread Specific Data */
2587 extern "C" int
2588 pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
2589 {
2590   *key = new pthread_key (destructor);
2591
2592   if (!pthread_key::is_good_object (key))
2593     {
2594       delete (*key);
2595       *key = NULL;
2596       return EAGAIN;
2597     }
2598   return 0;
2599 }
2600
2601 extern "C" int
2602 pthread_key_delete (pthread_key_t key)
2603 {
2604   if (!pthread_key::is_good_object (&key))
2605     return EINVAL;
2606
2607   delete (key);
2608   return 0;
2609 }
2610
2611 /* provided for source level compatability.  See
2612 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2613 */
2614 extern "C" int
2615 pthread_setconcurrency (int new_level)
2616 {
2617   if (new_level < 0)
2618     return EINVAL;
2619   MT_INTERFACE->concurrency = new_level;
2620   return 0;
2621 }
2622
2623 /* keep syncronised with sched.cc */
2624 extern "C" int
2625 pthread_setschedparam (pthread_t thread, int policy,
2626                          const struct sched_param *param)
2627 {
2628   if (!pthread::is_good_object (&thread))
2629     return ESRCH;
2630   if (policy != SCHED_FIFO)
2631     return ENOTSUP;
2632   if (!param)
2633     return EINVAL;
2634   int rv =
2635     sched_set_thread_priority (thread->win32_obj_id, param->sched_priority);
2636   if (!rv)
2637     thread->attr.schedparam.sched_priority = param->sched_priority;
2638   return rv;
2639 }
2640
2641 extern "C" int
2642 pthread_setschedprio (pthread_t thread, int priority)
2643 {
2644   if (!pthread::is_good_object (&thread))
2645     return ESRCH;
2646   int rv =
2647     sched_set_thread_priority (thread->win32_obj_id, priority);
2648   if (!rv)
2649     thread->attr.schedparam.sched_priority = priority;
2650   return rv;
2651 }
2652
2653 extern "C" int
2654 pthread_setspecific (pthread_key_t key, const void *value)
2655 {
2656   if (!pthread_key::is_good_object (&key))
2657     return EINVAL;
2658   (key)->set (value);
2659   return 0;
2660 }
2661
2662 extern "C" void *
2663 pthread_getspecific (pthread_key_t key)
2664 {
2665   if (!pthread_key::is_good_object (&key))
2666     return NULL;
2667
2668   return (key)->get ();
2669
2670 }
2671
2672 extern "C" int
2673 pthread_cond_destroy (pthread_cond_t *cond)
2674 {
2675   if (pthread_cond::is_initializer (cond))
2676     return 0;
2677   if (!pthread_cond::is_good_object (cond))
2678     return EINVAL;
2679
2680   /* reads are atomic */
2681   if ((*cond)->waiting)
2682     return EBUSY;
2683
2684   delete (*cond);
2685   *cond = NULL;
2686
2687   return 0;
2688 }
2689
2690 int
2691 pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
2692 {
2693   pthread_cond_t new_cond;
2694
2695   if (attr && !pthread_condattr::is_good_object (attr))
2696     return EINVAL;
2697
2698   cond_initialization_lock.lock ();
2699
2700   new_cond = new pthread_cond (attr ? (*attr) : NULL);
2701   if (!is_good_object (&new_cond))
2702     {
2703       delete new_cond;
2704       cond_initialization_lock.unlock ();
2705       return EAGAIN;
2706     }
2707
2708   myfault efault;
2709   if (efault.faulted ())
2710     {
2711       delete new_cond;
2712       cond_initialization_lock.unlock ();
2713       return EINVAL;
2714     }
2715
2716   *cond = new_cond;
2717   cond_initialization_lock.unlock ();
2718
2719   return 0;
2720 }
2721
2722 extern "C" int
2723 pthread_cond_broadcast (pthread_cond_t *cond)
2724 {
2725   if (pthread_cond::is_initializer (cond))
2726     return 0;
2727   if (!pthread_cond::is_good_object (cond))
2728     return EINVAL;
2729
2730   (*cond)->unblock (true);
2731
2732   return 0;
2733 }
2734
2735 extern "C" int
2736 pthread_cond_signal (pthread_cond_t *cond)
2737 {
2738   if (pthread_cond::is_initializer (cond))
2739     return 0;
2740   if (!pthread_cond::is_good_object (cond))
2741     return EINVAL;
2742
2743   (*cond)->unblock (false);
2744
2745   return 0;
2746 }
2747
2748 static int
2749 __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2750                        PLARGE_INTEGER waitlength)
2751 {
2752   if (!pthread_mutex::is_good_object (mutex))
2753     return EINVAL;
2754   if (!(*mutex)->can_be_unlocked ())
2755     return EPERM;
2756
2757   if (pthread_cond::is_initializer (cond))
2758     pthread_cond::init (cond, NULL);
2759   if (!pthread_cond::is_good_object (cond))
2760     return EINVAL;
2761
2762   return (*cond)->wait (*mutex, waitlength);
2763 }
2764
2765 extern "C" int
2766 pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2767                         const struct timespec *abstime)
2768 {
2769   struct timespec tp;
2770   LARGE_INTEGER timeout;
2771
2772   myfault efault;
2773   if (efault.faulted ())
2774     return EINVAL;
2775
2776   pthread_testcancel ();
2777
2778   /* According to SUSv3, the abstime value must be checked for validity. */
2779   if (abstime->tv_sec < 0
2780       || abstime->tv_nsec < 0
2781       || abstime->tv_nsec > 999999999)
2782     return EINVAL;
2783
2784   clock_gettime ((*cond)->clock_id, &tp);
2785
2786   /* Check for immediate timeout before converting */
2787   if (tp.tv_sec > abstime->tv_sec
2788       || (tp.tv_sec == abstime->tv_sec
2789           && tp.tv_nsec > abstime->tv_nsec))
2790     return ETIMEDOUT;
2791
2792   timeout.QuadPart = abstime->tv_sec * NSPERSEC
2793                       + (abstime->tv_nsec + 99LL) / 100LL;
2794
2795   switch ((*cond)->clock_id)
2796     {
2797     case CLOCK_REALTIME:
2798       timeout.QuadPart += FACTOR;
2799       break;
2800     default:
2801       /* other clocks must be handled as relative timeout */
2802       timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
2803       timeout.QuadPart *= -1LL;
2804       break;
2805     }
2806   return __pthread_cond_dowait (cond, mutex, &timeout);
2807 }
2808
2809 extern "C" int
2810 pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
2811 {
2812   pthread_testcancel ();
2813
2814   return __pthread_cond_dowait (cond, mutex, NULL);
2815 }
2816
2817 extern "C" int
2818 pthread_condattr_init (pthread_condattr_t *condattr)
2819 {
2820   if (pthread_condattr::is_good_object (condattr))
2821     return EBUSY;
2822
2823   *condattr = new pthread_condattr;
2824   if (!pthread_condattr::is_good_object (condattr))
2825     {
2826       delete (*condattr);
2827       *condattr = NULL;
2828       return ENOMEM;
2829     }
2830   return 0;
2831 }
2832
2833 extern "C" int
2834 pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
2835 {
2836   if (!pthread_condattr::is_good_object (attr))
2837     return EINVAL;
2838   *pshared = (*attr)->shared;
2839   return 0;
2840 }
2841
2842 extern "C" int
2843 pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
2844 {
2845   if (!pthread_condattr::is_good_object (attr))
2846     return EINVAL;
2847   if ((pshared < 0) || (pshared > 1))
2848     return EINVAL;
2849   /* shared cond vars not currently supported */
2850   if (pshared != PTHREAD_PROCESS_PRIVATE)
2851     return EINVAL;
2852   (*attr)->shared = pshared;
2853   return 0;
2854 }
2855
2856 extern "C" int
2857 pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t *clock_id)
2858 {
2859   if (!pthread_condattr::is_good_object (attr))
2860     return EINVAL;
2861   *clock_id = (*attr)->clock_id;
2862   return 0;
2863 }
2864
2865 extern "C" int
2866 pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
2867 {
2868   if (!pthread_condattr::is_good_object (attr))
2869     return EINVAL;
2870   switch (clock_id)
2871     {
2872     case CLOCK_REALTIME:
2873     case CLOCK_MONOTONIC:
2874       break;
2875     default:
2876       return EINVAL;
2877     }
2878   (*attr)->clock_id = clock_id;
2879   return 0;
2880 }
2881
2882 extern "C" int
2883 pthread_condattr_destroy (pthread_condattr_t *condattr)
2884 {
2885   if (!pthread_condattr::is_good_object (condattr))
2886     return EINVAL;
2887   delete (*condattr);
2888   *condattr = NULL;
2889   return 0;
2890 }
2891
2892 extern "C" int
2893 pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
2894 {
2895   if (pthread_rwlock::is_initializer (rwlock))
2896     return 0;
2897   if (!pthread_rwlock::is_good_object (rwlock))
2898     return EINVAL;
2899
2900   if ((*rwlock)->writer || (*rwlock)->readers ||
2901       (*rwlock)->waiting_readers || (*rwlock)->waiting_writers)
2902     return EBUSY;
2903
2904   delete (*rwlock);
2905   *rwlock = NULL;
2906
2907   return 0;
2908 }
2909
2910 int
2911 pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
2912 {
2913   pthread_rwlock_t new_rwlock;
2914
2915   if (attr && !pthread_rwlockattr::is_good_object (attr))
2916     return EINVAL;
2917
2918   rwlock_initialization_lock.lock ();
2919
2920   new_rwlock = new pthread_rwlock (attr ? (*attr) : NULL);
2921   if (!is_good_object (&new_rwlock))
2922     {
2923       delete new_rwlock;
2924       rwlock_initialization_lock.unlock ();
2925       return EAGAIN;
2926     }
2927
2928   myfault efault;
2929   if (efault.faulted ())
2930     {
2931       delete new_rwlock;
2932       rwlock_initialization_lock.unlock ();
2933       return EINVAL;
2934     }
2935
2936   *rwlock = new_rwlock;
2937   rwlock_initialization_lock.unlock ();
2938
2939   return 0;
2940 }
2941
2942 extern "C" int
2943 pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
2944 {
2945   pthread_testcancel ();
2946
2947   if (pthread_rwlock::is_initializer (rwlock))
2948     pthread_rwlock::init (rwlock, NULL);
2949   if (!pthread_rwlock::is_good_object (rwlock))
2950     return EINVAL;
2951
2952   return (*rwlock)->rdlock ();
2953 }
2954
2955 extern "C" int
2956 pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
2957 {
2958   if (pthread_rwlock::is_initializer (rwlock))
2959     pthread_rwlock::init (rwlock, NULL);
2960   if (!pthread_rwlock::is_good_object (rwlock))
2961     return EINVAL;
2962
2963   return (*rwlock)->tryrdlock ();
2964 }
2965
2966 extern "C" int
2967 pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
2968 {
2969   pthread_testcancel ();
2970
2971   if (pthread_rwlock::is_initializer (rwlock))
2972     pthread_rwlock::init (rwlock, NULL);
2973   if (!pthread_rwlock::is_good_object (rwlock))
2974     return EINVAL;
2975
2976   return (*rwlock)->wrlock ();
2977 }
2978
2979 extern "C" int
2980 pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
2981 {
2982   if (pthread_rwlock::is_initializer (rwlock))
2983     pthread_rwlock::init (rwlock, NULL);
2984   if (!pthread_rwlock::is_good_object (rwlock))
2985     return EINVAL;
2986
2987   return (*rwlock)->trywrlock ();
2988 }
2989
2990 extern "C" int
2991 pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
2992 {
2993   if (pthread_rwlock::is_initializer (rwlock))
2994     return 0;
2995   if (!pthread_rwlock::is_good_object (rwlock))
2996     return EINVAL;
2997
2998   return (*rwlock)->unlock ();
2999 }
3000
3001 extern "C" int
3002 pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
3003 {
3004   if (pthread_rwlockattr::is_good_object (rwlockattr))
3005     return EBUSY;
3006
3007   *rwlockattr = new pthread_rwlockattr;
3008   if (!pthread_rwlockattr::is_good_object (rwlockattr))
3009     {
3010       delete (*rwlockattr);
3011       *rwlockattr = NULL;
3012       return ENOMEM;
3013     }
3014   return 0;
3015 }
3016
3017 extern "C" int
3018 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
3019 {
3020   if (!pthread_rwlockattr::is_good_object (attr))
3021     return EINVAL;
3022   *pshared = (*attr)->shared;
3023   return 0;
3024 }
3025
3026 extern "C" int
3027 pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
3028 {
3029   if (!pthread_rwlockattr::is_good_object (attr))
3030     return EINVAL;
3031   if ((pshared < 0) || (pshared > 1))
3032     return EINVAL;
3033   /* shared rwlock vars not currently supported */
3034   if (pshared != PTHREAD_PROCESS_PRIVATE)
3035     return EINVAL;
3036   (*attr)->shared = pshared;
3037   return 0;
3038 }
3039
3040 extern "C" int
3041 pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
3042 {
3043   if (!pthread_rwlockattr::is_good_object (rwlockattr))
3044     return EINVAL;
3045   delete (*rwlockattr);
3046   *rwlockattr = NULL;
3047   return 0;
3048 }
3049
3050 /* Thread signal */
3051 extern "C" int
3052 pthread_kill (pthread_t thread, int sig)
3053 {
3054   // lock myself, for the use of thread2signal
3055   // two different kills might clash: FIXME
3056
3057   if (!pthread::is_good_object (&thread))
3058     return EINVAL;
3059
3060   siginfo_t si = {0};
3061   si.si_signo = sig;
3062   si.si_code = SI_USER;
3063   si.si_pid = myself->pid;
3064   si.si_uid = myself->uid;
3065   int rval;
3066   if (!thread->valid)
3067     rval = ESRCH;
3068   else if (sig)
3069     {
3070       thread->cygtls->set_threadkill ();
3071       rval = sig_send (NULL, si, thread->cygtls);
3072     }
3073   else
3074     switch (WaitForSingleObject (thread->win32_obj_id, 0))
3075       {
3076       case WAIT_TIMEOUT:
3077         rval = 0;
3078         break;
3079       default:
3080         rval = ESRCH;
3081         break;
3082       }
3083
3084   // unlock myself
3085   return rval;
3086 }
3087
3088 extern "C" int
3089 pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
3090 {
3091   int res = handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
3092   syscall_printf ("%d = pthread_sigmask(%d, %p, %p)", operation, set, old_set);
3093   return res;
3094 }
3095
3096 extern "C" int
3097 pthread_sigqueue (pthread_t *thread, int sig, const union sigval value)
3098 {
3099   siginfo_t si = {0};
3100
3101   if (!pthread::is_good_object (thread))
3102     return EINVAL;
3103   if (!(*thread)->valid)
3104     return ESRCH;
3105
3106   si.si_signo = sig;
3107   si.si_code = SI_QUEUE;
3108   si.si_value = value;
3109   si.si_pid = myself->pid;
3110   si.si_uid = myself->uid;
3111   return sig_send (NULL, si, (*thread)->cygtls);
3112 }
3113
3114 /* ID */
3115
3116 extern "C" int
3117 pthread_equal (pthread_t t1, pthread_t t2)
3118 {
3119   return pthread::equal (t1, t2);
3120 }
3121
3122 /* Mutexes  */
3123
3124 int
3125 pthread_mutex::init (pthread_mutex_t *mutex,
3126                      const pthread_mutexattr_t *attr,
3127                      const pthread_mutex_t initializer)
3128 {
3129   if (attr && !pthread_mutexattr::is_good_object (attr))
3130     return EINVAL;
3131
3132   mutex_initialization_lock.lock ();
3133   if (initializer == NULL || pthread_mutex::is_initializer (mutex))
3134     {
3135       pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
3136       if (!is_good_object (&new_mutex))
3137         {
3138           delete new_mutex;
3139           mutex_initialization_lock.unlock ();
3140           return EAGAIN;
3141         }
3142
3143       if (!attr && initializer)
3144         {
3145           if (initializer == PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
3146             new_mutex->type = PTHREAD_MUTEX_RECURSIVE;
3147           else if (initializer == PTHREAD_NORMAL_MUTEX_INITIALIZER_NP)
3148             new_mutex->type = PTHREAD_MUTEX_NORMAL;
3149           else if (initializer == PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
3150             new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
3151         }
3152
3153       myfault efault;
3154       if (efault.faulted ())
3155         {
3156           delete new_mutex;
3157           mutex_initialization_lock.unlock ();
3158           return EINVAL;
3159         }
3160
3161       *mutex = new_mutex;
3162     }
3163   mutex_initialization_lock.unlock ();
3164   pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
3165
3166   return 0;
3167 }
3168
3169 extern "C" int
3170 pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
3171                                 int *prioceiling)
3172 {
3173   /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
3174      mutex priorities.
3175
3176      We can support mutex priorities in the future though:
3177      Store a priority with each mutex.
3178      When the mutex is optained, set the thread priority as appropriate
3179      When the mutex is released, reset the thread priority.  */
3180   return ENOSYS;
3181 }
3182
3183 extern "C" int
3184 pthread_mutex_lock (pthread_mutex_t *mutex)
3185 {
3186   if (pthread_mutex::is_initializer (mutex))
3187     pthread_mutex::init (mutex, NULL, *mutex);
3188   if (!pthread_mutex::is_good_object (mutex))
3189     return EINVAL;
3190   return (*mutex)->lock ();
3191 }
3192
3193 extern "C" int
3194 pthread_mutex_trylock (pthread_mutex_t *mutex)
3195 {
3196   if (pthread_mutex::is_initializer (mutex))
3197     pthread_mutex::init (mutex, NULL, *mutex);
3198   if (!pthread_mutex::is_good_object (mutex))
3199     return EINVAL;
3200   return (*mutex)->trylock ();
3201 }
3202
3203 extern "C" int
3204 pthread_mutex_unlock (pthread_mutex_t *mutex)
3205 {
3206   if (pthread_mutex::is_initializer (mutex))
3207     return EPERM;
3208   if (!pthread_mutex::is_good_object (mutex))
3209     return EINVAL;
3210   return (*mutex)->unlock ();
3211 }
3212
3213 extern "C" int
3214 pthread_mutex_destroy (pthread_mutex_t *mutex)
3215 {
3216   int rv;
3217
3218   if (pthread_mutex::is_initializer (mutex))
3219     return 0;
3220   if (!pthread_mutex::is_good_object (mutex))
3221     return EINVAL;
3222
3223   rv = (*mutex)->destroy ();
3224   if (rv)
3225     return rv;
3226
3227   *mutex = NULL;
3228   return 0;
3229 }
3230
3231 extern "C" int
3232 pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
3233                                 int *old_ceiling)
3234 {
3235   return ENOSYS;
3236 }
3237
3238 /* Spinlocks  */
3239
3240 int
3241 pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
3242 {
3243   pthread_spinlock_t new_spinlock = new pthread_spinlock (pshared);
3244   if (!is_good_object (&new_spinlock))
3245     {
3246       delete new_spinlock;
3247       return EAGAIN;
3248     }
3249
3250   myfault efault;
3251   if (efault.faulted ())
3252     {
3253       delete new_spinlock;
3254       return EINVAL;
3255     }
3256
3257   *spinlock = new_spinlock;
3258   pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
3259
3260   return 0;
3261 }
3262
3263 extern "C" int
3264 pthread_spin_lock (pthread_spinlock_t *spinlock)
3265 {
3266   if (!pthread_spinlock::is_good_object (spinlock))
3267     return EINVAL;
3268   return (*spinlock)->lock ();
3269 }
3270
3271 extern "C" int
3272 pthread_spin_trylock (pthread_spinlock_t *spinlock)
3273 {
3274   if (!pthread_spinlock::is_good_object (spinlock))
3275     return EINVAL;
3276   return (*spinlock)->trylock ();
3277 }
3278
3279 extern "C" int
3280 pthread_spin_unlock (pthread_spinlock_t *spinlock)
3281 {
3282   if (!pthread_spinlock::is_good_object (spinlock))
3283     return EINVAL;
3284   return (*spinlock)->unlock ();
3285 }
3286
3287 extern "C" int
3288 pthread_spin_destroy (pthread_spinlock_t *spinlock)
3289 {
3290   if (!pthread_spinlock::is_good_object (spinlock))
3291     return EINVAL;
3292   return (*spinlock)->destroy ();
3293 }
3294
3295 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3296    for more detail */
3297 extern "C" int
3298 pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr,
3299                                  int *protocol)
3300 {
3301   if (!pthread_mutexattr::is_good_object (attr))
3302     return EINVAL;
3303   return ENOSYS;
3304 }
3305
3306 extern "C" int
3307 pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr,
3308                                 int *pshared)
3309 {
3310   if (!pthread_mutexattr::is_good_object (attr))
3311     return EINVAL;
3312   *pshared = (*attr)->pshared;
3313   return 0;
3314 }
3315
3316 extern "C" int
3317 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)
3318 {
3319   if (!pthread_mutexattr::is_good_object (attr))
3320     return EINVAL;
3321   *type = (*attr)->mutextype;
3322   return 0;
3323 }
3324
3325 /* FIXME: write and test process shared mutex's.  */
3326 extern "C" int
3327 pthread_mutexattr_init (pthread_mutexattr_t *attr)
3328 {
3329   if (pthread_mutexattr::is_good_object (attr))
3330     return EBUSY;
3331
3332   *attr = new pthread_mutexattr ();
3333   if (!pthread_mutexattr::is_good_object (attr))
3334     {
3335       delete (*attr);
3336       *attr = NULL;
3337       return ENOMEM;
3338     }
3339   return 0;
3340 }
3341
3342 extern "C" int
3343 pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
3344 {
3345   if (!pthread_mutexattr::is_good_object (attr))
3346     return EINVAL;
3347   delete (*attr);
3348   *attr = NULL;
3349   return 0;
3350 }
3351
3352
3353 /* Win32 doesn't support mutex priorities */
3354 extern "C" int
3355 pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol)
3356 {
3357   if (!pthread_mutexattr::is_good_object (attr))
3358     return EINVAL;
3359   return ENOSYS;
3360 }
3361
3362 /* Win32 doesn't support mutex priorities */
3363 extern "C" int
3364 pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr,
3365                                     int prioceiling)
3366 {
3367   if (!pthread_mutexattr::is_good_object (attr))
3368     return EINVAL;
3369   return ENOSYS;
3370 }
3371
3372 extern "C" int
3373 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,
3374                                     int *prioceiling)
3375 {
3376   if (!pthread_mutexattr::is_good_object (attr))
3377     return EINVAL;
3378   return ENOSYS;
3379 }
3380
3381 extern "C" int
3382 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
3383 {
3384   if (!pthread_mutexattr::is_good_object (attr))
3385     return EINVAL;
3386   /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3387    *functionality
3388    */
3389   if (pshared != PTHREAD_PROCESS_PRIVATE)
3390     return EINVAL;
3391   (*attr)->pshared = pshared;
3392   return 0;
3393 }
3394
3395 /* see pthread_mutex_gettype */
3396 extern "C" int
3397 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
3398 {
3399   if (!pthread_mutexattr::is_good_object (attr))
3400     return EINVAL;
3401
3402   switch (type)
3403     {
3404     case PTHREAD_MUTEX_ERRORCHECK:
3405     case PTHREAD_MUTEX_RECURSIVE:
3406     case PTHREAD_MUTEX_NORMAL:
3407       (*attr)->mutextype = type;
3408       break;
3409     default:
3410       return EINVAL;
3411     }
3412
3413   return 0;
3414 }
3415
3416 /* Semaphores */
3417
3418 List<semaphore> semaphore::semaphores;
3419
3420 semaphore::semaphore (int pshared, unsigned int value)
3421 : verifyable_object (SEM_MAGIC),
3422   shared (pshared),
3423   currentvalue (value),
3424   fd (-1),
3425   hash (0ULL),
3426   sem (NULL)
3427 {
3428   SECURITY_ATTRIBUTES sa = (pshared != PTHREAD_PROCESS_PRIVATE)
3429                            ? sec_all : sec_none_nih;
3430   this->win32_obj_id = ::CreateSemaphore (&sa, value, LONG_MAX, NULL);
3431   if (!this->win32_obj_id)
3432     magic = 0;
3433
3434   semaphores.insert (this);
3435 }
3436
3437 semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd,
3438                       sem_t *ssem, int oflag, mode_t mode, unsigned int value)
3439 : verifyable_object (SEM_MAGIC),
3440   shared (PTHREAD_PROCESS_SHARED),
3441   currentvalue (value),         /* Unused for named semaphores. */
3442   fd (sfd),
3443   hash (shash),
3444   luid (sluid),
3445   sem (ssem)
3446 {
3447   char name[MAX_PATH];
3448
3449   __small_sprintf (name, "semaphore/%016X%08x%08x",
3450                    hash, luid.HighPart, luid.LowPart);
3451   this->win32_obj_id = ::CreateSemaphore (&sec_all, value, LONG_MAX, name);
3452   if (!this->win32_obj_id)
3453     magic = 0;
3454   if (GetLastError () == ERROR_ALREADY_EXISTS && (oflag & O_EXCL))
3455     {
3456       __seterrno ();
3457       CloseHandle (this->win32_obj_id);
3458       magic = 0;
3459     }
3460
3461   semaphores.insert (this);
3462 }
3463
3464 semaphore::~semaphore ()
3465 {
3466   if (win32_obj_id)
3467     CloseHandle (win32_obj_id);
3468
3469   semaphores.remove (this);
3470 }
3471
3472 void
3473 semaphore::_post ()
3474 {
3475   if (ReleaseSemaphore (win32_obj_id, 1, &currentvalue))
3476     currentvalue++;
3477 }
3478
3479 int
3480 semaphore::_getvalue (int *sval)
3481 {
3482   long val;
3483
3484   switch (WaitForSingleObject (win32_obj_id, 0))
3485     {
3486       case WAIT_OBJECT_0:
3487         ReleaseSemaphore (win32_obj_id, 1, &val);
3488         *sval = val + 1;
3489         break;
3490       case WAIT_TIMEOUT:
3491         *sval = 0;
3492         break;
3493       default:
3494         set_errno (EAGAIN);
3495         return -1;
3496     }
3497   return 0;
3498 }
3499
3500 int
3501 semaphore::_trywait ()
3502 {
3503   /* FIXME: signals should be able to interrupt semaphores...
3504     We probably need WaitForMultipleObjects here.  */
3505   if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
3506     {
3507       set_errno (EAGAIN);
3508       return -1;
3509     }
3510   currentvalue--;
3511   return 0;
3512 }
3513
3514 int
3515 semaphore::_timedwait (const struct timespec *abstime)
3516 {
3517   LARGE_INTEGER timeout;
3518
3519   myfault efault;
3520   if (efault.faulted ())
3521     {
3522       /* According to SUSv3, abstime need not be checked for validity,
3523          if the semaphore can be locked immediately. */
3524       if (!_trywait ())
3525         return 0;
3526       set_errno (EINVAL);
3527       return -1;
3528     }
3529
3530   timeout.QuadPart = abstime->tv_sec * NSPERSEC
3531                      + (abstime->tv_nsec + 99) / 100 + FACTOR;
3532
3533   switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
3534     {
3535     case WAIT_OBJECT_0:
3536       currentvalue--;
3537       break;
3538     case WAIT_SIGNALED:
3539       set_errno (EINTR);
3540       return -1;
3541     case WAIT_TIMEOUT:
3542       set_errno (ETIMEDOUT);
3543       return -1;
3544     default:
3545       pthread_printf ("cancelable_wait failed. %E");
3546       __seterrno ();
3547       return -1;
3548     }
3549   return 0;
3550 }
3551
3552 int
3553 semaphore::_wait ()
3554 {
3555   switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
3556     {
3557     case WAIT_OBJECT_0:
3558       currentvalue--;
3559       break;
3560     case WAIT_SIGNALED:
3561       set_errno (EINTR);
3562       return -1;
3563     default:
3564       pthread_printf ("cancelable_wait failed. %E");
3565       break;
3566     }
3567   return 0;
3568 }
3569
3570 void
3571 semaphore::_fixup_after_fork ()
3572 {
3573   if (shared == PTHREAD_PROCESS_PRIVATE)
3574     {
3575       pthread_printf ("sem %x", this);
3576       /* FIXME: duplicate code here and in the constructor. */
3577       this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue,
3578                                               LONG_MAX, NULL);
3579       if (!win32_obj_id)
3580         api_fatal ("failed to create new win32 semaphore, error %d");
3581     }
3582 }
3583
3584 void
3585 semaphore::_terminate ()
3586 {
3587   int _sem_close (sem_t *, bool);
3588
3589   if (sem)
3590     _sem_close (sem, false);
3591 }
3592
3593 /* static members */
3594
3595 int
3596 semaphore::init (sem_t *sem, int pshared, unsigned int value)
3597 {
3598   /*
3599      We can't tell the difference between reinitialising an
3600      existing semaphore and initialising a semaphore who's
3601      contents happen to be a valid pointer
3602    */
3603   if (is_good_object (sem))
3604     {
3605       paranoid_printf ("potential attempt to reinitialise a semaphore");
3606     }
3607
3608   if (value > SEM_VALUE_MAX)
3609     {
3610       set_errno(EINVAL);
3611       return -1;
3612     }
3613
3614   *sem = new semaphore (pshared, value);
3615
3616   if (!is_good_object (sem))
3617     {
3618       delete (*sem);
3619       *sem = NULL;
3620       set_errno(EAGAIN);
3621       return -1;
3622     }
3623   return 0;
3624 }
3625
3626 int
3627 semaphore::destroy (sem_t *sem)
3628 {
3629   if (!is_good_object (sem))
3630     {
3631       set_errno(EINVAL);
3632       return -1;
3633     }
3634
3635   /* It's invalid to destroy a semaphore not opened with sem_init. */
3636   if ((*sem)->fd != -1)
3637     {
3638       set_errno(EINVAL);
3639       return -1;
3640     }
3641
3642   /* FIXME - new feature - test for busy against threads... */
3643
3644   delete (*sem);
3645   *sem = NULL;
3646   return 0;
3647 }
3648
3649 int
3650 semaphore::close (sem_t *sem)
3651 {
3652   if (!is_good_object (sem))
3653     {
3654       set_errno(EINVAL);
3655       return -1;
3656     }
3657
3658   /* It's invalid to close a semaphore not opened with sem_open. */
3659   if ((*sem)->fd == -1)
3660     {
3661       set_errno(EINVAL);
3662       return -1;
3663     }
3664
3665   delete (*sem);
3666   delete sem;
3667   return 0;
3668 }
3669
3670 sem_t *
3671 semaphore::open (unsigned long long hash, LUID luid, int fd, int oflag,
3672                  mode_t mode, unsigned int value, bool &wasopen)
3673 {
3674   if (value > SEM_VALUE_MAX)
3675     {
3676       set_errno (EINVAL);
3677       return NULL;
3678     }
3679
3680   /* sem_open is supposed to return the same pointer, if the same named
3681      semaphore is opened multiple times in the same process, as long as
3682      the semaphore hasn't been closed or unlinked in the meantime. */
3683   semaphores.mx.lock ();
3684   for (semaphore *sema = semaphores.head; sema; sema = sema->next)
3685     if (sema->fd >= 0 && sema->hash == hash
3686         && sema->luid.HighPart == luid.HighPart
3687         && sema->luid.LowPart == sema->luid.LowPart)
3688       {
3689         wasopen = true;
3690         semaphores.mx.unlock ();
3691         return sema->sem;
3692       }
3693   semaphores.mx.unlock ();
3694
3695   wasopen = false;
3696   sem_t *sem = new sem_t;
3697   if (!sem)
3698     {
3699       set_errno (ENOMEM);
3700       return NULL;
3701     }
3702
3703   *sem = new semaphore (hash, luid, fd, sem, oflag, mode, value);
3704
3705   if (!is_good_object (sem))
3706     {
3707       delete *sem;
3708       delete sem;
3709       return NULL;
3710     }
3711   return sem;
3712 }
3713
3714 int
3715 semaphore::wait (sem_t *sem)
3716 {
3717   pthread_testcancel ();
3718
3719   if (!is_good_object (sem))
3720     {
3721       set_errno (EINVAL);
3722       return -1;
3723     }
3724
3725   return (*sem)->_wait ();
3726 }
3727
3728 int
3729 semaphore::trywait (sem_t *sem)
3730 {
3731   if (!is_good_object (sem))
3732     {
3733       set_errno (EINVAL);
3734       return -1;
3735     }
3736
3737   return (*sem)->_trywait ();
3738 }
3739
3740 int
3741 semaphore::timedwait (sem_t *sem, const struct timespec *abstime)
3742 {
3743   if (!is_good_object (sem))
3744     {
3745       set_errno (EINVAL);
3746       return -1;
3747     }
3748
3749   return (*sem)->_timedwait (abstime);
3750 }
3751
3752 int
3753 semaphore::post (sem_t *sem)
3754 {
3755   if (!is_good_object (sem))
3756     {
3757       set_errno (EINVAL);
3758       return -1;
3759     }
3760
3761   (*sem)->_post ();
3762   return 0;
3763 }
3764
3765 int
3766 semaphore::getvalue (sem_t *sem, int *sval)
3767 {
3768   myfault efault;
3769   if (efault.faulted () || !is_good_object (sem))
3770     {
3771       set_errno (EINVAL);
3772       return -1;
3773     }
3774
3775   return (*sem)->_getvalue (sval);
3776 }
3777
3778 int
3779 semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
3780                         LUID *sluid, unsigned int *sval)
3781 {
3782   myfault efault;
3783   if (efault.faulted () || !is_good_object (sem))
3784     {
3785       set_errno (EINVAL);
3786       return -1;
3787     }
3788   if ((*sfd = (*sem)->fd) < 0)
3789     {
3790       set_errno (EINVAL);
3791       return -1;
3792     }
3793   *shash = (*sem)->hash;
3794   *sluid = (*sem)->luid;
3795   /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3796      the sem_getvalue gets a pointer to int to return the value.  Go figure! */
3797   return (*sem)->_getvalue ((int *)sval);
3798 }
3799
3800 /* pthread_null */
3801 pthread *
3802 pthread_null::get_null_pthread ()
3803 {
3804   /* because of weird entry points */
3805   _instance.magic = 0;
3806   return &_instance;
3807 }
3808
3809 pthread_null::pthread_null ()
3810 {
3811   attr.joinable = PTHREAD_CREATE_DETACHED;
3812   /* Mark ourselves as invalid */
3813   magic = 0;
3814 }
3815
3816 pthread_null::~pthread_null ()
3817 {
3818 }
3819
3820 bool
3821 pthread_null::create (void *(*)(void *), pthread_attr *, void *)
3822 {
3823   return true;
3824 }
3825
3826 void
3827 pthread_null::exit (void *value_ptr)
3828 {
3829   _my_tls.remove (INFINITE);
3830   ExitThread (0);
3831 }
3832
3833 int
3834 pthread_null::cancel ()
3835 {
3836   return 0;
3837 }
3838
3839 void
3840 pthread_null::testcancel ()
3841 {
3842 }
3843
3844 int
3845 pthread_null::setcancelstate (int state, int *oldstate)
3846 {
3847   return EINVAL;
3848 }
3849
3850 int
3851 pthread_null::setcanceltype (int type, int *oldtype)
3852 {
3853   return EINVAL;
3854 }
3855
3856 void
3857 pthread_null::push_cleanup_handler (__pthread_cleanup_handler *handler)
3858 {
3859 }
3860
3861 void
3862 pthread_null::pop_cleanup_handler (int const execute)
3863 {
3864 }
3865
3866 unsigned long
3867 pthread_null::getsequence_np ()
3868 {
3869   return 0;
3870 }
3871
3872 pthread_null pthread_null::_instance;