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. */
30 #include "miscfuncs.h"
35 #include "perprocess.h"
42 extern "C" void __fp_lock_all ();
43 extern "C" void __fp_unlock_all ();
44 extern "C" int valid_sched_parameters(const struct sched_param
*);
45 extern "C" int sched_set_thread_priority(HANDLE thread
, int priority
);
46 static inline verifyable_object_state
47 verifyable_object_isvalid (void const * objectptr
, thread_magic_t magic
,
48 void *static_ptr1
= NULL
,
49 void *static_ptr2
= NULL
,
50 void *static_ptr3
= NULL
);
52 extern int threadsafe
;
54 const pthread_t
pthread_mutex::_new_mutex
= (pthread_t
) 1;
55 const pthread_t
pthread_mutex::_unlocked_mutex
= (pthread_t
) 2;
56 const pthread_t
pthread_mutex::_destroyed_mutex
= (pthread_t
) 3;
59 pthread_mutex::no_owner()
64 debug_printf ("NULL owner value");
67 else if (owner
== _destroyed_mutex
)
69 paranoid_printf ("attempt to use destroyed mutex");
72 else if (owner
== _new_mutex
|| owner
== _unlocked_mutex
)
80 extern "C" struct _reent
*
83 return &_my_tls
.local_clib
;
87 __cygwin_lock_init (_LOCK_T
*lock
)
89 *lock
= _LOCK_T_INITIALIZER
;
93 __cygwin_lock_init_recursive (_LOCK_T
*lock
)
95 *lock
= _LOCK_T_RECURSIVE_INITIALIZER
;
99 __cygwin_lock_fini (_LOCK_T
*lock
)
101 pthread_mutex_destroy ((pthread_mutex_t
*) lock
);
105 __cygwin_lock_lock (_LOCK_T
*lock
)
107 paranoid_printf ("threadcount %d. locking", MT_INTERFACE
->threadcount
);
108 pthread_mutex_lock ((pthread_mutex_t
*) lock
);
112 __cygwin_lock_trylock (_LOCK_T
*lock
)
114 return pthread_mutex_trylock ((pthread_mutex_t
*) lock
);
119 __cygwin_lock_unlock (_LOCK_T
*lock
)
121 pthread_mutex_unlock ((pthread_mutex_t
*) lock
);
122 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE
->threadcount
);
125 static inline verifyable_object_state
126 verifyable_object_isvalid (void const *objectptr
, thread_magic_t magic
, void *static_ptr1
,
127 void *static_ptr2
, void *static_ptr3
)
130 if (efault
.faulted (objectptr
))
131 return INVALID_OBJECT
;
133 verifyable_object
**object
= (verifyable_object
**) objectptr
;
135 if ((static_ptr1
&& *object
== static_ptr1
) ||
136 (static_ptr2
&& *object
== static_ptr2
) ||
137 (static_ptr3
&& *object
== static_ptr3
))
138 return VALID_STATIC_OBJECT
;
139 if ((*object
)->magic
!= magic
)
140 return INVALID_OBJECT
;
146 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
148 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
154 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
156 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
162 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
164 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
170 pthread_key::is_good_object (pthread_key_t
const *key
)
172 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
178 pthread_spinlock::is_good_object (pthread_spinlock_t
const *mutex
)
180 if (verifyable_object_isvalid (mutex
, PTHREAD_SPINLOCK_MAGIC
) != VALID_OBJECT
)
186 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
188 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
194 pthread_mutex::is_initializer (pthread_mutex_t
const *mutex
)
196 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
197 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
198 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
199 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) != VALID_STATIC_OBJECT
)
205 pthread_mutex::is_initializer_or_object (pthread_mutex_t
const *mutex
)
207 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
208 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
209 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
210 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == INVALID_OBJECT
)
215 /* FIXME: Accommodate PTHREAD_MUTEX_ERRORCHECK */
217 pthread_mutex::can_be_unlocked ()
219 pthread_t self
= pthread::self ();
220 /* Check if the mutex is owned by the current thread and can be unlocked.
221 * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
222 bool res
= type
== PTHREAD_MUTEX_NORMAL
|| no_owner ()
223 || (recursion_counter
== 1 && pthread::equal (owner
, self
));
224 pthread_printf ("recursion_counter %d res %d", recursion_counter
, res
);
229 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
231 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
236 inline bool __attribute__ ((used
))
237 pthread::is_good_object (pthread_t
const *thread
)
239 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
244 /* Thread synchronisation */
246 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
248 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
254 pthread_cond::is_initializer (pthread_cond_t
const *cond
)
256 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
262 pthread_cond::is_initializer_or_object (pthread_cond_t
const *cond
)
264 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
271 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
273 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
279 pthread_rwlock::is_initializer (pthread_rwlock_t
const *rwlock
)
281 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
287 pthread_rwlock::is_initializer_or_object (pthread_rwlock_t
const *rwlock
)
289 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
295 semaphore::is_good_object (sem_t
const * sem
)
297 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
305 pthread_mutex::init_mutex ();
306 pthread_cond::init_mutex ();
307 pthread_rwlock::init_mutex ();
311 MTinterface::fixup_before_fork ()
313 pthread_key::fixup_before_fork ();
316 /* This function is called from a single threaded process */
318 MTinterface::fixup_after_fork ()
320 pthread_key::fixup_after_fork ();
323 pthread::init_mainthread ();
325 pthread::fixup_after_fork ();
326 pthread_mutex::fixup_after_fork ();
327 pthread_cond::fixup_after_fork ();
328 pthread_rwlock::fixup_after_fork ();
329 semaphore::fixup_after_fork ();
336 pthread::init_mainthread ()
338 pthread
*thread
= _my_tls
.tid
;
341 thread
= new pthread ();
343 api_fatal ("failed to create mainthread object");
346 set_tls_self_pointer (thread
);
347 thread
->thread_id
= GetCurrentThreadId ();
348 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
349 GetCurrentProcess (), &thread
->win32_obj_id
,
350 0, FALSE
, DUPLICATE_SAME_ACCESS
))
351 api_fatal ("failed to create mainthread handle");
352 if (!thread
->create_cancel_event ())
353 api_fatal ("couldn't create cancel event for main thread");
354 VerifyHandle (thread
->win32_obj_id
);
355 thread
->postcreate ();
361 pthread
*thread
= _my_tls
.tid
;
364 thread
= pthread_null::get_null_pthread ();
365 set_tls_self_pointer (thread
);
371 pthread::set_tls_self_pointer (pthread
*thread
)
373 thread
->cygtls
= &_my_tls
;
374 _my_tls
.tid
= thread
;
377 List
<pthread
> pthread::threads
;
380 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
381 valid (false), suspended (false), canceled (false),
382 cancelstate (0), canceltype (0), cancel_event (0),
383 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
385 if (this != pthread_null::get_null_pthread ())
386 threads
.insert (this);
387 parent_tls
= &_my_tls
;
393 CloseHandle (win32_obj_id
);
395 CloseHandle (cancel_event
);
397 if (this != pthread_null::get_null_pthread ())
398 threads
.remove (this);
402 pthread::create_cancel_event ()
404 cancel_event
= ::CreateEvent (&sec_none_nih
, true, false, NULL
);
407 system_printf ("couldn't create cancel event, %E");
408 /* we need the event for correct behaviour */
415 pthread::precreate (pthread_attr
*newattr
)
417 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
419 /* already running ? */
425 attr
.joinable
= newattr
->joinable
;
426 attr
.contentionscope
= newattr
->contentionscope
;
427 attr
.inheritsched
= newattr
->inheritsched
;
428 attr
.stacksize
= newattr
->stacksize
;
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
= ::CreateThread (&sec_none_nih
, attr
.stacksize
,
459 thread_init_wrapper
, this, 0, &thread_id
);
463 thread_printf ("CreateThread failed: this %p, %E", this);
478 pthread::postcreate ()
482 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
483 /* FIXME: set the priority appropriately for system contention scope */
484 if (attr
.inheritsched
== PTHREAD_EXPLICIT_SCHED
)
486 /* FIXME: set the scheduling settings for the new thread */
487 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
492 pthread::exit (void *value_ptr
)
494 class pthread
*thread
= this;
496 // run cleanup handlers
497 pop_all_cleanup_handlers ();
499 pthread_key::run_all_destructors ();
502 // cleanup if thread is in detached state and not joined
503 if (equal (joiner
, thread
))
508 return_ptr
= value_ptr
;
512 if (_my_tls
.local_clib
.__sdidinit
< 0)
513 _my_tls
.local_clib
.__sdidinit
= 0;
514 (_reclaim_reent
) (_REENT
);
516 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
525 class pthread
*thread
= this;
526 class pthread
*self
= pthread::self ();
536 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
537 cancelstate
== PTHREAD_CANCEL_DISABLE
)
542 SetEvent (cancel_event
);
545 else if (equal (thread
, self
))
549 return 0; // Never reached
552 // cancel asynchronous
553 SuspendThread (win32_obj_id
);
554 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
557 context
.ContextFlags
= CONTEXT_CONTROL
;
558 GetThreadContext (win32_obj_id
, &context
);
559 context
.Eip
= (DWORD
) pthread::static_cancel_self
;
560 SetThreadContext (win32_obj_id
, &context
);
563 ResumeThread (win32_obj_id
);
568 /* TODO: Insert pthread_testcancel into the required functions.
570 Here are the lists of required and optional functions per POSIX.1-2001
571 and POSIX.1-2008. A star (*) indicates that the Cygwin function already
572 is a cancellation point (aka "calls pthread_testcancel"), an o (o)
573 indicates that the function is not implemented in Cygwin.
575 Required cancellation points:
603 * pthread_cond_timedwait ()
604 * pthread_cond_wait ()
606 * pthread_testcancel ()
637 Optional cancellation points:
642 catclose () Implemented externally: libcatgets
643 catgets () Implemented externally: libcatgets
644 catopen () Implemented externally: libcatgets
652 dbm_close () Implemented externally: libgdbm
653 dbm_delete () Implemented externally: libgdbm
654 dbm_fetch () Implemented externally: libgdbm
655 dbm_nextkey () Implemented externally: libgdbm
656 dbm_open () Implemented externally: libgdbm
657 dbm_store () Implemented externally: libgdbm
674 * fcntl () (any value)
729 getopt () (if opterr is nonzero)
749 iconv_close () Implemented externally: libiconv
750 iconv_open () Implemented externally: libiconv
782 o posix_trace_clear ()
783 o posix_trace_close ()
784 o posix_trace_create ()
785 o posix_trace_create_withlog ()
786 o posix_trace_eventtypelist_getnext_id ()
787 o posix_trace_eventtypelist_rewind ()
788 o posix_trace_flush ()
789 o posix_trace_get_attr ()
790 o posix_trace_get_filter ()
791 o posix_trace_get_status ()
792 o posix_trace_getnext_event ()
793 o posix_trace_open ()
794 o posix_trace_rewind ()
795 o posix_trace_set_filter ()
796 o posix_trace_shutdown ()
797 o posix_trace_timedgetnext_event ()
798 o posix_typed_mem_open ()
802 pthread_rwlock_rdlock ()
803 pthread_rwlock_timedrdlock ()
804 pthread_rwlock_timedwrlock ()
805 pthread_rwlock_wrlock ()
865 An implementation may also mark other functions not specified in the
866 standard as cancellation points. In particular, an implementation is
867 likely to mark any nonstandard function that may block as a
868 cancellation point. */
871 pthread::testcancel ()
873 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
876 /* We check for the canceled flag first. This allows to use the
877 pthread_testcancel function a lot without adding the overhead of
878 an OS call. Only if the thread is marked as canceled, we wait for
879 cancel_event being really set, on the off-chance that pthread_cancel
880 gets interrupted before calling SetEvent. */
883 WaitForSingleObject (cancel_event
, INFINITE
);
888 /* Return cancel event handle if it exists *and* cancel is not disabled.
889 This function is supposed to be used from other functions which are
890 cancelable and need the cancel event in a WFMO call. */
892 pthread::get_cancel_event ()
894 pthread_t thread
= pthread::self ();
896 return (thread
&& thread
->cancel_event
897 && thread
->cancelstate
!= PTHREAD_CANCEL_DISABLE
)
898 ? thread
->cancel_event
: NULL
;
902 pthread::static_cancel_self ()
904 pthread::self ()->cancel_self ();
908 cancelable_wait (HANDLE object
, DWORD timeout
,
909 const cw_cancel_action cancel_action
,
910 const enum cw_sig_wait sig_wait
)
914 HANDLE wait_objects
[3];
915 pthread_t thread
= pthread::self ();
917 /* Do not change the wait order.
918 The object must have higher priority than the cancel event,
919 because WaitForMultipleObjects will return the smallest index
920 if both objects are signaled. */
921 wait_objects
[num
++] = object
;
923 if (cancel_action
== cw_no_cancel
|| !pthread::is_good_object (&thread
) ||
924 thread
->cancelstate
== PTHREAD_CANCEL_DISABLE
)
925 cancel_n
= WAIT_TIMEOUT
+ 1;
928 cancel_n
= WAIT_OBJECT_0
+ num
++;
929 wait_objects
[cancel_n
] = thread
->cancel_event
;
933 if (sig_wait
== cw_sig_nosig
)
934 sig_n
= WAIT_TIMEOUT
+ 1;
937 sig_n
= WAIT_OBJECT_0
+ num
++;
938 wait_objects
[sig_n
] = signal_arrived
;
943 res
= WaitForMultipleObjects (num
, wait_objects
, FALSE
, timeout
);
946 if (cancel_action
== cw_cancel_self
)
947 pthread::static_cancel_self ();
950 else if (res
!= sig_n
)
952 else if (sig_wait
== cw_sig_eintr
)
956 _my_tls
.call_signal_handler ();
965 pthread::setcancelstate (int state
, int *oldstate
)
971 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
976 *oldstate
= cancelstate
;
986 pthread::setcanceltype (int type
, int *oldtype
)
992 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
997 *oldtype
= canceltype
;
1007 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
1009 if (this != self ())
1011 api_fatal ("Attempt to push a cleanup handler across threads");
1012 handler
->next
= cleanup_stack
;
1013 cleanup_stack
= handler
;
1017 pthread::pop_cleanup_handler (int const execute
)
1019 if (this != self ())
1020 // TODO: send a signal or something to the thread ?
1021 api_fatal ("Attempt to execute a cleanup handler across threads");
1025 if (cleanup_stack
!= NULL
)
1027 __pthread_cleanup_handler
*handler
= cleanup_stack
;
1030 (*handler
->function
) (handler
->arg
);
1031 cleanup_stack
= handler
->next
;
1038 pthread::pop_all_cleanup_handlers ()
1040 while (cleanup_stack
!= NULL
)
1041 pop_cleanup_handler (1);
1045 pthread::cancel_self ()
1047 exit (PTHREAD_CANCELED
);
1051 pthread::get_thread_id ()
1057 pthread::_fixup_after_fork ()
1059 /* set thread to not running if it is not the forking thread */
1060 if (this != pthread::self ())
1064 win32_obj_id
= NULL
;
1066 cancel_event
= NULL
;
1071 pthread::suspend_except_self ()
1073 if (valid
&& this != pthread::self ())
1074 SuspendThread (win32_obj_id
);
1081 ResumeThread (win32_obj_id
);
1084 /* instance members */
1086 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
1087 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
1088 inheritsched (PTHREAD_INHERIT_SCHED
), stackaddr (NULL
), stacksize (0)
1090 schedparam
.sched_priority
= 0;
1093 pthread_attr::~pthread_attr ()
1097 pthread_condattr::pthread_condattr ():verifyable_object
1098 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1102 pthread_condattr::~pthread_condattr ()
1106 List
<pthread_cond
> pthread_cond::conds
;
1108 /* This is used for cond creation protection within a single process only */
1109 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
1111 /* We can only be called once.
1112 TODO: (no rush) use a non copied memory section to
1113 hold an initialization flag. */
1115 pthread_cond::init_mutex ()
1117 if (!cond_initialization_lock
.init ())
1118 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
1121 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
1122 verifyable_object (PTHREAD_COND_MAGIC
),
1123 shared (0), waiting (0), pending (0), sem_wait (NULL
),
1124 mtx_cond(NULL
), next (NULL
)
1126 pthread_mutex
*verifyable_mutex_obj
;
1129 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1135 verifyable_mutex_obj
= &mtx_in
;
1136 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1138 thread_printf ("Internal cond mutex is not valid. this %p", this);
1143 * Change the mutex type to NORMAL.
1144 * This mutex MUST be of type normal
1146 mtx_in
.set_type (PTHREAD_MUTEX_NORMAL
);
1148 verifyable_mutex_obj
= &mtx_out
;
1149 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1151 thread_printf ("Internal cond mutex is not valid. this %p", this);
1155 /* Change the mutex type to NORMAL to speed up mutex operations */
1156 mtx_out
.set_type (PTHREAD_MUTEX_NORMAL
);
1158 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1161 pthread_printf ("CreateSemaphore failed. %E");
1166 conds
.insert (this);
1169 pthread_cond::~pthread_cond ()
1172 CloseHandle (sem_wait
);
1174 conds
.remove (this);
1178 pthread_cond::unblock (const bool all
)
1180 unsigned long releaseable
;
1183 * Block outgoing threads (and avoid simultanous unblocks)
1187 releaseable
= waiting
- pending
;
1190 unsigned long released
;
1195 * Block incoming threads until all waiting threads are released.
1200 * Calculate releaseable again because threads can enter until
1201 * the semaphore has been taken, but they can not leave, therefore pending
1202 * is unchanged and releaseable can only get higher
1204 releaseable
= waiting
- pending
;
1207 released
= all
? releaseable
: 1;
1208 pending
+= released
;
1212 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
1216 * And let the threads release.
1222 pthread_cond::wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
)
1227 if (InterlockedIncrement ((long *)&waiting
) == 1)
1229 else if (mtx_cond
!= mutex
)
1231 InterlockedDecrement ((long *)&waiting
);
1238 * Release the mutex and wait on semaphore
1243 rv
= cancelable_wait (sem_wait
, dwMilliseconds
, cw_no_cancel_self
, cw_sig_eintr
);
1247 if (rv
!= WAIT_OBJECT_0
)
1250 * It might happen that a signal is sent while the thread got canceled
1251 * or timed out. Try to take one.
1252 * If the thread gets one than a signal|broadcast is in progress.
1254 if (WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
1256 * thread got cancelled ot timed out while a signalling is in progress.
1257 * Set wait result back to signaled
1262 InterlockedDecrement ((long *)&waiting
);
1264 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
1266 * All signaled threads are released,
1267 * new threads can enter Wait
1276 if (rv
== WAIT_CANCELED
)
1277 pthread::static_cancel_self ();
1278 else if (rv
== WAIT_SIGNALED
)
1279 /* SUSv3 states: If a signal is delivered to a thread waiting for a
1280 condition variable, upon return from the signal handler the thread
1281 resumes waiting for the condition variable as if it was not
1282 interrupted, or it shall return zero due to spurious wakeup.
1283 We opt for the latter choice here. */
1285 else if (rv
== WAIT_TIMEOUT
)
1292 pthread_cond::_fixup_after_fork ()
1294 waiting
= pending
= 0;
1297 /* Unlock eventually locked mutexes */
1301 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1303 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1306 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1307 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1311 pthread_rwlockattr::~pthread_rwlockattr ()
1315 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
1317 /* This is used for rwlock creation protection within a single process only */
1318 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
1320 /* We can only be called once.
1321 TODO: (no rush) use a non copied memory section to
1322 hold an initialization flag. */
1324 pthread_rwlock::init_mutex ()
1326 if (!rwlock_initialization_lock
.init ())
1327 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1330 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
1331 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
1332 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
1333 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
1336 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
1337 pthread_cond
*verifyable_cond_obj
;
1339 if (!readers_mx
.init ())
1341 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1347 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1353 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1355 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1359 /* Change the mutex type to NORMAL to speed up mutex operations */
1360 mtx
.set_type (PTHREAD_MUTEX_NORMAL
);
1362 verifyable_cond_obj
= &cond_readers
;
1363 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1365 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1370 verifyable_cond_obj
= &cond_writers
;
1371 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1373 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1379 rwlocks
.insert (this);
1382 pthread_rwlock::~pthread_rwlock ()
1384 rwlocks
.remove (this);
1388 pthread_rwlock::rdlock ()
1391 struct RWLOCK_READER
*reader
;
1392 pthread_t self
= pthread::self ();
1396 reader
= lookup_reader (self
);
1399 if (reader
->n
< ULONG_MAX
)
1406 reader
= new struct RWLOCK_READER
;
1413 while (writer
|| waiting_writers
)
1415 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1418 cond_readers
.wait (&mtx
);
1421 pthread_cleanup_pop (0);
1424 reader
->thread
= self
;
1426 add_reader (reader
);
1435 pthread_rwlock::tryrdlock ()
1438 pthread_t self
= pthread::self ();
1442 if (writer
|| waiting_writers
|| lookup_reader (self
))
1446 struct RWLOCK_READER
*reader
;
1448 reader
= lookup_reader (self
);
1449 if (reader
&& reader
->n
< ULONG_MAX
)
1451 else if ((reader
= new struct RWLOCK_READER
))
1453 reader
->thread
= self
;
1455 add_reader (reader
);
1467 pthread_rwlock::wrlock ()
1470 pthread_t self
= pthread::self ();
1474 if (writer
== self
|| lookup_reader (self
))
1480 while (writer
|| readers
)
1482 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1485 cond_writers
.wait (&mtx
);
1488 pthread_cleanup_pop (0);
1500 pthread_rwlock::trywrlock ()
1503 pthread_t self
= pthread::self ();
1507 if (writer
|| readers
)
1518 pthread_rwlock::unlock ()
1521 pthread_t self
= pthread::self ();
1537 struct RWLOCK_READER
*reader
= lookup_reader (self
);
1544 if (--reader
->n
> 0)
1547 remove_reader (reader
);
1560 pthread_rwlock::add_reader (struct RWLOCK_READER
*rd
)
1562 List_insert (readers
, rd
);
1566 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1568 List_remove (readers_mx
, readers
, rd
);
1571 struct pthread_rwlock::RWLOCK_READER
*
1572 pthread_rwlock::lookup_reader (pthread_t thread
)
1576 struct RWLOCK_READER
*cur
= readers
;
1578 while (cur
&& cur
->thread
!= thread
)
1581 readers_mx
.unlock ();
1587 pthread_rwlock::rdlock_cleanup (void *arg
)
1589 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1591 --(rwlock
->waiting_readers
);
1593 rwlock
->mtx
.unlock ();
1597 pthread_rwlock::wrlock_cleanup (void *arg
)
1599 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1601 --(rwlock
->waiting_writers
);
1603 rwlock
->mtx
.unlock ();
1607 pthread_rwlock::_fixup_after_fork ()
1609 pthread_t self
= pthread::self ();
1610 struct RWLOCK_READER
**temp
= &readers
;
1612 waiting_readers
= 0;
1613 waiting_writers
= 0;
1615 if (!readers_mx
.init ())
1616 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1618 /* Unlock eventually locked mutex */
1621 * Remove all readers except self
1625 if ((*temp
)->thread
== self
)
1626 temp
= &((*temp
)->next
);
1629 struct RWLOCK_READER
*cur
= *temp
;
1630 *temp
= (*temp
)->next
;
1637 /* static members */
1638 /* This stores pthread_key information across fork() boundaries */
1639 List
<pthread_key
> pthread_key::keys
;
1641 /* non-static members */
1643 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1645 tls_index
= TlsAlloc ();
1646 if (tls_index
== TLS_OUT_OF_INDEXES
)
1652 pthread_key::~pthread_key ()
1654 /* We may need to make the list code lock the list during operations
1659 TlsFree (tls_index
);
1664 pthread_key::_fixup_before_fork ()
1670 pthread_key::_fixup_after_fork ()
1672 tls_index
= TlsAlloc ();
1673 if (tls_index
== TLS_OUT_OF_INDEXES
)
1674 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1679 pthread_key::run_destructor ()
1683 void *oldValue
= get ();
1687 destructor (oldValue
);
1692 /* pshared mutexs */
1694 /* static members */
1696 List
<pthread_mutex
> pthread_mutex::mutexes
;
1698 /* This is used for mutex creation protection within a single process only */
1699 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1702 pthread_mutex::init_mutex ()
1704 if (!mutex_initialization_lock
.init ())
1705 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1708 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1709 verifyable_object (0), /* set magic to zero initially */
1711 win32_obj_id (NULL
), owner (_new_mutex
),
1715 recursion_counter (0), condwaits (0),
1716 type (PTHREAD_MUTEX_ERRORCHECK
),
1717 pshared (PTHREAD_PROCESS_PRIVATE
)
1719 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
1722 /*attr checked in the C call */
1724 /* handled in the caller */;
1725 else if (attr
->pshared
!= PTHREAD_PROCESS_SHARED
)
1726 type
= attr
->mutextype
;
1728 return; /* Not implemented */
1730 magic
= PTHREAD_MUTEX_MAGIC
;
1731 mutexes
.insert (this);
1734 pthread_mutex::~pthread_mutex ()
1738 CloseHandle (win32_obj_id
);
1739 win32_obj_id
= NULL
;
1742 mutexes
.remove (this);
1743 owner
= _destroyed_mutex
;
1748 pthread_mutex::lock ()
1750 pthread_t self
= ::pthread_self ();
1753 if (InterlockedIncrement ((long *) &lock_counter
) == 1)
1755 else if (type
== PTHREAD_MUTEX_NORMAL
/* potentially causes deadlock */
1756 || !pthread::equal (owner
, self
))
1758 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
1763 InterlockedDecrement ((long *) &lock_counter
);
1764 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1765 result
= lock_recursive ();
1770 pthread_printf ("mutex %p, self %p, owner %p, lock_counter %d, recursion_counter %d",
1771 this, self
, owner
, lock_counter
, recursion_counter
);
1776 pthread_mutex::unlock ()
1779 pthread_t self
= ::pthread_self ();
1780 if (type
== PTHREAD_MUTEX_NORMAL
)
1781 /* no error checking */;
1782 else if (no_owner ())
1783 res
= type
== PTHREAD_MUTEX_ERRORCHECK
? EINVAL
: 0;
1784 else if (!pthread::equal (owner
, self
))
1786 if (!res
&& recursion_counter
> 0 && --recursion_counter
== 0)
1787 /* Don't try to unlock anything if recursion_counter == 0.
1788 This means the mutex was never locked or that we've forked. */
1790 owner
= (pthread_t
) _unlocked_mutex
;
1794 if (InterlockedDecrement ((long *) &lock_counter
))
1795 ::SetEvent (win32_obj_id
); // Another thread is waiting
1799 pthread_printf ("mutex %p, owner %p, self %p, lock_counter %d, recursion_counter %d, type %d, res %d",
1800 this, owner
, self
, lock_counter
, recursion_counter
, type
, res
);
1805 pthread_mutex::trylock ()
1807 pthread_t self
= ::pthread_self ();
1810 if (InterlockedCompareExchange ((long *) &lock_counter
, 1, 0) == 0)
1812 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1813 result
= lock_recursive ();
1821 pthread_mutex::destroy ()
1823 if (condwaits
|| trylock ())
1824 // Do not destroy a condwaited or locked mutex
1826 else if (recursion_counter
> 1)
1828 // Do not destroy a recursive locked mutex
1829 recursion_counter
--;
1838 pthread_mutex::_fixup_after_fork ()
1840 pthread_printf ("mutex %p", this);
1841 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1842 api_fatal ("pthread_mutex::_fixup_after_fork () doesn't understand PROCESS_SHARED mutex's");
1844 /* All waiting threads are gone after a fork */
1845 recursion_counter
= 0;
1849 tid
= 0xffffffff; /* Don't know the tid after a fork */
1851 win32_obj_id
= ::CreateEvent (&sec_none_nih
, false, false, NULL
);
1853 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 event for mutex");
1856 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1857 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_ERRORCHECK
)
1861 pthread_mutexattr::~pthread_mutexattr ()
1865 /* pshared spinlocks
1867 The infrastructure is provided by the underlying pthread_mutex class.
1868 The rest is a simplification implementing spin locking. */
1870 pthread_spinlock::pthread_spinlock (int pshared
) :
1871 pthread_mutex (NULL
)
1873 magic
= PTHREAD_SPINLOCK_MAGIC
;
1874 set_type (PTHREAD_MUTEX_NORMAL
);
1875 set_shared (pshared
);
1879 pthread_spinlock::lock ()
1881 pthread_t self
= ::pthread_self ();
1886 if (InterlockedExchange ((long *) &lock_counter
, 1) == 0)
1891 else if (pthread::equal (owner
, self
))
1893 else /* Minimal timeout to minimize CPU usage while still spinning. */
1894 cancelable_wait (win32_obj_id
, 1L, cw_no_cancel
, cw_sig_resume
);
1896 while (result
== -1);
1897 pthread_printf ("spinlock %p, self %p, owner %p", this, self
, owner
);
1902 pthread_spinlock::unlock ()
1904 pthread_t self
= ::pthread_self ();
1907 if (!pthread::equal (owner
, self
))
1911 owner
= (pthread_t
) _unlocked_mutex
;
1915 InterlockedExchange ((long *) &lock_counter
, 0);
1916 ::SetEvent (win32_obj_id
);
1919 pthread_printf ("spinlock %p, owner %p, self %p, res %d",
1920 this, owner
, self
, result
);
1925 pthread::thread_init_wrapper (void *arg
)
1927 pthread
*thread
= (pthread
*) arg
;
1928 set_tls_self_pointer (thread
);
1930 thread
->mutex
.lock ();
1932 // if thread is detached force cleanup on exit
1933 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
1934 thread
->joiner
= thread
;
1935 _my_tls
.sigmask
= thread
->parent_tls
->sigmask
;
1936 thread
->mutex
.unlock ();
1938 thread_printf ("started thread %p %p %p %p %p %p", arg
, &_my_tls
.local_clib
,
1939 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
1941 // call the user's thread
1942 void *ret
= thread
->function (thread
->arg
);
1946 return 0; // just for show. Never returns.
1950 pthread::getsequence_np ()
1952 return get_thread_id ();
1956 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
1957 void *(*start_routine
) (void *), void *arg
)
1959 if (attr
&& !pthread_attr::is_good_object (attr
))
1962 *thread
= new pthread ();
1963 if (!(*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
))
1974 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
1977 if (once_control
->state
)
1980 pthread_mutex_lock (&once_control
->mutex
);
1981 /* Here we must set a cancellation handler to unlock the mutex if needed */
1982 /* but a cancellation handler is not the right thing. We need this in the thread
1983 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
1984 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
1985 *on pthread_exit ();
1987 if (!once_control
->state
)
1990 once_control
->state
= 1;
1992 /* Here we must remove our cancellation handler */
1993 pthread_mutex_unlock (&once_control
->mutex
);
1998 pthread::cancel (pthread_t thread
)
2000 if (!is_good_object (&thread
))
2003 return thread
->cancel ();
2007 pthread::atforkprepare ()
2009 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
2018 MT_INTERFACE
->fixup_before_fork ();
2022 pthread::atforkparent ()
2026 callback
*cb
= MT_INTERFACE
->pthread_parent
;
2035 pthread::atforkchild ()
2037 MT_INTERFACE
->fixup_after_fork ();
2041 callback
*cb
= MT_INTERFACE
->pthread_child
;
2049 /* Register a set of functions to run before and after fork.
2050 prepare calls are called in LI-FC order.
2051 parent and child calls are called in FI-FC order. */
2053 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
2055 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
2058 prepcb
= new callback
;
2064 parentcb
= new callback
;
2074 childcb
= new callback
;
2087 prepcb
->cb
= prepare
;
2088 List_insert (MT_INTERFACE
->pthread_prepare
, prepcb
);
2092 parentcb
->cb
= parent
;
2093 callback
**t
= &MT_INTERFACE
->pthread_parent
;
2096 /* t = pointer to last next in the list */
2097 List_insert (*t
, parentcb
);
2101 childcb
->cb
= child
;
2102 callback
**t
= &MT_INTERFACE
->pthread_child
;
2105 /* t = pointer to last next in the list */
2106 List_insert (*t
, childcb
);
2112 pthread_attr_init (pthread_attr_t
*attr
)
2114 if (pthread_attr::is_good_object (attr
))
2117 *attr
= new pthread_attr
;
2118 if (!pthread_attr::is_good_object (attr
))
2128 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
2131 if (!pthread_attr::is_good_object (attr
))
2133 *inheritsched
= (*attr
)->inheritsched
;
2138 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
2139 struct sched_param
*param
)
2141 if (!pthread_attr::is_good_object (attr
))
2143 *param
= (*attr
)->schedparam
;
2147 /* From a pure code point of view, this should call a helper in sched.cc,
2148 to allow for someone adding scheduler policy changes to win32 in the future.
2149 However that's extremely unlikely, so short and sweet will do us */
2151 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
2153 if (!pthread_attr::is_good_object (attr
))
2155 *policy
= SCHED_FIFO
;
2161 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
2163 if (!pthread_attr::is_good_object (attr
))
2165 *contentionscope
= (*attr
)->contentionscope
;
2170 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
2172 if (!pthread_attr::is_good_object (attr
))
2174 if (detachstate
< 0 || detachstate
> 1)
2176 (*attr
)->joinable
= detachstate
;
2181 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
2183 if (!pthread_attr::is_good_object (attr
))
2185 *detachstate
= (*attr
)->joinable
;
2190 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
2192 if (!pthread_attr::is_good_object (attr
))
2194 if (inheritsched
!= PTHREAD_INHERIT_SCHED
2195 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
2197 (*attr
)->inheritsched
= inheritsched
;
2202 pthread_attr_setschedparam (pthread_attr_t
*attr
,
2203 const struct sched_param
*param
)
2205 if (!pthread_attr::is_good_object (attr
))
2207 if (!valid_sched_parameters (param
))
2209 (*attr
)->schedparam
= *param
;
2213 /* See __pthread_attr_getschedpolicy for some notes */
2215 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
2217 if (!pthread_attr::is_good_object (attr
))
2219 if (policy
!= SCHED_FIFO
)
2225 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
2227 if (!pthread_attr::is_good_object (attr
))
2229 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
2230 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2232 /* In future, we may be able to support system scope by escalating the thread
2233 priority to exceed the priority class. For now we only support PROCESS scope. */
2234 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2236 (*attr
)->contentionscope
= contentionscope
;
2241 pthread_attr_getstack (const pthread_attr_t
*attr
, void **addr
, size_t *size
)
2243 if (!pthread_attr::is_good_object (attr
))
2245 /* uses lowest address of stack on all platforms */
2246 *addr
= (void *)((int)(*attr
)->stackaddr
- (*attr
)->stacksize
);
2247 *size
= (*attr
)->stacksize
;
2252 pthread_attr_getstackaddr (const pthread_attr_t
*attr
, void **addr
)
2254 if (!pthread_attr::is_good_object (attr
))
2256 /* uses stack address, which is the higher address on platforms
2257 where the stack grows downwards, such as x86 */
2258 *addr
= (*attr
)->stackaddr
;
2263 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
2265 if (!pthread_attr::is_good_object (attr
))
2267 if (size
< PTHREAD_STACK_MIN
)
2269 (*attr
)->stacksize
= size
;
2274 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
2276 if (!pthread_attr::is_good_object (attr
))
2278 *size
= (*attr
)->stacksize
;
2283 pthread_attr_destroy (pthread_attr_t
*attr
)
2285 if (!pthread_attr::is_good_object (attr
))
2293 pthread::join (pthread_t
*thread
, void **return_val
)
2295 pthread_t joiner
= self ();
2297 joiner
->testcancel ();
2299 // Initialize return val with NULL
2303 if (!is_good_object (&joiner
))
2306 if (!is_good_object (thread
))
2309 if (equal (*thread
,joiner
))
2312 (*thread
)->mutex
.lock ();
2314 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2316 (*thread
)->mutex
.unlock ();
2321 (*thread
)->joiner
= joiner
;
2322 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2323 (*thread
)->mutex
.unlock ();
2325 switch (cancelable_wait ((*thread
)->win32_obj_id
, INFINITE
, cw_no_cancel_self
, cw_sig_resume
))
2329 *return_val
= (*thread
)->return_ptr
;
2333 // set joined thread back to joinable since we got canceled
2334 (*thread
)->joiner
= NULL
;
2335 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2336 joiner
->cancel_self ();
2340 // should never happen
2349 pthread::detach (pthread_t
*thread
)
2351 if (!is_good_object (thread
))
2354 (*thread
)->mutex
.lock ();
2355 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2357 (*thread
)->mutex
.unlock ();
2361 // check if thread is still alive
2362 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2364 // force cleanup on exit
2365 (*thread
)->joiner
= *thread
;
2366 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2367 (*thread
)->mutex
.unlock ();
2371 // thread has already terminated.
2372 (*thread
)->mutex
.unlock ();
2380 pthread::suspend (pthread_t
*thread
)
2382 if (!is_good_object (thread
))
2385 if ((*thread
)->suspended
== false)
2387 (*thread
)->suspended
= true;
2388 SuspendThread ((*thread
)->win32_obj_id
);
2396 pthread::resume (pthread_t
*thread
)
2398 if (!is_good_object (thread
))
2401 if ((*thread
)->suspended
== true)
2402 ResumeThread ((*thread
)->win32_obj_id
);
2403 (*thread
)->suspended
= false;
2409 pthread_getattr_np (pthread_t thread
, pthread_attr_t
*attr
)
2411 const size_t sizeof_tbi
= sizeof (THREAD_BASIC_INFORMATION
);
2412 PTHREAD_BASIC_INFORMATION tbi
;
2415 if (!pthread::is_good_object (&thread
))
2418 /* attr may not be pre-initialized */
2419 if (!pthread_attr::is_good_object (attr
))
2421 int rv
= pthread_attr_init (attr
);
2426 (*attr
)->joinable
= thread
->attr
.joinable
;
2427 (*attr
)->contentionscope
= thread
->attr
.contentionscope
;
2428 (*attr
)->inheritsched
= thread
->attr
.inheritsched
;
2429 (*attr
)->schedparam
= thread
->attr
.schedparam
;
2431 tbi
= (PTHREAD_BASIC_INFORMATION
) malloc (sizeof_tbi
);
2432 ret
= NtQueryInformationThread (thread
->win32_obj_id
, ThreadBasicInformation
,
2433 tbi
, sizeof_tbi
, NULL
);
2435 if (NT_SUCCESS (ret
))
2437 PNT_TIB tib
= tbi
->TebBaseAddress
;
2438 (*attr
)->stackaddr
= tib
->StackBase
;
2439 /* stack grows downwards on x86 systems */
2440 (*attr
)->stacksize
= (int)tib
->StackBase
- (int)tib
->StackLimit
;
2444 debug_printf ("NtQueryInformationThread(ThreadBasicInformation), "
2446 (*attr
)->stackaddr
= thread
->attr
.stackaddr
;
2447 (*attr
)->stacksize
= thread
->attr
.stacksize
;
2453 /* provided for source level compatability.
2454 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2457 pthread_getconcurrency ()
2459 return MT_INTERFACE
->concurrency
;
2462 /* keep this in sync with sched.cc */
2464 pthread_getschedparam (pthread_t thread
, int *policy
,
2465 struct sched_param
*param
)
2467 if (!pthread::is_good_object (&thread
))
2469 *policy
= SCHED_FIFO
;
2470 /* we don't return the current effective priority, we return the current
2471 requested priority */
2472 *param
= thread
->attr
.schedparam
;
2476 /* Thread Specific Data */
2478 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
2480 *key
= new pthread_key (destructor
);
2482 if (!pthread_key::is_good_object (key
))
2492 pthread_key_delete (pthread_key_t key
)
2494 if (!pthread_key::is_good_object (&key
))
2501 /* provided for source level compatability. See
2502 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2505 pthread_setconcurrency (int new_level
)
2509 MT_INTERFACE
->concurrency
= new_level
;
2513 /* keep syncronised with sched.cc */
2515 pthread_setschedparam (pthread_t thread
, int policy
,
2516 const struct sched_param
*param
)
2518 if (!pthread::is_good_object (&thread
))
2520 if (policy
!= SCHED_FIFO
)
2525 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
2527 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
2532 pthread_setschedprio (pthread_t thread
, int priority
)
2534 if (!pthread::is_good_object (&thread
))
2537 sched_set_thread_priority (thread
->win32_obj_id
, priority
);
2539 thread
->attr
.schedparam
.sched_priority
= priority
;
2544 pthread_setspecific (pthread_key_t key
, const void *value
)
2546 if (!pthread_key::is_good_object (&key
))
2553 pthread_getspecific (pthread_key_t key
)
2555 if (!pthread_key::is_good_object (&key
))
2558 return (key
)->get ();
2563 pthread_cond_destroy (pthread_cond_t
*cond
)
2565 if (pthread_cond::is_initializer (cond
))
2567 if (!pthread_cond::is_good_object (cond
))
2570 /* reads are atomic */
2571 if ((*cond
)->waiting
)
2581 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2583 pthread_cond_t new_cond
;
2585 if (attr
&& !pthread_condattr::is_good_object (attr
))
2588 cond_initialization_lock
.lock ();
2590 new_cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2591 if (!is_good_object (&new_cond
))
2594 cond_initialization_lock
.unlock ();
2599 if (efault
.faulted ())
2602 cond_initialization_lock
.unlock ();
2607 cond_initialization_lock
.unlock ();
2613 pthread_cond_broadcast (pthread_cond_t
*cond
)
2615 if (pthread_cond::is_initializer (cond
))
2617 if (!pthread_cond::is_good_object (cond
))
2620 (*cond
)->unblock (true);
2626 pthread_cond_signal (pthread_cond_t
*cond
)
2628 if (pthread_cond::is_initializer (cond
))
2630 if (!pthread_cond::is_good_object (cond
))
2633 (*cond
)->unblock (false);
2639 __pthread_cond_dowait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2642 if (!pthread_mutex::is_good_object (mutex
))
2644 if (!(*mutex
)->can_be_unlocked ())
2647 if (pthread_cond::is_initializer (cond
))
2648 pthread_cond::init (cond
, NULL
);
2649 if (!pthread_cond::is_good_object (cond
))
2652 return (*cond
)->wait (*mutex
, waitlength
);
2656 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2657 const struct timespec
*abstime
)
2663 if (efault
.faulted ())
2666 pthread_testcancel ();
2668 /* According to SUSv3, the abstime value must be checked for validity. */
2669 if (abstime
->tv_sec
< 0
2670 || abstime
->tv_nsec
< 0
2671 || abstime
->tv_nsec
> 999999999)
2674 gettimeofday (&tv
, NULL
);
2675 /* Check for immediate timeout before converting to microseconds, since
2676 the resulting value can easily overflow long. This also allows to
2677 evaluate microseconds directly in DWORD. */
2678 if (tv
.tv_sec
> abstime
->tv_sec
2679 || (tv
.tv_sec
== abstime
->tv_sec
2680 && tv
.tv_usec
> abstime
->tv_nsec
/ 1000))
2683 waitlength
= (abstime
->tv_sec
- tv
.tv_sec
) * 1000;
2684 waitlength
+= (abstime
->tv_nsec
/ 1000 - tv
.tv_usec
) / 1000;
2685 return __pthread_cond_dowait (cond
, mutex
, waitlength
);
2689 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
2691 pthread_testcancel ();
2693 return __pthread_cond_dowait (cond
, mutex
, INFINITE
);
2697 pthread_condattr_init (pthread_condattr_t
*condattr
)
2699 if (pthread_condattr::is_good_object (condattr
))
2702 *condattr
= new pthread_condattr
;
2703 if (!pthread_condattr::is_good_object (condattr
))
2713 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
2715 if (!pthread_condattr::is_good_object (attr
))
2717 *pshared
= (*attr
)->shared
;
2722 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
2724 if (!pthread_condattr::is_good_object (attr
))
2726 if ((pshared
< 0) || (pshared
> 1))
2728 /* shared cond vars not currently supported */
2729 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2731 (*attr
)->shared
= pshared
;
2736 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
2738 if (!pthread_condattr::is_good_object (condattr
))
2746 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
2748 if (pthread_rwlock::is_initializer (rwlock
))
2750 if (!pthread_rwlock::is_good_object (rwlock
))
2753 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
2754 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
2764 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2766 pthread_rwlock_t new_rwlock
;
2768 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2771 rwlock_initialization_lock
.lock ();
2773 new_rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2774 if (!is_good_object (&new_rwlock
))
2777 rwlock_initialization_lock
.unlock ();
2782 if (efault
.faulted ())
2785 rwlock_initialization_lock
.unlock ();
2789 *rwlock
= new_rwlock
;
2790 rwlock_initialization_lock
.unlock ();
2796 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
2798 pthread_testcancel ();
2800 if (pthread_rwlock::is_initializer (rwlock
))
2801 pthread_rwlock::init (rwlock
, NULL
);
2802 if (!pthread_rwlock::is_good_object (rwlock
))
2805 return (*rwlock
)->rdlock ();
2809 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
2811 if (pthread_rwlock::is_initializer (rwlock
))
2812 pthread_rwlock::init (rwlock
, NULL
);
2813 if (!pthread_rwlock::is_good_object (rwlock
))
2816 return (*rwlock
)->tryrdlock ();
2820 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
2822 pthread_testcancel ();
2824 if (pthread_rwlock::is_initializer (rwlock
))
2825 pthread_rwlock::init (rwlock
, NULL
);
2826 if (!pthread_rwlock::is_good_object (rwlock
))
2829 return (*rwlock
)->wrlock ();
2833 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
2835 if (pthread_rwlock::is_initializer (rwlock
))
2836 pthread_rwlock::init (rwlock
, NULL
);
2837 if (!pthread_rwlock::is_good_object (rwlock
))
2840 return (*rwlock
)->trywrlock ();
2844 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
2846 if (pthread_rwlock::is_initializer (rwlock
))
2848 if (!pthread_rwlock::is_good_object (rwlock
))
2851 return (*rwlock
)->unlock ();
2855 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
2857 if (pthread_rwlockattr::is_good_object (rwlockattr
))
2860 *rwlockattr
= new pthread_rwlockattr
;
2861 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2863 delete (*rwlockattr
);
2871 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
2873 if (!pthread_rwlockattr::is_good_object (attr
))
2875 *pshared
= (*attr
)->shared
;
2880 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
2882 if (!pthread_rwlockattr::is_good_object (attr
))
2884 if ((pshared
< 0) || (pshared
> 1))
2886 /* shared rwlock vars not currently supported */
2887 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2889 (*attr
)->shared
= pshared
;
2894 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
2896 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2898 delete (*rwlockattr
);
2905 pthread_kill (pthread_t thread
, int sig
)
2907 // lock myself, for the use of thread2signal
2908 // two different kills might clash: FIXME
2910 if (!pthread::is_good_object (&thread
))
2915 si
.si_code
= SI_USER
;
2916 si
.si_pid
= myself
->pid
;
2917 si
.si_uid
= myself
->uid
;
2923 thread
->cygtls
->set_threadkill ();
2924 rval
= sig_send (NULL
, si
, thread
->cygtls
);
2927 switch (WaitForSingleObject (thread
->win32_obj_id
, 0))
2942 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
2944 return handle_sigprocmask (operation
, set
, old_set
, _my_tls
.sigmask
);
2950 pthread_equal (pthread_t t1
, pthread_t t2
)
2952 return pthread::equal (t1
, t2
);
2958 pthread_mutex::init (pthread_mutex_t
*mutex
,
2959 const pthread_mutexattr_t
*attr
,
2960 const pthread_mutex_t initializer
)
2962 if (attr
&& !pthread_mutexattr::is_good_object (attr
))
2965 mutex_initialization_lock
.lock ();
2966 if (initializer
== NULL
|| pthread_mutex::is_initializer (mutex
))
2968 pthread_mutex_t new_mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2969 if (!is_good_object (&new_mutex
))
2972 mutex_initialization_lock
.unlock ();
2976 if (!attr
&& initializer
)
2978 if (initializer
== PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
)
2979 new_mutex
->type
= PTHREAD_MUTEX_RECURSIVE
;
2980 else if (initializer
== PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
)
2981 new_mutex
->type
= PTHREAD_MUTEX_NORMAL
;
2982 else if (initializer
== PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
)
2983 new_mutex
->type
= PTHREAD_MUTEX_ERRORCHECK
;
2987 if (efault
.faulted ())
2990 mutex_initialization_lock
.unlock ();
2996 mutex_initialization_lock
.unlock ();
2997 pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex
, attr
, initializer
);
3003 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
3006 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
3009 We can support mutex priorities in the future though:
3010 Store a priority with each mutex.
3011 When the mutex is optained, set the thread priority as appropriate
3012 When the mutex is released, reset the thread priority. */
3017 pthread_mutex_lock (pthread_mutex_t
*mutex
)
3019 if (pthread_mutex::is_initializer (mutex
))
3020 pthread_mutex::init (mutex
, NULL
, *mutex
);
3021 if (!pthread_mutex::is_good_object (mutex
))
3023 return (*mutex
)->lock ();
3027 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
3029 if (pthread_mutex::is_initializer (mutex
))
3030 pthread_mutex::init (mutex
, NULL
, *mutex
);
3031 if (!pthread_mutex::is_good_object (mutex
))
3033 return (*mutex
)->trylock ();
3037 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
3039 if (pthread_mutex::is_initializer (mutex
))
3041 if (!pthread_mutex::is_good_object (mutex
))
3043 return (*mutex
)->unlock ();
3047 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
3051 if (pthread_mutex::is_initializer (mutex
))
3053 if (!pthread_mutex::is_good_object (mutex
))
3056 rv
= (*mutex
)->destroy ();
3065 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
3074 pthread_spinlock::init (pthread_spinlock_t
*spinlock
, int pshared
)
3076 pthread_spinlock_t new_spinlock
= new pthread_spinlock (pshared
);
3077 if (!is_good_object (&new_spinlock
))
3079 delete new_spinlock
;
3084 if (efault
.faulted ())
3086 delete new_spinlock
;
3090 *spinlock
= new_spinlock
;
3091 pthread_printf ("*spinlock %p, pshared %d", *spinlock
, pshared
);
3097 pthread_spin_lock (pthread_spinlock_t
*spinlock
)
3099 if (!pthread_spinlock::is_good_object (spinlock
))
3101 return (*spinlock
)->lock ();
3105 pthread_spin_trylock (pthread_spinlock_t
*spinlock
)
3107 if (!pthread_spinlock::is_good_object (spinlock
))
3109 return (*spinlock
)->trylock ();
3113 pthread_spin_unlock (pthread_spinlock_t
*spinlock
)
3115 if (!pthread_spinlock::is_good_object (spinlock
))
3117 return (*spinlock
)->unlock ();
3121 pthread_spin_destroy (pthread_spinlock_t
*spinlock
)
3123 if (!pthread_spinlock::is_good_object (spinlock
))
3125 return (*spinlock
)->destroy ();
3128 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3131 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
3134 if (!pthread_mutexattr::is_good_object (attr
))
3140 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
3143 if (!pthread_mutexattr::is_good_object (attr
))
3145 *pshared
= (*attr
)->pshared
;
3150 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
3152 if (!pthread_mutexattr::is_good_object (attr
))
3154 *type
= (*attr
)->mutextype
;
3158 /* FIXME: write and test process shared mutex's. */
3160 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
3162 if (pthread_mutexattr::is_good_object (attr
))
3165 *attr
= new pthread_mutexattr ();
3166 if (!pthread_mutexattr::is_good_object (attr
))
3176 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
3178 if (!pthread_mutexattr::is_good_object (attr
))
3186 /* Win32 doesn't support mutex priorities */
3188 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
3190 if (!pthread_mutexattr::is_good_object (attr
))
3195 /* Win32 doesn't support mutex priorities */
3197 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
3200 if (!pthread_mutexattr::is_good_object (attr
))
3206 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
3209 if (!pthread_mutexattr::is_good_object (attr
))
3215 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
3217 if (!pthread_mutexattr::is_good_object (attr
))
3219 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3222 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
3224 (*attr
)->pshared
= pshared
;
3228 /* see pthread_mutex_gettype */
3230 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
3232 if (!pthread_mutexattr::is_good_object (attr
))
3237 case PTHREAD_MUTEX_ERRORCHECK
:
3238 case PTHREAD_MUTEX_RECURSIVE
:
3239 case PTHREAD_MUTEX_NORMAL
:
3240 (*attr
)->mutextype
= type
;
3251 List
<semaphore
> semaphore::semaphores
;
3253 semaphore::semaphore (int pshared
, unsigned int value
)
3254 : verifyable_object (SEM_MAGIC
),
3256 currentvalue (value
),
3261 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
3262 ? sec_all
: sec_none_nih
;
3263 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, NULL
);
3264 if (!this->win32_obj_id
)
3267 semaphores
.insert (this);
3270 semaphore::semaphore (unsigned long long shash
, LUID sluid
, int sfd
,
3271 sem_t
*ssem
, int oflag
, mode_t mode
, unsigned int value
)
3272 : verifyable_object (SEM_MAGIC
),
3273 shared (PTHREAD_PROCESS_SHARED
),
3274 currentvalue (value
), /* Unused for named semaphores. */
3280 char name
[MAX_PATH
];
3282 __small_sprintf (name
, "semaphore/%016X%08x%08x",
3283 hash
, luid
.HighPart
, luid
.LowPart
);
3284 this->win32_obj_id
= ::CreateSemaphore (&sec_all
, value
, LONG_MAX
, name
);
3285 if (!this->win32_obj_id
)
3287 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
3290 CloseHandle (this->win32_obj_id
);
3294 semaphores
.insert (this);
3297 semaphore::~semaphore ()
3300 CloseHandle (win32_obj_id
);
3302 semaphores
.remove (this);
3308 if (ReleaseSemaphore (win32_obj_id
, 1, ¤tvalue
))
3313 semaphore::_getvalue (int *sval
)
3317 switch (WaitForSingleObject (win32_obj_id
, 0))
3320 ReleaseSemaphore (win32_obj_id
, 1, &val
);
3334 semaphore::_trywait ()
3336 /* FIXME: signals should be able to interrupt semaphores...
3337 We probably need WaitForMultipleObjects here. */
3338 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
3348 semaphore::_timedwait (const struct timespec
*abstime
)
3354 if (efault
.faulted ())
3356 /* According to SUSv3, abstime need not be checked for validity,
3357 if the semaphore can be locked immediately. */
3364 gettimeofday (&tv
, NULL
);
3365 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
3366 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
3369 switch (cancelable_wait (win32_obj_id
, waitlength
, cw_cancel_self
, cw_sig_eintr
))
3378 set_errno (ETIMEDOUT
);
3381 pthread_printf ("cancelable_wait failed. %E");
3391 switch (cancelable_wait (win32_obj_id
, INFINITE
, cw_cancel_self
, cw_sig_eintr
))
3400 pthread_printf ("cancelable_wait failed. %E");
3407 semaphore::_fixup_after_fork ()
3409 if (shared
== PTHREAD_PROCESS_PRIVATE
)
3411 pthread_printf ("sem %x", this);
3412 /* FIXME: duplicate code here and in the constructor. */
3413 this->win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
3416 api_fatal ("failed to create new win32 semaphore, error %d");
3421 semaphore::_terminate ()
3423 int _sem_close (sem_t
*, bool);
3426 _sem_close (sem
, false);
3429 /* static members */
3432 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
3435 We can't tell the difference between reinitialising an
3436 existing semaphore and initialising a semaphore who's
3437 contents happen to be a valid pointer
3439 if (is_good_object (sem
))
3441 paranoid_printf ("potential attempt to reinitialise a semaphore");
3444 if (value
> SEM_VALUE_MAX
)
3450 *sem
= new semaphore (pshared
, value
);
3452 if (!is_good_object (sem
))
3463 semaphore::destroy (sem_t
*sem
)
3465 if (!is_good_object (sem
))
3471 /* It's invalid to destroy a semaphore not opened with sem_init. */
3472 if ((*sem
)->fd
!= -1)
3478 /* FIXME - new feature - test for busy against threads... */
3486 semaphore::close (sem_t
*sem
)
3488 if (!is_good_object (sem
))
3494 /* It's invalid to close a semaphore not opened with sem_open. */
3495 if ((*sem
)->fd
== -1)
3507 semaphore::open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
3508 mode_t mode
, unsigned int value
, bool &wasopen
)
3510 if (value
> SEM_VALUE_MAX
)
3516 /* sem_open is supposed to return the same pointer, if the same named
3517 semaphore is opened multiple times in the same process, as long as
3518 the semaphore hasn't been closed or unlinked in the meantime. */
3519 semaphores
.mx
.lock ();
3520 for (semaphore
*sema
= semaphores
.head
; sema
; sema
= sema
->next
)
3521 if (sema
->fd
>= 0 && sema
->hash
== hash
3522 && sema
->luid
.HighPart
== luid
.HighPart
3523 && sema
->luid
.LowPart
== sema
->luid
.LowPart
)
3526 semaphores
.mx
.unlock ();
3529 semaphores
.mx
.unlock ();
3532 sem_t
*sem
= new sem_t
;
3539 *sem
= new semaphore (hash
, luid
, fd
, sem
, oflag
, mode
, value
);
3541 if (!is_good_object (sem
))
3551 semaphore::wait (sem_t
*sem
)
3553 pthread_testcancel ();
3555 if (!is_good_object (sem
))
3561 return (*sem
)->_wait ();
3565 semaphore::trywait (sem_t
*sem
)
3567 if (!is_good_object (sem
))
3573 return (*sem
)->_trywait ();
3577 semaphore::timedwait (sem_t
*sem
, const struct timespec
*abstime
)
3579 if (!is_good_object (sem
))
3585 return (*sem
)->_timedwait (abstime
);
3589 semaphore::post (sem_t
*sem
)
3591 if (!is_good_object (sem
))
3602 semaphore::getvalue (sem_t
*sem
, int *sval
)
3605 if (efault
.faulted () || !is_good_object (sem
))
3611 return (*sem
)->_getvalue (sval
);
3615 semaphore::getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
3616 LUID
*sluid
, unsigned int *sval
)
3619 if (efault
.faulted () || !is_good_object (sem
))
3624 if ((*sfd
= (*sem
)->fd
) < 0)
3629 *shash
= (*sem
)->hash
;
3630 *sluid
= (*sem
)->luid
;
3631 /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3632 the sem_getvalue gets a pointer to int to return the value. Go figure! */
3633 return (*sem
)->_getvalue ((int *)sval
);
3638 pthread_null::get_null_pthread ()
3640 /* because of weird entry points */
3641 _instance
.magic
= 0;
3645 pthread_null::pthread_null ()
3647 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
3648 /* Mark ourselves as invalid */
3652 pthread_null::~pthread_null ()
3657 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
3663 pthread_null::exit (void *value_ptr
)
3665 _my_tls
.remove (INFINITE
);
3670 pthread_null::cancel ()
3676 pthread_null::testcancel ()
3681 pthread_null::setcancelstate (int state
, int *oldstate
)
3687 pthread_null::setcanceltype (int type
, int *oldtype
)
3693 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
3698 pthread_null::pop_cleanup_handler (int const execute
)
3703 pthread_null::getsequence_np ()
3708 pthread_null
pthread_null::_instance
;