1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12 /* Implementation overview and caveats:
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
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.
24 R.Collins, April 2001. */
27 #include "miscfuncs.h"
32 #include "perprocess.h"
38 #include "miscfuncs.h"
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);
50 extern int threadsafe;
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;
57 pthread_mutex::no_owner()
62 debug_printf ("NULL owner value");
65 else if (owner == _destroyed_mutex)
67 paranoid_printf ("attempt to use destroyed mutex");
70 else if (owner == _new_mutex || owner == _unlocked_mutex)
78 extern "C" struct _reent *
81 return &_my_tls.local_clib;
85 __cygwin_lock_init (_LOCK_T *lock)
87 *lock = _LOCK_T_INITIALIZER;
91 __cygwin_lock_init_recursive (_LOCK_T *lock)
93 *lock = _LOCK_T_RECURSIVE_INITIALIZER;
97 __cygwin_lock_fini (_LOCK_T *lock)
99 pthread_mutex_destroy ((pthread_mutex_t*) lock);
103 __cygwin_lock_lock (_LOCK_T *lock)
105 paranoid_printf ("threadcount %d. locking", MT_INTERFACE->threadcount);
106 pthread_mutex_lock ((pthread_mutex_t*) lock);
110 __cygwin_lock_trylock (_LOCK_T *lock)
112 return pthread_mutex_trylock ((pthread_mutex_t*) lock);
117 __cygwin_lock_unlock (_LOCK_T *lock)
119 pthread_mutex_unlock ((pthread_mutex_t*) lock);
120 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE->threadcount);
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)
128 if (efault.faulted (objectptr))
129 return INVALID_OBJECT;
131 verifyable_object **object = (verifyable_object **) objectptr;
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;
144 pthread_attr::is_good_object (pthread_attr_t const *attr)
146 if (verifyable_object_isvalid (attr, PTHREAD_ATTR_MAGIC) != VALID_OBJECT)
152 pthread_condattr::is_good_object (pthread_condattr_t const *attr)
154 if (verifyable_object_isvalid (attr, PTHREAD_CONDATTR_MAGIC) != VALID_OBJECT)
160 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t const *attr)
162 if (verifyable_object_isvalid (attr, PTHREAD_RWLOCKATTR_MAGIC) != VALID_OBJECT)
168 pthread_key::is_good_object (pthread_key_t const *key)
170 if (verifyable_object_isvalid (key, PTHREAD_KEY_MAGIC) != VALID_OBJECT)
176 pthread_spinlock::is_good_object (pthread_spinlock_t const *mutex)
178 if (verifyable_object_isvalid (mutex, PTHREAD_SPINLOCK_MAGIC) != VALID_OBJECT)
184 pthread_mutex::is_good_object (pthread_mutex_t const *mutex)
186 if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
192 pthread_mutex::is_initializer (pthread_mutex_t const *mutex)
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)
203 pthread_mutex::is_initializer_or_object (pthread_mutex_t const *mutex)
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)
213 /* FIXME: Accommodate PTHREAD_MUTEX_ERRORCHECK */
215 pthread_mutex::can_be_unlocked ()
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);
227 pthread_mutexattr::is_good_object (pthread_mutexattr_t const * attr)
229 if (verifyable_object_isvalid (attr, PTHREAD_MUTEXATTR_MAGIC) != VALID_OBJECT)
234 inline bool __attribute__ ((used))
235 pthread::is_good_object (pthread_t const *thread)
237 if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
242 /* Thread synchronisation */
244 pthread_cond::is_good_object (pthread_cond_t const *cond)
246 if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC) != VALID_OBJECT)
252 pthread_cond::is_initializer (pthread_cond_t const *cond)
254 if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) != VALID_STATIC_OBJECT)
260 pthread_cond::is_initializer_or_object (pthread_cond_t const *cond)
262 if (verifyable_object_isvalid (cond, PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER) == INVALID_OBJECT)
269 pthread_rwlock::is_good_object (pthread_rwlock_t const *rwlock)
271 if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC) != VALID_OBJECT)
277 pthread_rwlock::is_initializer (pthread_rwlock_t const *rwlock)
279 if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) != VALID_STATIC_OBJECT)
285 pthread_rwlock::is_initializer_or_object (pthread_rwlock_t const *rwlock)
287 if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) == INVALID_OBJECT)
293 semaphore::is_good_object (sem_t const * sem)
295 if (verifyable_object_isvalid (sem, SEM_MAGIC) != VALID_OBJECT)
303 pthread_mutex::init_mutex ();
304 pthread_cond::init_mutex ();
305 pthread_rwlock::init_mutex ();
309 MTinterface::fixup_before_fork ()
311 pthread_key::fixup_before_fork ();
314 /* This function is called from a single threaded process */
316 MTinterface::fixup_after_fork ()
318 pthread_key::fixup_after_fork ();
321 pthread::init_mainthread ();
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 ();
334 pthread::init_mainthread ()
336 pthread *thread = _my_tls.tid;
339 thread = new pthread ();
341 api_fatal ("failed to create mainthread object");
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 ();
359 pthread *thread = _my_tls.tid;
362 thread = pthread_null::get_null_pthread ();
363 set_tls_self_pointer (thread);
369 pthread::set_tls_self_pointer (pthread *thread)
371 thread->cygtls = &_my_tls;
372 _my_tls.tid = thread;
375 List<pthread> pthread::threads;
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)
383 if (this != pthread_null::get_null_pthread ())
384 threads.insert (this);
385 sigprocmask (SIG_SETMASK, NULL, &parent_sigmask);
391 CloseHandle (win32_obj_id);
393 CloseHandle (cancel_event);
395 if (this != pthread_null::get_null_pthread ())
396 threads.remove (this);
400 pthread::create_cancel_event ()
402 cancel_event = ::CreateEvent (&sec_none_nih, true, false, NULL);
405 system_printf ("couldn't create cancel event, %E");
406 /* we need the event for correct behaviour */
413 pthread::precreate (pthread_attr *newattr)
415 pthread_mutex *verifyable_mutex_obj = &mutex;
417 /* already running ? */
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;
431 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
433 thread_printf ("New thread object access mutex is not valid. this %p",
438 /* Change the mutex type to NORMAL to speed up mutex operations */
439 mutex.set_type (PTHREAD_MUTEX_NORMAL);
440 if (!create_cancel_event ())
445 pthread::create (void *(*func) (void *), pthread_attr *newattr,
458 win32_obj_id = CygwinCreateThread (thread_init_wrapper, this,
459 attr.stackaddr, attr.stacksize,
460 attr.guardsize, 0, &thread_id);
464 thread_printf ("CreateThread failed: this %p, %E", this);
479 pthread::postcreate ()
483 InterlockedIncrement (&MT_INTERFACE->threadcount);
484 /* FIXME: set the priority appropriately for system contention scope */
485 if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
487 /* FIXME: set the scheduling settings for the new thread */
488 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
493 pthread::exit (void *value_ptr)
495 class pthread *thread = this;
497 // run cleanup handlers
498 pop_all_cleanup_handlers ();
500 pthread_key::run_all_destructors ();
503 // cleanup if thread is in detached state and not joined
504 if (equal (joiner, thread))
509 return_ptr = value_ptr;
513 if (_my_tls.local_clib.__sdidinit < 0)
514 _my_tls.local_clib.__sdidinit = 0;
515 (_reclaim_reent) (_REENT);
517 if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
521 if (cygtls == _main_tls)
523 _cygtls *dummy = (_cygtls *) malloc (sizeof (_cygtls));
526 _main_tls->initialized = false;
535 class pthread *thread = this;
536 class pthread *self = pthread::self ();
546 if (canceltype == PTHREAD_CANCEL_DEFERRED ||
547 cancelstate == PTHREAD_CANCEL_DISABLE)
552 SetEvent (cancel_event);
555 else if (equal (thread, self))
559 return 0; // Never reached
562 // cancel asynchronous
563 SuspendThread (win32_obj_id);
564 if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
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);
573 ResumeThread (win32_obj_id);
578 /* TODO: Insert pthread_testcancel into the required functions.
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.
585 Required cancellation points:
613 * pthread_cond_timedwait ()
614 * pthread_cond_wait ()
616 * pthread_testcancel ()
647 Optional cancellation points:
652 catclose () Implemented externally: libcatgets
653 catgets () Implemented externally: libcatgets
654 catopen () Implemented externally: libcatgets
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
684 * fcntl () (any value)
739 getopt () (if opterr is nonzero)
759 iconv_close () Implemented externally: libiconv
760 iconv_open () Implemented externally: libiconv
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 ()
812 pthread_rwlock_rdlock ()
813 o pthread_rwlock_timedrdlock ()
814 o pthread_rwlock_timedwrlock ()
815 pthread_rwlock_wrlock ()
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. */
881 pthread::testcancel ()
883 if (cancelstate == PTHREAD_CANCEL_DISABLE)
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. */
893 WaitForSingleObject (cancel_event, INFINITE);
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. */
902 pthread::get_cancel_event ()
904 pthread_t thread = pthread::self ();
906 return (thread && thread->cancel_event
907 && thread->cancelstate != PTHREAD_CANCEL_DISABLE)
908 ? thread->cancel_event : NULL;
912 pthread::static_cancel_self ()
914 pthread::self ()->cancel_self ();
918 cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
919 const cw_cancel_action cancel_action,
920 const enum cw_sig_wait sig_wait)
924 HANDLE wait_objects[4];
925 pthread_t thread = pthread::self ();
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;
933 if (cancel_action == cw_no_cancel || !pthread::is_good_object (&thread) ||
934 thread->cancelstate == PTHREAD_CANCEL_DISABLE)
935 cancel_n = WAIT_TIMEOUT + 1;
938 cancel_n = WAIT_OBJECT_0 + num++;
939 wait_objects[cancel_n] = thread->cancel_event;
943 if (sig_wait == cw_sig_nosig)
944 sig_n = WAIT_TIMEOUT + 1;
947 sig_n = WAIT_OBJECT_0 + num++;
948 wait_objects[sig_n] = signal_arrived;
953 timeout_n = WAIT_TIMEOUT + 1;
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,
960 NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
961 wait_objects[timeout_n] = _my_tls.locals.cw_timer;
966 res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
969 if (cancel_action == cw_cancel_self)
970 pthread::static_cancel_self ();
973 else if (res == timeout_n)
975 else if (res != sig_n)
977 else if (sig_wait == cw_sig_eintr)
981 _my_tls.call_signal_handler ();
989 const size_t sizeof_tbi = sizeof (TIMER_BASIC_INFORMATION);
990 PTIMER_BASIC_INFORMATION tbi = (PTIMER_BASIC_INFORMATION) malloc (sizeof_tbi);
992 NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, tbi,
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);
1005 pthread::setcancelstate (int state, int *oldstate)
1011 if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
1016 *oldstate = cancelstate;
1017 cancelstate = state;
1026 pthread::setcanceltype (int type, int *oldtype)
1032 if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS)
1037 *oldtype = canceltype;
1047 pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
1049 if (this != self ())
1051 api_fatal ("Attempt to push a cleanup handler across threads");
1052 handler->next = cleanup_stack;
1053 cleanup_stack = handler;
1057 pthread::pop_cleanup_handler (int const execute)
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");
1065 if (cleanup_stack != NULL)
1067 __pthread_cleanup_handler *handler = cleanup_stack;
1070 (*handler->function) (handler->arg);
1071 cleanup_stack = handler->next;
1078 pthread::pop_all_cleanup_handlers ()
1080 while (cleanup_stack != NULL)
1081 pop_cleanup_handler (1);
1085 pthread::cancel_self ()
1087 /* Can someone explain why the pthread:: is needed here? g++ complains
1089 pthread::exit (PTHREAD_CANCELED);
1093 pthread::get_thread_id ()
1099 pthread::_fixup_after_fork ()
1101 /* set thread to not running if it is not the forking thread */
1102 if (this != pthread::self ())
1106 win32_obj_id = NULL;
1108 cancel_event = NULL;
1113 pthread::suspend_except_self ()
1115 if (valid && this != pthread::self ())
1116 SuspendThread (win32_obj_id);
1123 ResumeThread (win32_obj_id);
1126 /* instance members */
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)
1133 schedparam.sched_priority = 0;
1136 pthread_attr::~pthread_attr ()
1140 pthread_condattr::pthread_condattr ():verifyable_object
1141 (PTHREAD_CONDATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE),
1142 clock_id (CLOCK_REALTIME)
1146 pthread_condattr::~pthread_condattr ()
1150 List<pthread_cond> pthread_cond::conds;
1152 /* This is used for cond creation protection within a single process only */
1153 fast_mutex NO_COPY pthread_cond::cond_initialization_lock;
1155 /* We can only be called once.
1156 TODO: (no rush) use a non copied memory section to
1157 hold an initialization flag. */
1159 pthread_cond::init_mutex ()
1161 if (!cond_initialization_lock.init ())
1162 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
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)
1170 pthread_mutex *verifyable_mutex_obj;
1174 clock_id = attr->clock_id;
1176 if (attr->shared != PTHREAD_PROCESS_PRIVATE)
1183 verifyable_mutex_obj = &mtx_in;
1184 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1186 thread_printf ("Internal cond mutex is not valid. this %p", this);
1191 * Change the mutex type to NORMAL.
1192 * This mutex MUST be of type normal
1194 mtx_in.set_type (PTHREAD_MUTEX_NORMAL);
1196 verifyable_mutex_obj = &mtx_out;
1197 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1199 thread_printf ("Internal cond mutex is not valid. this %p", this);
1203 /* Change the mutex type to NORMAL to speed up mutex operations */
1204 mtx_out.set_type (PTHREAD_MUTEX_NORMAL);
1206 sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
1209 pthread_printf ("CreateSemaphore failed. %E");
1214 conds.insert (this);
1217 pthread_cond::~pthread_cond ()
1220 CloseHandle (sem_wait);
1222 conds.remove (this);
1226 pthread_cond::unblock (const bool all)
1228 unsigned long releaseable;
1231 * Block outgoing threads (and avoid simultanous unblocks)
1235 releaseable = waiting - pending;
1238 unsigned long released;
1243 * Block incoming threads until all waiting threads are released.
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
1252 releaseable = waiting - pending;
1255 released = all ? releaseable : 1;
1256 pending += released;
1260 ::ReleaseSemaphore (sem_wait, released, NULL);
1264 * And let the threads release.
1270 pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout)
1275 if (InterlockedIncrement ((long *)&waiting) == 1)
1277 else if (mtx_cond != mutex)
1279 InterlockedDecrement ((long *)&waiting);
1286 * Release the mutex and wait on semaphore
1291 rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
1295 if (rv != WAIT_OBJECT_0)
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.
1302 if (WaitForSingleObject (sem_wait, 0) == WAIT_OBJECT_0)
1304 * thread got cancelled ot timed out while a signalling is in progress.
1305 * Set wait result back to signaled
1310 InterlockedDecrement ((long *)&waiting);
1312 if (rv == WAIT_OBJECT_0 && --pending == 0)
1314 * All signaled threads are released,
1315 * new threads can enter Wait
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. */
1333 else if (rv == WAIT_TIMEOUT)
1340 pthread_cond::_fixup_after_fork ()
1342 waiting = pending = 0;
1345 /* Unlock eventually locked mutexes */
1349 sem_wait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
1351 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1354 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1355 (PTHREAD_RWLOCKATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
1359 pthread_rwlockattr::~pthread_rwlockattr ()
1363 List<pthread_rwlock> pthread_rwlock::rwlocks;
1365 /* This is used for rwlock creation protection within a single process only */
1366 fast_mutex NO_COPY pthread_rwlock::rwlock_initialization_lock;
1368 /* We can only be called once.
1369 TODO: (no rush) use a non copied memory section to
1370 hold an initialization flag. */
1372 pthread_rwlock::init_mutex ()
1374 if (!rwlock_initialization_lock.init ())
1375 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
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),
1384 pthread_mutex *verifyable_mutex_obj = &mtx;
1385 pthread_cond *verifyable_cond_obj;
1387 if (!readers_mx.init ())
1389 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1395 if (attr->shared != PTHREAD_PROCESS_PRIVATE)
1401 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj))
1403 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1407 /* Change the mutex type to NORMAL to speed up mutex operations */
1408 mtx.set_type (PTHREAD_MUTEX_NORMAL);
1410 verifyable_cond_obj = &cond_readers;
1411 if (!pthread_cond::is_good_object (&verifyable_cond_obj))
1413 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1418 verifyable_cond_obj = &cond_writers;
1419 if (!pthread_cond::is_good_object (&verifyable_cond_obj))
1421 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1427 rwlocks.insert (this);
1430 pthread_rwlock::~pthread_rwlock ()
1432 rwlocks.remove (this);
1436 pthread_rwlock::rdlock ()
1439 struct RWLOCK_READER *reader;
1440 pthread_t self = pthread::self ();
1444 reader = lookup_reader (self);
1447 if (reader->n < ULONG_MAX)
1454 reader = new struct RWLOCK_READER;
1461 while (writer || waiting_writers)
1463 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup, this);
1466 cond_readers.wait (&mtx);
1469 pthread_cleanup_pop (0);
1472 reader->thread = self;
1474 add_reader (reader);
1483 pthread_rwlock::tryrdlock ()
1486 pthread_t self = pthread::self ();
1490 if (writer || waiting_writers || lookup_reader (self))
1494 struct RWLOCK_READER *reader;
1496 reader = lookup_reader (self);
1497 if (reader && reader->n < ULONG_MAX)
1499 else if ((reader = new struct RWLOCK_READER))
1501 reader->thread = self;
1503 add_reader (reader);
1515 pthread_rwlock::wrlock ()
1518 pthread_t self = pthread::self ();
1522 if (writer == self || lookup_reader (self))
1528 while (writer || readers)
1530 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup, this);
1533 cond_writers.wait (&mtx);
1536 pthread_cleanup_pop (0);
1548 pthread_rwlock::trywrlock ()
1551 pthread_t self = pthread::self ();
1555 if (writer || readers)
1566 pthread_rwlock::unlock ()
1569 pthread_t self = pthread::self ();
1585 struct RWLOCK_READER *reader = lookup_reader (self);
1592 if (--reader->n > 0)
1595 remove_reader (reader);
1608 pthread_rwlock::add_reader (struct RWLOCK_READER *rd)
1610 List_insert (readers, rd);
1614 pthread_rwlock::remove_reader (struct RWLOCK_READER *rd)
1616 List_remove (readers_mx, readers, rd);
1619 struct pthread_rwlock::RWLOCK_READER *
1620 pthread_rwlock::lookup_reader (pthread_t thread)
1624 struct RWLOCK_READER *cur = readers;
1626 while (cur && cur->thread != thread)
1629 readers_mx.unlock ();
1635 pthread_rwlock::rdlock_cleanup (void *arg)
1637 pthread_rwlock *rwlock = (pthread_rwlock *) arg;
1639 --(rwlock->waiting_readers);
1641 rwlock->mtx.unlock ();
1645 pthread_rwlock::wrlock_cleanup (void *arg)
1647 pthread_rwlock *rwlock = (pthread_rwlock *) arg;
1649 --(rwlock->waiting_writers);
1651 rwlock->mtx.unlock ();
1655 pthread_rwlock::_fixup_after_fork ()
1657 pthread_t self = pthread::self ();
1658 struct RWLOCK_READER **temp = &readers;
1660 waiting_readers = 0;
1661 waiting_writers = 0;
1663 if (!readers_mx.init ())
1664 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1666 /* Unlock eventually locked mutex */
1669 * Remove all readers except self
1673 if ((*temp)->thread == self)
1674 temp = &((*temp)->next);
1677 struct RWLOCK_READER *cur = *temp;
1678 *temp = (*temp)->next;
1685 /* static members */
1686 /* This stores pthread_key information across fork() boundaries */
1687 List<pthread_key> pthread_key::keys;
1689 /* non-static members */
1691 pthread_key::pthread_key (void (*aDestructor) (void *)):verifyable_object (PTHREAD_KEY_MAGIC), destructor (aDestructor)
1693 tls_index = TlsAlloc ();
1694 if (tls_index == TLS_OUT_OF_INDEXES)
1700 pthread_key::~pthread_key ()
1702 /* We may need to make the list code lock the list during operations
1707 TlsFree (tls_index);
1712 pthread_key::_fixup_before_fork ()
1718 pthread_key::_fixup_after_fork ()
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");
1727 pthread_key::run_destructor ()
1731 void *oldValue = get ();
1735 destructor (oldValue);
1740 /* pshared mutexs */
1742 /* static members */
1744 List<pthread_mutex> pthread_mutex::mutexes;
1746 /* This is used for mutex creation protection within a single process only */
1747 fast_mutex NO_COPY pthread_mutex::mutex_initialization_lock;
1750 pthread_mutex::init_mutex ()
1752 if (!mutex_initialization_lock.init ())
1753 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1756 pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
1757 verifyable_object (0), /* set magic to zero initially */
1759 win32_obj_id (NULL), owner (_new_mutex),
1763 recursion_counter (0), condwaits (0),
1764 type (PTHREAD_MUTEX_ERRORCHECK),
1765 pshared (PTHREAD_PROCESS_PRIVATE)
1767 win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
1770 /*attr checked in the C call */
1772 /* handled in the caller */;
1773 else if (attr->pshared != PTHREAD_PROCESS_SHARED)
1774 type = attr->mutextype;
1776 return; /* Not implemented */
1778 magic = PTHREAD_MUTEX_MAGIC;
1779 mutexes.insert (this);
1782 pthread_mutex::~pthread_mutex ()
1786 CloseHandle (win32_obj_id);
1787 win32_obj_id = NULL;
1790 mutexes.remove (this);
1791 owner = _destroyed_mutex;
1796 pthread_mutex::lock ()
1798 pthread_t self = ::pthread_self ();
1801 if (InterlockedIncrement ((long *) &lock_counter) == 1)
1803 else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
1804 || !pthread::equal (owner, self))
1806 cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
1811 InterlockedDecrement ((long *) &lock_counter);
1812 if (type == PTHREAD_MUTEX_RECURSIVE)
1813 result = lock_recursive ();
1818 pthread_printf ("mutex %p, self %p, owner %p, lock_counter %d, recursion_counter %d",
1819 this, self, owner, lock_counter, recursion_counter);
1824 pthread_mutex::unlock ()
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))
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. */
1838 owner = (pthread_t) _unlocked_mutex;
1842 if (InterlockedDecrement ((long *) &lock_counter))
1843 ::SetEvent (win32_obj_id); // Another thread is waiting
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);
1853 pthread_mutex::trylock ()
1855 pthread_t self = ::pthread_self ();
1858 if (InterlockedCompareExchange ((long *) &lock_counter, 1, 0) == 0)
1860 else if (type == PTHREAD_MUTEX_RECURSIVE && pthread::equal (owner, self))
1861 result = lock_recursive ();
1869 pthread_mutex::destroy ()
1871 if (condwaits || trylock ())
1872 // Do not destroy a condwaited or locked mutex
1874 else if (recursion_counter > 1)
1876 // Do not destroy a recursive locked mutex
1877 recursion_counter--;
1886 pthread_mutex::_fixup_after_fork ()
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");
1892 /* All waiting threads are gone after a fork */
1893 recursion_counter = 0;
1897 tid = 0xffffffff; /* Don't know the tid after a fork */
1899 win32_obj_id = ::CreateEvent (&sec_none_nih, false, false, NULL);
1901 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 event for mutex");
1904 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC),
1905 pshared (PTHREAD_PROCESS_PRIVATE), mutextype (PTHREAD_MUTEX_ERRORCHECK)
1909 pthread_mutexattr::~pthread_mutexattr ()
1913 /* pshared spinlocks
1915 The infrastructure is provided by the underlying pthread_mutex class.
1916 The rest is a simplification implementing spin locking. */
1918 pthread_spinlock::pthread_spinlock (int pshared) :
1919 pthread_mutex (NULL)
1921 magic = PTHREAD_SPINLOCK_MAGIC;
1922 set_type (PTHREAD_MUTEX_NORMAL);
1923 set_shared (pshared);
1927 pthread_spinlock::lock ()
1929 pthread_t self = ::pthread_self ();
1934 if (InterlockedExchange ((long *) &lock_counter, 1) == 0)
1939 else if (pthread::equal (owner, self))
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);
1949 while (result == -1);
1950 pthread_printf ("spinlock %p, self %p, owner %p", this, self, owner);
1955 pthread_spinlock::unlock ()
1957 pthread_t self = ::pthread_self ();
1960 if (!pthread::equal (owner, self))
1964 owner = (pthread_t) _unlocked_mutex;
1968 InterlockedExchange ((long *) &lock_counter, 0);
1969 ::SetEvent (win32_obj_id);
1972 pthread_printf ("spinlock %p, owner %p, self %p, res %d",
1973 this, owner, self, result);
1978 pthread::thread_init_wrapper (void *arg)
1980 pthread *thread = (pthread *) arg;
1981 set_tls_self_pointer (thread);
1983 thread->mutex.lock ();
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 ();
1991 thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
1992 _impure_ptr, thread, thread->function, thread->arg);
1994 // call the user's thread
1995 void *ret = thread->function (thread->arg);
1999 return 0; // just for show. Never returns.
2003 pthread::getsequence_np ()
2005 return get_thread_id ();
2009 pthread::create (pthread_t *thread, const pthread_attr_t *attr,
2010 void *(*start_routine) (void *), void *arg)
2012 if (attr && !pthread_attr::is_good_object (attr))
2015 *thread = new pthread ();
2016 if (!(*thread)->create (start_routine, attr ? *attr : NULL, arg))
2027 pthread::once (pthread_once_t *once_control, void (*init_routine) (void))
2030 if (once_control->state)
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 ();
2040 if (!once_control->state)
2043 once_control->state = 1;
2045 /* Here we must remove our cancellation handler */
2046 pthread_mutex_unlock (&once_control->mutex);
2051 pthread::cancel (pthread_t thread)
2053 if (!is_good_object (&thread))
2056 return thread->cancel ();
2060 pthread::atforkprepare ()
2062 callback *cb = MT_INTERFACE->pthread_prepare;
2071 MT_INTERFACE->fixup_before_fork ();
2075 pthread::atforkparent ()
2079 callback *cb = MT_INTERFACE->pthread_parent;
2088 pthread::atforkchild ()
2090 MT_INTERFACE->fixup_after_fork ();
2094 callback *cb = MT_INTERFACE->pthread_child;
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. */
2106 pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void))
2108 callback *prepcb = NULL, *parentcb = NULL, *childcb = NULL;
2111 prepcb = new callback;
2117 parentcb = new callback;
2127 childcb = new callback;
2140 prepcb->cb = prepare;
2141 List_insert (MT_INTERFACE->pthread_prepare, prepcb);
2145 parentcb->cb = parent;
2146 callback **t = &MT_INTERFACE->pthread_parent;
2149 /* t = pointer to last next in the list */
2150 List_insert (*t, parentcb);
2154 childcb->cb = child;
2155 callback **t = &MT_INTERFACE->pthread_child;
2158 /* t = pointer to last next in the list */
2159 List_insert (*t, childcb);
2165 pthread_attr_init (pthread_attr_t *attr)
2167 if (pthread_attr::is_good_object (attr))
2170 *attr = new pthread_attr;
2171 if (!pthread_attr::is_good_object (attr))
2181 pthread_attr_getinheritsched (const pthread_attr_t *attr,
2184 if (!pthread_attr::is_good_object (attr))
2186 *inheritsched = (*attr)->inheritsched;
2191 pthread_attr_getschedparam (const pthread_attr_t *attr,
2192 struct sched_param *param)
2194 if (!pthread_attr::is_good_object (attr))
2196 *param = (*attr)->schedparam;
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 */
2204 pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy)
2206 if (!pthread_attr::is_good_object (attr))
2208 *policy = SCHED_FIFO;
2214 pthread_attr_getscope (const pthread_attr_t *attr, int *contentionscope)
2216 if (!pthread_attr::is_good_object (attr))
2218 *contentionscope = (*attr)->contentionscope;
2223 pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate)
2225 if (!pthread_attr::is_good_object (attr))
2227 if (detachstate < 0 || detachstate > 1)
2229 (*attr)->joinable = detachstate;
2234 pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstate)
2236 if (!pthread_attr::is_good_object (attr))
2238 *detachstate = (*attr)->joinable;
2243 pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched)
2245 if (!pthread_attr::is_good_object (attr))
2247 if (inheritsched != PTHREAD_INHERIT_SCHED
2248 && inheritsched != PTHREAD_EXPLICIT_SCHED)
2250 (*attr)->inheritsched = inheritsched;
2255 pthread_attr_setschedparam (pthread_attr_t *attr,
2256 const struct sched_param *param)
2258 if (!pthread_attr::is_good_object (attr))
2260 if (!valid_sched_parameters (param))
2262 (*attr)->schedparam = *param;
2266 /* See __pthread_attr_getschedpolicy for some notes */
2268 pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)
2270 if (!pthread_attr::is_good_object (attr))
2272 if (policy != SCHED_FIFO)
2278 pthread_attr_setscope (pthread_attr_t *attr, int contentionscope)
2280 if (!pthread_attr::is_good_object (attr))
2282 if (contentionscope != PTHREAD_SCOPE_SYSTEM
2283 && contentionscope != PTHREAD_SCOPE_PROCESS)
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)
2289 (*attr)->contentionscope = contentionscope;
2294 pthread_attr_setstack (pthread_attr_t *attr, void *addr, size_t size)
2296 if (!pthread_attr::is_good_object (attr))
2300 if (size < PTHREAD_STACK_MIN)
2302 (*attr)->stackaddr = addr;
2303 (*attr)->stacksize = size;
2308 pthread_attr_getstack (const pthread_attr_t *attr, void **addr, size_t *size)
2310 if (!pthread_attr::is_good_object (attr))
2312 /* uses lowest address of stack on all platforms */
2313 *addr = (void *)((int)(*attr)->stackaddr - (*attr)->stacksize);
2314 *size = (*attr)->stacksize;
2319 pthread_attr_setstackaddr (pthread_attr_t *attr, void *addr)
2321 if (!pthread_attr::is_good_object (attr))
2325 (*attr)->stackaddr = addr;
2330 pthread_attr_getstackaddr (const pthread_attr_t *attr, void **addr)
2332 if (!pthread_attr::is_good_object (attr))
2334 /* uses stack address, which is the higher address on platforms
2335 where the stack grows downwards, such as x86 */
2336 *addr = (*attr)->stackaddr;
2341 pthread_attr_setstacksize (pthread_attr_t *attr, size_t size)
2343 if (!pthread_attr::is_good_object (attr))
2345 if (size < PTHREAD_STACK_MIN)
2347 (*attr)->stacksize = size;
2352 pthread_attr_getstacksize (const pthread_attr_t *attr, size_t *size)
2354 if (!pthread_attr::is_good_object (attr))
2356 *size = (*attr)->stacksize;
2361 pthread_attr_setguardsize (pthread_attr_t *attr, size_t size)
2363 if (!pthread_attr::is_good_object (attr))
2365 /* We don't support a guardsize of more than 1 Meg. */
2366 if (size > 1024 * 1024)
2368 (*attr)->guardsize = size;
2373 pthread_attr_getguardsize (const pthread_attr_t *attr, size_t *size)
2375 if (!pthread_attr::is_good_object (attr))
2377 *size = (*attr)->guardsize;
2382 pthread_attr_destroy (pthread_attr_t *attr)
2384 if (!pthread_attr::is_good_object (attr))
2392 pthread::join (pthread_t *thread, void **return_val)
2394 pthread_t joiner = self ();
2396 joiner->testcancel ();
2398 // Initialize return val with NULL
2402 if (!is_good_object (&joiner))
2405 if (!is_good_object (thread))
2408 if (equal (*thread,joiner))
2411 (*thread)->mutex.lock ();
2413 if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
2415 (*thread)->mutex.unlock ();
2420 (*thread)->joiner = joiner;
2421 (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
2422 (*thread)->mutex.unlock ();
2424 switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
2428 *return_val = (*thread)->return_ptr;
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 ();
2439 // should never happen
2448 pthread::detach (pthread_t *thread)
2450 if (!is_good_object (thread))
2453 (*thread)->mutex.lock ();
2454 if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
2456 (*thread)->mutex.unlock ();
2460 // check if thread is still alive
2461 if ((*thread)->valid && WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT)
2463 // force cleanup on exit
2464 (*thread)->joiner = *thread;
2465 (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
2466 (*thread)->mutex.unlock ();
2470 // thread has already terminated.
2471 (*thread)->mutex.unlock ();
2479 pthread::suspend (pthread_t *thread)
2481 if (!is_good_object (thread))
2484 if ((*thread)->suspended == false)
2486 (*thread)->suspended = true;
2487 SuspendThread ((*thread)->win32_obj_id);
2495 pthread::resume (pthread_t *thread)
2497 if (!is_good_object (thread))
2500 if ((*thread)->suspended == true)
2501 ResumeThread ((*thread)->win32_obj_id);
2502 (*thread)->suspended = false;
2508 pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
2510 const size_t sizeof_tbi = sizeof (THREAD_BASIC_INFORMATION);
2511 PTHREAD_BASIC_INFORMATION tbi;
2514 if (!pthread::is_good_object (&thread))
2517 /* attr may not be pre-initialized */
2518 if (!pthread_attr::is_good_object (attr))
2520 int rv = pthread_attr_init (attr);
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;
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))
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;
2545 debug_printf ("NtQueryInformationThread(ThreadBasicInformation), "
2546 "status %p", status);
2547 (*attr)->stackaddr = thread->attr.stackaddr;
2548 (*attr)->stacksize = thread->attr.stacksize;
2554 /* provided for source level compatability.
2555 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2558 pthread_getconcurrency ()
2560 return MT_INTERFACE->concurrency;
2564 pthread_getcpuclockid (pthread_t thread, clockid_t *clk_id)
2566 if (!pthread::is_good_object (&thread))
2568 *clk_id = (clockid_t) THREADID_TO_CLOCKID (thread->getsequence_np ());
2572 /* keep this in sync with sched.cc */
2574 pthread_getschedparam (pthread_t thread, int *policy,
2575 struct sched_param *param)
2577 if (!pthread::is_good_object (&thread))
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;
2586 /* Thread Specific Data */
2588 pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
2590 *key = new pthread_key (destructor);
2592 if (!pthread_key::is_good_object (key))
2602 pthread_key_delete (pthread_key_t key)
2604 if (!pthread_key::is_good_object (&key))
2611 /* provided for source level compatability. See
2612 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2615 pthread_setconcurrency (int new_level)
2619 MT_INTERFACE->concurrency = new_level;
2623 /* keep syncronised with sched.cc */
2625 pthread_setschedparam (pthread_t thread, int policy,
2626 const struct sched_param *param)
2628 if (!pthread::is_good_object (&thread))
2630 if (policy != SCHED_FIFO)
2635 sched_set_thread_priority (thread->win32_obj_id, param->sched_priority);
2637 thread->attr.schedparam.sched_priority = param->sched_priority;
2642 pthread_setschedprio (pthread_t thread, int priority)
2644 if (!pthread::is_good_object (&thread))
2647 sched_set_thread_priority (thread->win32_obj_id, priority);
2649 thread->attr.schedparam.sched_priority = priority;
2654 pthread_setspecific (pthread_key_t key, const void *value)
2656 if (!pthread_key::is_good_object (&key))
2663 pthread_getspecific (pthread_key_t key)
2665 if (!pthread_key::is_good_object (&key))
2668 return (key)->get ();
2673 pthread_cond_destroy (pthread_cond_t *cond)
2675 if (pthread_cond::is_initializer (cond))
2677 if (!pthread_cond::is_good_object (cond))
2680 /* reads are atomic */
2681 if ((*cond)->waiting)
2691 pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
2693 pthread_cond_t new_cond;
2695 if (attr && !pthread_condattr::is_good_object (attr))
2698 cond_initialization_lock.lock ();
2700 new_cond = new pthread_cond (attr ? (*attr) : NULL);
2701 if (!is_good_object (&new_cond))
2704 cond_initialization_lock.unlock ();
2709 if (efault.faulted ())
2712 cond_initialization_lock.unlock ();
2717 cond_initialization_lock.unlock ();
2723 pthread_cond_broadcast (pthread_cond_t *cond)
2725 if (pthread_cond::is_initializer (cond))
2727 if (!pthread_cond::is_good_object (cond))
2730 (*cond)->unblock (true);
2736 pthread_cond_signal (pthread_cond_t *cond)
2738 if (pthread_cond::is_initializer (cond))
2740 if (!pthread_cond::is_good_object (cond))
2743 (*cond)->unblock (false);
2749 __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2750 PLARGE_INTEGER waitlength)
2752 if (!pthread_mutex::is_good_object (mutex))
2754 if (!(*mutex)->can_be_unlocked ())
2757 if (pthread_cond::is_initializer (cond))
2758 pthread_cond::init (cond, NULL);
2759 if (!pthread_cond::is_good_object (cond))
2762 return (*cond)->wait (*mutex, waitlength);
2766 pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
2767 const struct timespec *abstime)
2770 LARGE_INTEGER timeout;
2773 if (efault.faulted ())
2776 pthread_testcancel ();
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)
2784 clock_gettime ((*cond)->clock_id, &tp);
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))
2792 timeout.QuadPart = abstime->tv_sec * NSPERSEC
2793 + (abstime->tv_nsec + 99LL) / 100LL;
2795 switch ((*cond)->clock_id)
2797 case CLOCK_REALTIME:
2798 timeout.QuadPart += FACTOR;
2801 /* other clocks must be handled as relative timeout */
2802 timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
2803 timeout.QuadPart *= -1LL;
2806 return __pthread_cond_dowait (cond, mutex, &timeout);
2810 pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
2812 pthread_testcancel ();
2814 return __pthread_cond_dowait (cond, mutex, NULL);
2818 pthread_condattr_init (pthread_condattr_t *condattr)
2820 if (pthread_condattr::is_good_object (condattr))
2823 *condattr = new pthread_condattr;
2824 if (!pthread_condattr::is_good_object (condattr))
2834 pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
2836 if (!pthread_condattr::is_good_object (attr))
2838 *pshared = (*attr)->shared;
2843 pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared)
2845 if (!pthread_condattr::is_good_object (attr))
2847 if ((pshared < 0) || (pshared > 1))
2849 /* shared cond vars not currently supported */
2850 if (pshared != PTHREAD_PROCESS_PRIVATE)
2852 (*attr)->shared = pshared;
2857 pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t *clock_id)
2859 if (!pthread_condattr::is_good_object (attr))
2861 *clock_id = (*attr)->clock_id;
2866 pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
2868 if (!pthread_condattr::is_good_object (attr))
2872 case CLOCK_REALTIME:
2873 case CLOCK_MONOTONIC:
2878 (*attr)->clock_id = clock_id;
2883 pthread_condattr_destroy (pthread_condattr_t *condattr)
2885 if (!pthread_condattr::is_good_object (condattr))
2893 pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
2895 if (pthread_rwlock::is_initializer (rwlock))
2897 if (!pthread_rwlock::is_good_object (rwlock))
2900 if ((*rwlock)->writer || (*rwlock)->readers ||
2901 (*rwlock)->waiting_readers || (*rwlock)->waiting_writers)
2911 pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
2913 pthread_rwlock_t new_rwlock;
2915 if (attr && !pthread_rwlockattr::is_good_object (attr))
2918 rwlock_initialization_lock.lock ();
2920 new_rwlock = new pthread_rwlock (attr ? (*attr) : NULL);
2921 if (!is_good_object (&new_rwlock))
2924 rwlock_initialization_lock.unlock ();
2929 if (efault.faulted ())
2932 rwlock_initialization_lock.unlock ();
2936 *rwlock = new_rwlock;
2937 rwlock_initialization_lock.unlock ();
2943 pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
2945 pthread_testcancel ();
2947 if (pthread_rwlock::is_initializer (rwlock))
2948 pthread_rwlock::init (rwlock, NULL);
2949 if (!pthread_rwlock::is_good_object (rwlock))
2952 return (*rwlock)->rdlock ();
2956 pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
2958 if (pthread_rwlock::is_initializer (rwlock))
2959 pthread_rwlock::init (rwlock, NULL);
2960 if (!pthread_rwlock::is_good_object (rwlock))
2963 return (*rwlock)->tryrdlock ();
2967 pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
2969 pthread_testcancel ();
2971 if (pthread_rwlock::is_initializer (rwlock))
2972 pthread_rwlock::init (rwlock, NULL);
2973 if (!pthread_rwlock::is_good_object (rwlock))
2976 return (*rwlock)->wrlock ();
2980 pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
2982 if (pthread_rwlock::is_initializer (rwlock))
2983 pthread_rwlock::init (rwlock, NULL);
2984 if (!pthread_rwlock::is_good_object (rwlock))
2987 return (*rwlock)->trywrlock ();
2991 pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
2993 if (pthread_rwlock::is_initializer (rwlock))
2995 if (!pthread_rwlock::is_good_object (rwlock))
2998 return (*rwlock)->unlock ();
3002 pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
3004 if (pthread_rwlockattr::is_good_object (rwlockattr))
3007 *rwlockattr = new pthread_rwlockattr;
3008 if (!pthread_rwlockattr::is_good_object (rwlockattr))
3010 delete (*rwlockattr);
3018 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
3020 if (!pthread_rwlockattr::is_good_object (attr))
3022 *pshared = (*attr)->shared;
3027 pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
3029 if (!pthread_rwlockattr::is_good_object (attr))
3031 if ((pshared < 0) || (pshared > 1))
3033 /* shared rwlock vars not currently supported */
3034 if (pshared != PTHREAD_PROCESS_PRIVATE)
3036 (*attr)->shared = pshared;
3041 pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
3043 if (!pthread_rwlockattr::is_good_object (rwlockattr))
3045 delete (*rwlockattr);
3052 pthread_kill (pthread_t thread, int sig)
3054 // lock myself, for the use of thread2signal
3055 // two different kills might clash: FIXME
3057 if (!pthread::is_good_object (&thread))
3062 si.si_code = SI_USER;
3063 si.si_pid = myself->pid;
3064 si.si_uid = myself->uid;
3070 thread->cygtls->set_threadkill ();
3071 rval = sig_send (NULL, si, thread->cygtls);
3074 switch (WaitForSingleObject (thread->win32_obj_id, 0))
3089 pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
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);
3097 pthread_sigqueue (pthread_t *thread, int sig, const union sigval value)
3101 if (!pthread::is_good_object (thread))
3103 if (!(*thread)->valid)
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);
3117 pthread_equal (pthread_t t1, pthread_t t2)
3119 return pthread::equal (t1, t2);
3125 pthread_mutex::init (pthread_mutex_t *mutex,
3126 const pthread_mutexattr_t *attr,
3127 const pthread_mutex_t initializer)
3129 if (attr && !pthread_mutexattr::is_good_object (attr))
3132 mutex_initialization_lock.lock ();
3133 if (initializer == NULL || pthread_mutex::is_initializer (mutex))
3135 pthread_mutex_t new_mutex = new pthread_mutex (attr ? (*attr) : NULL);
3136 if (!is_good_object (&new_mutex))
3139 mutex_initialization_lock.unlock ();
3143 if (!attr && initializer)
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;
3154 if (efault.faulted ())
3157 mutex_initialization_lock.unlock ();
3163 mutex_initialization_lock.unlock ();
3164 pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
3170 pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
3173 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
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. */
3184 pthread_mutex_lock (pthread_mutex_t *mutex)
3186 if (pthread_mutex::is_initializer (mutex))
3187 pthread_mutex::init (mutex, NULL, *mutex);
3188 if (!pthread_mutex::is_good_object (mutex))
3190 return (*mutex)->lock ();
3194 pthread_mutex_trylock (pthread_mutex_t *mutex)
3196 if (pthread_mutex::is_initializer (mutex))
3197 pthread_mutex::init (mutex, NULL, *mutex);
3198 if (!pthread_mutex::is_good_object (mutex))
3200 return (*mutex)->trylock ();
3204 pthread_mutex_unlock (pthread_mutex_t *mutex)
3206 if (pthread_mutex::is_initializer (mutex))
3208 if (!pthread_mutex::is_good_object (mutex))
3210 return (*mutex)->unlock ();
3214 pthread_mutex_destroy (pthread_mutex_t *mutex)
3218 if (pthread_mutex::is_initializer (mutex))
3220 if (!pthread_mutex::is_good_object (mutex))
3223 rv = (*mutex)->destroy ();
3232 pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
3241 pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
3243 pthread_spinlock_t new_spinlock = new pthread_spinlock (pshared);
3244 if (!is_good_object (&new_spinlock))
3246 delete new_spinlock;
3251 if (efault.faulted ())
3253 delete new_spinlock;
3257 *spinlock = new_spinlock;
3258 pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
3264 pthread_spin_lock (pthread_spinlock_t *spinlock)
3266 if (!pthread_spinlock::is_good_object (spinlock))
3268 return (*spinlock)->lock ();
3272 pthread_spin_trylock (pthread_spinlock_t *spinlock)
3274 if (!pthread_spinlock::is_good_object (spinlock))
3276 return (*spinlock)->trylock ();
3280 pthread_spin_unlock (pthread_spinlock_t *spinlock)
3282 if (!pthread_spinlock::is_good_object (spinlock))
3284 return (*spinlock)->unlock ();
3288 pthread_spin_destroy (pthread_spinlock_t *spinlock)
3290 if (!pthread_spinlock::is_good_object (spinlock))
3292 return (*spinlock)->destroy ();
3295 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3298 pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr,
3301 if (!pthread_mutexattr::is_good_object (attr))
3307 pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr,
3310 if (!pthread_mutexattr::is_good_object (attr))
3312 *pshared = (*attr)->pshared;
3317 pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type)
3319 if (!pthread_mutexattr::is_good_object (attr))
3321 *type = (*attr)->mutextype;
3325 /* FIXME: write and test process shared mutex's. */
3327 pthread_mutexattr_init (pthread_mutexattr_t *attr)
3329 if (pthread_mutexattr::is_good_object (attr))
3332 *attr = new pthread_mutexattr ();
3333 if (!pthread_mutexattr::is_good_object (attr))
3343 pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
3345 if (!pthread_mutexattr::is_good_object (attr))
3353 /* Win32 doesn't support mutex priorities */
3355 pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol)
3357 if (!pthread_mutexattr::is_good_object (attr))
3362 /* Win32 doesn't support mutex priorities */
3364 pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr,
3367 if (!pthread_mutexattr::is_good_object (attr))
3373 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr,
3376 if (!pthread_mutexattr::is_good_object (attr))
3382 pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared)
3384 if (!pthread_mutexattr::is_good_object (attr))
3386 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3389 if (pshared != PTHREAD_PROCESS_PRIVATE)
3391 (*attr)->pshared = pshared;
3395 /* see pthread_mutex_gettype */
3397 pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type)
3399 if (!pthread_mutexattr::is_good_object (attr))
3404 case PTHREAD_MUTEX_ERRORCHECK:
3405 case PTHREAD_MUTEX_RECURSIVE:
3406 case PTHREAD_MUTEX_NORMAL:
3407 (*attr)->mutextype = type;
3418 List<semaphore> semaphore::semaphores;
3420 semaphore::semaphore (int pshared, unsigned int value)
3421 : verifyable_object (SEM_MAGIC),
3423 currentvalue (value),
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)
3434 semaphores.insert (this);
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. */
3447 char name[MAX_PATH];
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)
3454 if (GetLastError () == ERROR_ALREADY_EXISTS && (oflag & O_EXCL))
3457 CloseHandle (this->win32_obj_id);
3461 semaphores.insert (this);
3464 semaphore::~semaphore ()
3467 CloseHandle (win32_obj_id);
3469 semaphores.remove (this);
3475 if (ReleaseSemaphore (win32_obj_id, 1, ¤tvalue))
3480 semaphore::_getvalue (int *sval)
3484 switch (WaitForSingleObject (win32_obj_id, 0))
3487 ReleaseSemaphore (win32_obj_id, 1, &val);
3501 semaphore::_trywait ()
3503 /* FIXME: signals should be able to interrupt semaphores...
3504 We probably need WaitForMultipleObjects here. */
3505 if (WaitForSingleObject (win32_obj_id, 0) == WAIT_TIMEOUT)
3515 semaphore::_timedwait (const struct timespec *abstime)
3517 LARGE_INTEGER timeout;
3520 if (efault.faulted ())
3522 /* According to SUSv3, abstime need not be checked for validity,
3523 if the semaphore can be locked immediately. */
3530 timeout.QuadPart = abstime->tv_sec * NSPERSEC
3531 + (abstime->tv_nsec + 99) / 100 + FACTOR;
3533 switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
3542 set_errno (ETIMEDOUT);
3545 pthread_printf ("cancelable_wait failed. %E");
3555 switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
3564 pthread_printf ("cancelable_wait failed. %E");
3571 semaphore::_fixup_after_fork ()
3573 if (shared == PTHREAD_PROCESS_PRIVATE)
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,
3580 api_fatal ("failed to create new win32 semaphore, error %d");
3585 semaphore::_terminate ()
3587 int _sem_close (sem_t *, bool);
3590 _sem_close (sem, false);
3593 /* static members */
3596 semaphore::init (sem_t *sem, int pshared, unsigned int value)
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
3603 if (is_good_object (sem))
3605 paranoid_printf ("potential attempt to reinitialise a semaphore");
3608 if (value > SEM_VALUE_MAX)
3614 *sem = new semaphore (pshared, value);
3616 if (!is_good_object (sem))
3627 semaphore::destroy (sem_t *sem)
3629 if (!is_good_object (sem))
3635 /* It's invalid to destroy a semaphore not opened with sem_init. */
3636 if ((*sem)->fd != -1)
3642 /* FIXME - new feature - test for busy against threads... */
3650 semaphore::close (sem_t *sem)
3652 if (!is_good_object (sem))
3658 /* It's invalid to close a semaphore not opened with sem_open. */
3659 if ((*sem)->fd == -1)
3671 semaphore::open (unsigned long long hash, LUID luid, int fd, int oflag,
3672 mode_t mode, unsigned int value, bool &wasopen)
3674 if (value > SEM_VALUE_MAX)
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)
3690 semaphores.mx.unlock ();
3693 semaphores.mx.unlock ();
3696 sem_t *sem = new sem_t;
3703 *sem = new semaphore (hash, luid, fd, sem, oflag, mode, value);
3705 if (!is_good_object (sem))
3715 semaphore::wait (sem_t *sem)
3717 pthread_testcancel ();
3719 if (!is_good_object (sem))
3725 return (*sem)->_wait ();
3729 semaphore::trywait (sem_t *sem)
3731 if (!is_good_object (sem))
3737 return (*sem)->_trywait ();
3741 semaphore::timedwait (sem_t *sem, const struct timespec *abstime)
3743 if (!is_good_object (sem))
3749 return (*sem)->_timedwait (abstime);
3753 semaphore::post (sem_t *sem)
3755 if (!is_good_object (sem))
3766 semaphore::getvalue (sem_t *sem, int *sval)
3769 if (efault.faulted () || !is_good_object (sem))
3775 return (*sem)->_getvalue (sval);
3779 semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
3780 LUID *sluid, unsigned int *sval)
3783 if (efault.faulted () || !is_good_object (sem))
3788 if ((*sfd = (*sem)->fd) < 0)
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);
3802 pthread_null::get_null_pthread ()
3804 /* because of weird entry points */
3805 _instance.magic = 0;
3809 pthread_null::pthread_null ()
3811 attr.joinable = PTHREAD_CREATE_DETACHED;
3812 /* Mark ourselves as invalid */
3816 pthread_null::~pthread_null ()
3821 pthread_null::create (void *(*)(void *), pthread_attr *, void *)
3827 pthread_null::exit (void *value_ptr)
3829 _my_tls.remove (INFINITE);
3834 pthread_null::cancel ()
3840 pthread_null::testcancel ()
3845 pthread_null::setcancelstate (int state, int *oldstate)
3851 pthread_null::setcanceltype (int type, int *oldtype)
3857 pthread_null::push_cleanup_handler (__pthread_cleanup_handler *handler)
3862 pthread_null::pop_cleanup_handler (int const execute)
3867 pthread_null::getsequence_np ()
3872 pthread_null pthread_null::_instance;