1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008 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"
41 extern "C" void __fp_lock_all ();
42 extern "C" void __fp_unlock_all ();
43 static inline verifyable_object_state
44 verifyable_object_isvalid (void const * objectptr
, long magic
,
45 void *static_ptr1
= NULL
,
46 void *static_ptr2
= NULL
,
47 void *static_ptr3
= NULL
);
49 extern int threadsafe
;
52 extern "C" struct _reent
*
55 return &_my_tls
.local_clib
;
59 __cygwin_lock_init (_LOCK_T
*lock
)
61 *lock
= _LOCK_T_INITIALIZER
;
65 __cygwin_lock_init_recursive (_LOCK_T
*lock
)
67 *lock
= _LOCK_T_RECURSIVE_INITIALIZER
;
71 __cygwin_lock_fini (_LOCK_T
*lock
)
73 pthread_mutex_destroy ((pthread_mutex_t
*) lock
);
77 __cygwin_lock_lock (_LOCK_T
*lock
)
79 if (MT_INTERFACE
->threadcount
<= 1)
80 paranoid_printf ("threadcount %d. not locking", MT_INTERFACE
->threadcount
);
83 paranoid_printf ("threadcount %d. locking", MT_INTERFACE
->threadcount
);
84 pthread_mutex_lock ((pthread_mutex_t
*) lock
);
89 __cygwin_lock_trylock (_LOCK_T
*lock
)
91 return pthread_mutex_trylock ((pthread_mutex_t
*) lock
);
96 __cygwin_lock_unlock (_LOCK_T
*lock
)
98 if (MT_INTERFACE
->threadcount
<= 1)
99 paranoid_printf ("threadcount %d. not unlocking", MT_INTERFACE
->threadcount
);
102 pthread_mutex_unlock ((pthread_mutex_t
*) lock
);
103 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE
->threadcount
);
107 static inline verifyable_object_state
108 verifyable_object_isvalid (void const *objectptr
, long magic
, void *static_ptr1
,
109 void *static_ptr2
, void *static_ptr3
)
112 /* Check for NULL pointer specifically since it is a cheap test and avoids the
113 overhead of setting up the fault handler. */
114 if (!objectptr
|| efault
.faulted ())
115 return INVALID_OBJECT
;
117 verifyable_object
**object
= (verifyable_object
**) objectptr
;
119 if ((static_ptr1
&& *object
== static_ptr1
) ||
120 (static_ptr2
&& *object
== static_ptr2
) ||
121 (static_ptr3
&& *object
== static_ptr3
))
122 return VALID_STATIC_OBJECT
;
123 if ((*object
)->magic
!= magic
)
124 return INVALID_OBJECT
;
130 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
132 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
138 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
140 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
146 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
148 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
154 pthread_key::is_good_object (pthread_key_t
const *key
)
156 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
162 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
164 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
170 pthread_mutex::is_good_initializer (pthread_mutex_t
const *mutex
)
172 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
173 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
174 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
175 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) != VALID_STATIC_OBJECT
)
181 pthread_mutex::is_good_initializer_or_object (pthread_mutex_t
const *mutex
)
183 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
184 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
185 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
186 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == INVALID_OBJECT
)
192 pthread_mutex::can_be_unlocked (pthread_mutex_t
const *mutex
)
194 pthread_t self
= pthread::self ();
196 if (!is_good_object (mutex
))
198 /* Check if the mutex is owned by the current thread and can be unlocked.
199 * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
200 return ((*mutex
)->recursion_counter
== 1
201 && ((*mutex
)->owner
== MUTEX_OWNER_ANONYMOUS
202 || pthread::equal ((*mutex
)->owner
, self
)));
206 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
208 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
213 inline bool __attribute__ ((used
))
214 pthread::is_good_object (pthread_t
const *thread
)
216 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
221 /* Thread synchronisation */
223 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
225 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
231 pthread_cond::is_good_initializer (pthread_cond_t
const *cond
)
233 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
239 pthread_cond::is_good_initializer_or_object (pthread_cond_t
const *cond
)
241 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
248 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
250 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
256 pthread_rwlock::is_good_initializer (pthread_rwlock_t
const *rwlock
)
258 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
264 pthread_rwlock::is_good_initializer_or_object (pthread_rwlock_t
const *rwlock
)
266 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
272 semaphore::is_good_object (sem_t
const * sem
)
274 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
282 pthread_mutex::init_mutex ();
283 pthread_cond::init_mutex ();
284 pthread_rwlock::init_mutex ();
288 MTinterface::fixup_before_fork ()
290 pthread_key::fixup_before_fork ();
293 /* This function is called from a single threaded process */
295 MTinterface::fixup_after_fork ()
297 pthread_key::fixup_after_fork ();
300 pthread::init_mainthread ();
302 pthread::fixup_after_fork ();
303 pthread_mutex::fixup_after_fork ();
304 pthread_cond::fixup_after_fork ();
305 pthread_rwlock::fixup_after_fork ();
306 semaphore::fixup_after_fork ();
313 pthread::init_mainthread ()
315 pthread
*thread
= get_tls_self_pointer ();
318 thread
= new pthread ();
320 api_fatal ("failed to create mainthread object");
323 set_tls_self_pointer (thread
);
324 thread
->thread_id
= GetCurrentThreadId ();
325 if (!DuplicateHandle (hMainProc
, GetCurrentThread (), hMainProc
,
326 &thread
->win32_obj_id
, 0, FALSE
, DUPLICATE_SAME_ACCESS
))
327 api_fatal ("failed to create mainthread handle");
328 if (!thread
->create_cancel_event ())
329 api_fatal ("couldn't create cancel event for main thread");
330 VerifyHandle (thread
->win32_obj_id
);
331 thread
->postcreate ();
337 pthread
*thread
= get_tls_self_pointer ();
340 thread
= pthread_null::get_null_pthread ();
341 set_tls_self_pointer (thread
);
347 pthread::get_tls_self_pointer ()
353 pthread::set_tls_self_pointer (pthread
*thread
)
355 thread
->cygtls
= &_my_tls
;
356 _my_tls
.tid
= thread
;
359 List
<pthread
> pthread::threads
;
362 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
363 valid (false), suspended (false),
364 cancelstate (0), canceltype (0), cancel_event (0),
365 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
367 if (this != pthread_null::get_null_pthread ())
368 threads
.insert (this);
369 parent_tls
= &_my_tls
;
375 CloseHandle (win32_obj_id
);
377 CloseHandle (cancel_event
);
379 if (this != pthread_null::get_null_pthread ())
380 threads
.remove (this);
384 pthread::create_cancel_event ()
386 cancel_event
= ::CreateEvent (&sec_none_nih
, TRUE
, FALSE
, NULL
);
389 system_printf ("couldn't create cancel event, %E");
390 /* we need the event for correct behaviour */
397 pthread::precreate (pthread_attr
*newattr
)
399 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
401 /* already running ? */
407 attr
.joinable
= newattr
->joinable
;
408 attr
.contentionscope
= newattr
->contentionscope
;
409 attr
.inheritsched
= newattr
->inheritsched
;
410 attr
.stacksize
= newattr
->stacksize
;
413 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
415 thread_printf ("New thread object access mutex is not valid. this %p",
420 /* Change the mutex type to NORMAL to speed up mutex operations */
421 mutex
.type
= PTHREAD_MUTEX_NORMAL
;
422 if (!create_cancel_event ())
427 pthread::create (void *(*func
) (void *), pthread_attr
*newattr
,
440 win32_obj_id
= ::CreateThread (&sec_none_nih
, attr
.stacksize
,
441 thread_init_wrapper
, this, 0, &thread_id
);
445 thread_printf ("CreateThread failed: this %p, %E", this);
452 low_priority_sleep (0);
460 pthread::postcreate ()
464 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
465 /* FIXME: set the priority appropriately for system contention scope */
466 if (attr
.inheritsched
== PTHREAD_EXPLICIT_SCHED
)
468 /* FIXME: set the scheduling settings for the new thread */
469 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
474 pthread::exit (void *value_ptr
)
476 class pthread
*thread
= this;
478 // run cleanup handlers
479 pop_all_cleanup_handlers ();
481 pthread_key::run_all_destructors ();
484 // cleanup if thread is in detached state and not joined
485 if (equal (joiner
, thread
))
490 return_ptr
= value_ptr
;
494 if (_my_tls
.local_clib
.__sdidinit
< 0)
495 _my_tls
.local_clib
.__sdidinit
= 0;
496 (_reclaim_reent
) (_REENT
);
499 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
503 _my_tls
.remove (INFINITE
);
511 class pthread
*thread
= this;
512 class pthread
*self
= pthread::self ();
522 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
523 cancelstate
== PTHREAD_CANCEL_DISABLE
)
527 SetEvent (cancel_event
);
530 else if (equal (thread
, self
))
534 return 0; // Never reached
537 // cancel asynchronous
538 SuspendThread (win32_obj_id
);
539 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
542 context
.ContextFlags
= CONTEXT_CONTROL
;
543 GetThreadContext (win32_obj_id
, &context
);
544 context
.Eip
= (DWORD
) pthread::static_cancel_self
;
545 SetThreadContext (win32_obj_id
, &context
);
548 ResumeThread (win32_obj_id
);
552 TODO: insert pthread_testcancel into the required functions
553 the required function list is: *indicates done, X indicates not present in cygwin.
572 *pthread_cond_timedwait ()
573 *pthread_cond_wait ()
575 *pthread_testcancel ()
599 the optional list is:
719 Note, that for fcntl (), for any value of the cmd argument.
721 And we must not introduce cancellation points anywhere else that's part of the posix or
727 pthread::testcancel ()
729 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
732 if (WaitForSingleObject (cancel_event
, 0) == WAIT_OBJECT_0
)
737 pthread::static_cancel_self ()
739 pthread::self ()->cancel_self ();
743 cancelable_wait (HANDLE object
, DWORD timeout
,
744 const cw_cancel_action cancel_action
,
745 const enum cw_sig_wait sig_wait
)
749 HANDLE wait_objects
[3];
750 pthread_t thread
= pthread::self ();
752 /* Do not change the wait order.
753 The object must have higher priority than the cancel event,
754 because WaitForMultipleObjects will return the smallest index
755 if both objects are signaled. */
756 wait_objects
[num
++] = object
;
758 if (cancel_action
== cw_no_cancel
|| !pthread::is_good_object (&thread
) ||
759 thread
->cancelstate
== PTHREAD_CANCEL_DISABLE
)
760 cancel_n
= (DWORD
) -1;
763 cancel_n
= WAIT_OBJECT_0
+ num
++;
764 wait_objects
[cancel_n
] = thread
->cancel_event
;
768 if (sig_wait
== cw_sig_nosig
|| &_my_tls
!= _main_tls
)
772 sig_n
= WAIT_OBJECT_0
+ num
++;
773 wait_objects
[sig_n
] = signal_arrived
;
778 res
= WaitForMultipleObjects (num
, wait_objects
, FALSE
, timeout
);
781 if (cancel_action
== cw_cancel_self
)
782 pthread::static_cancel_self ();
785 else if (res
!= sig_n
)
787 else if (sig_wait
== cw_sig_eintr
)
791 _my_tls
.call_signal_handler ();
800 pthread::setcancelstate (int state
, int *oldstate
)
806 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
811 *oldstate
= cancelstate
;
821 pthread::setcanceltype (int type
, int *oldtype
)
827 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
832 *oldtype
= canceltype
;
842 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
846 api_fatal ("Attempt to push a cleanup handler across threads");
847 handler
->next
= cleanup_stack
;
848 cleanup_stack
= handler
;
852 pthread::pop_cleanup_handler (int const execute
)
855 // TODO: send a signal or something to the thread ?
856 api_fatal ("Attempt to execute a cleanup handler across threads");
860 if (cleanup_stack
!= NULL
)
862 __pthread_cleanup_handler
*handler
= cleanup_stack
;
865 (*handler
->function
) (handler
->arg
);
866 cleanup_stack
= handler
->next
;
873 pthread::pop_all_cleanup_handlers ()
875 while (cleanup_stack
!= NULL
)
876 pop_cleanup_handler (1);
880 pthread::cancel_self ()
882 exit (PTHREAD_CANCELED
);
886 pthread::get_thread_id ()
892 pthread::_fixup_after_fork ()
894 /* set thread to not running if it is not the forking thread */
895 if (this != pthread::self ())
905 pthread::suspend_except_self ()
907 if (valid
&& this != pthread::self ())
908 SuspendThread (win32_obj_id
);
915 ResumeThread (win32_obj_id
);
918 /* instance members */
920 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
921 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
922 inheritsched (PTHREAD_INHERIT_SCHED
), stacksize (0)
924 schedparam
.sched_priority
= 0;
927 pthread_attr::~pthread_attr ()
931 pthread_condattr::pthread_condattr ():verifyable_object
932 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
936 pthread_condattr::~pthread_condattr ()
940 List
<pthread_cond
> pthread_cond::conds
;
942 /* This is used for cond creation protection within a single process only */
943 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
945 /* We can only be called once.
946 TODO: (no rush) use a non copied memory section to
947 hold an initialization flag. */
949 pthread_cond::init_mutex ()
951 if (!cond_initialization_lock
.init ())
952 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
955 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
956 verifyable_object (PTHREAD_COND_MAGIC
),
957 shared (0), waiting (0), pending (0), sem_wait (NULL
),
958 mtx_cond(NULL
), next (NULL
)
960 pthread_mutex
*verifyable_mutex_obj
;
963 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
969 verifyable_mutex_obj
= &mtx_in
;
970 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
972 thread_printf ("Internal cond mutex is not valid. this %p", this);
977 * Change the mutex type to NORMAL.
978 * This mutex MUST be of type normal
980 mtx_in
.type
= PTHREAD_MUTEX_NORMAL
;
982 verifyable_mutex_obj
= &mtx_out
;
983 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
985 thread_printf ("Internal cond mutex is not valid. this %p", this);
989 /* Change the mutex type to NORMAL to speed up mutex operations */
990 mtx_out
.type
= PTHREAD_MUTEX_NORMAL
;
992 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
995 debug_printf ("CreateSemaphore failed. %E");
1000 conds
.insert (this);
1003 pthread_cond::~pthread_cond ()
1006 CloseHandle (sem_wait
);
1008 conds
.remove (this);
1012 pthread_cond::unblock (const bool all
)
1014 unsigned long releaseable
;
1017 * Block outgoing threads (and avoid simultanous unblocks)
1021 releaseable
= waiting
- pending
;
1024 unsigned long released
;
1029 * Block incoming threads until all waiting threads are released.
1034 * Calculate releaseable again because threads can enter until
1035 * the semaphore has been taken, but they can not leave, therefore pending
1036 * is unchanged and releaseable can only get higher
1038 releaseable
= waiting
- pending
;
1041 released
= all
? releaseable
: 1;
1042 pending
+= released
;
1046 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
1050 * And let the threads release.
1056 pthread_cond::wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
)
1061 if (InterlockedIncrement ((long *)&waiting
) == 1)
1063 else if (mtx_cond
!= mutex
)
1065 InterlockedDecrement ((long *)&waiting
);
1072 * Release the mutex and wait on semaphore
1077 rv
= cancelable_wait (sem_wait
, dwMilliseconds
, cw_no_cancel_self
, cw_sig_eintr
);
1081 if (rv
!= WAIT_OBJECT_0
)
1084 * It might happen that a signal is sent while the thread got canceled
1085 * or timed out. Try to take one.
1086 * If the thread gets one than a signal|broadcast is in progress.
1088 if (WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
1090 * thread got cancelled ot timed out while a signalling is in progress.
1091 * Set wait result back to signaled
1096 InterlockedDecrement ((long *)&waiting
);
1098 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
1100 * All signaled threads are released,
1101 * new threads can enter Wait
1110 if (rv
== WAIT_CANCELED
)
1111 pthread::static_cancel_self ();
1112 else if (rv
== WAIT_SIGNALED
)
1113 /* SUSv3 states: If a signal is delivered to a thread waiting for a
1114 condition variable, upon return from the signal handler the thread
1115 resumes waiting for the condition variable as if it was not
1116 interrupted, or it shall return zero due to spurious wakeup.
1117 We opt for the latter choice here. */
1119 else if (rv
== WAIT_TIMEOUT
)
1126 pthread_cond::_fixup_after_fork ()
1128 waiting
= pending
= 0;
1131 /* Unlock eventually locked mutexes */
1135 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1137 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1140 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1141 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1145 pthread_rwlockattr::~pthread_rwlockattr ()
1149 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
1151 /* This is used for rwlock creation protection within a single process only */
1152 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
1154 /* We can only be called once.
1155 TODO: (no rush) use a non copied memory section to
1156 hold an initialization flag. */
1158 pthread_rwlock::init_mutex ()
1160 if (!rwlock_initialization_lock
.init ())
1161 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1164 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
1165 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
1166 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
1167 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
1170 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
1171 pthread_cond
*verifyable_cond_obj
;
1173 if (!readers_mx
.init ())
1175 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1181 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1187 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1189 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1193 /* Change the mutex type to NORMAL to speed up mutex operations */
1194 mtx
.type
= PTHREAD_MUTEX_NORMAL
;
1196 verifyable_cond_obj
= &cond_readers
;
1197 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1199 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1204 verifyable_cond_obj
= &cond_writers
;
1205 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1207 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1213 rwlocks
.insert (this);
1216 pthread_rwlock::~pthread_rwlock ()
1218 rwlocks
.remove (this);
1222 pthread_rwlock::rdlock ()
1225 struct RWLOCK_READER
*reader
;
1226 pthread_t self
= pthread::self ();
1230 if (lookup_reader (self
))
1236 reader
= new struct RWLOCK_READER
;
1243 while (writer
|| waiting_writers
)
1245 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1248 cond_readers
.wait (&mtx
);
1251 pthread_cleanup_pop (0);
1254 reader
->thread
= self
;
1255 add_reader (reader
);
1264 pthread_rwlock::tryrdlock ()
1267 pthread_t self
= pthread::self ();
1271 if (writer
|| waiting_writers
|| lookup_reader (self
))
1275 struct RWLOCK_READER
*reader
= new struct RWLOCK_READER
;
1278 reader
->thread
= self
;
1279 add_reader (reader
);
1291 pthread_rwlock::wrlock ()
1294 pthread_t self
= pthread::self ();
1298 if (writer
== self
|| lookup_reader (self
))
1304 while (writer
|| readers
)
1306 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1309 cond_writers
.wait (&mtx
);
1312 pthread_cleanup_pop (0);
1324 pthread_rwlock::trywrlock ()
1327 pthread_t self
= pthread::self ();
1331 if (writer
|| readers
)
1342 pthread_rwlock::unlock ()
1345 pthread_t self
= pthread::self ();
1361 struct RWLOCK_READER
*reader
= lookup_reader (self
);
1369 remove_reader (reader
);
1382 pthread_rwlock::add_reader (struct RWLOCK_READER
*rd
)
1384 List_insert (readers
, rd
);
1388 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1390 List_remove (readers_mx
, readers
, rd
);
1393 struct pthread_rwlock::RWLOCK_READER
*
1394 pthread_rwlock::lookup_reader (pthread_t thread
)
1398 struct RWLOCK_READER
*cur
= readers
;
1400 while (cur
&& cur
->thread
!= thread
)
1403 readers_mx
.unlock ();
1409 pthread_rwlock::rdlock_cleanup (void *arg
)
1411 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1413 --(rwlock
->waiting_readers
);
1415 rwlock
->mtx
.unlock ();
1419 pthread_rwlock::wrlock_cleanup (void *arg
)
1421 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1423 --(rwlock
->waiting_writers
);
1425 rwlock
->mtx
.unlock ();
1429 pthread_rwlock::_fixup_after_fork ()
1431 pthread_t self
= pthread::self ();
1432 struct RWLOCK_READER
**temp
= &readers
;
1434 waiting_readers
= 0;
1435 waiting_writers
= 0;
1437 if (!readers_mx
.init ())
1438 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1440 /* Unlock eventually locked mutex */
1443 * Remove all readers except self
1447 if ((*temp
)->thread
== self
)
1448 temp
= &((*temp
)->next
);
1451 struct RWLOCK_READER
*cur
= *temp
;
1452 *temp
= (*temp
)->next
;
1459 /* static members */
1460 /* This stores pthread_key information across fork() boundaries */
1461 List
<pthread_key
> pthread_key::keys
;
1463 /* non-static members */
1465 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1467 tls_index
= TlsAlloc ();
1468 if (tls_index
== TLS_OUT_OF_INDEXES
)
1474 pthread_key::~pthread_key ()
1476 /* We may need to make the list code lock the list during operations
1481 TlsFree (tls_index
);
1486 pthread_key::_fixup_before_fork ()
1492 pthread_key::_fixup_after_fork ()
1494 tls_index
= TlsAlloc ();
1495 if (tls_index
== TLS_OUT_OF_INDEXES
)
1496 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1501 pthread_key::run_destructor ()
1505 void *oldValue
= get ();
1509 destructor (oldValue
);
1516 REMOVED FROM CURRENT. These can be reinstated with the daemon, when all the
1517 gymnastics can be a lot easier.
1519 the mutex_t (size 4) is not used as a verifyable object because we cannot
1520 guarantee the same address space for all processes.
1521 we use the following:
1522 high bit set (never a valid address).
1523 second byte is reserved for the priority.
1524 third byte is reserved
1525 fourth byte is the mutex id. (max 255 cygwin mutexs system wide).
1526 creating mutex's does get slower and slower, but as creation is a one time
1527 job, it should never become an issue
1529 And if you're looking at this and thinking, why not an array in cygwin for all mutexs,
1530 - you incur a penalty on _every_ mutex call and you have toserialise them all.
1533 option 2? put everything in userspace and update the ABI?
1534 - bad karma as well - the HANDLE, while identical across process's,
1535 Isn't duplicated, it's reopened. */
1537 /* static members */
1539 List
<pthread_mutex
> pthread_mutex::mutexes
;
1541 /* This is used for mutex creation protection within a single process only */
1542 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1544 /* We can only be called once.
1545 TODO: (no rush) use a non copied memory section to
1546 hold an initialization flag. */
1548 pthread_mutex::init_mutex ()
1550 if (!mutex_initialization_lock
.init ())
1551 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1554 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1555 verifyable_object (PTHREAD_MUTEX_MAGIC
),
1557 win32_obj_id (NULL
), recursion_counter (0),
1558 condwaits (0), owner (NULL
),
1562 type (PTHREAD_MUTEX_ERRORCHECK
),
1563 pshared (PTHREAD_PROCESS_PRIVATE
)
1565 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1571 /*attr checked in the C call */
1574 if (attr
->pshared
== PTHREAD_PROCESS_SHARED
)
1581 type
= attr
->mutextype
;
1584 mutexes
.insert (this);
1587 pthread_mutex::~pthread_mutex ()
1590 CloseHandle (win32_obj_id
);
1592 mutexes
.remove (this);
1596 pthread_mutex::_lock (pthread_t self
)
1600 if (InterlockedIncrement ((long *)&lock_counter
) == 1)
1602 else if (type
== PTHREAD_MUTEX_NORMAL
|| !pthread::equal (owner
, self
))
1604 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
1609 InterlockedDecrement ((long *) &lock_counter
);
1610 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1611 result
= lock_recursive ();
1620 pthread_mutex::_trylock (pthread_t self
)
1624 if (InterlockedCompareExchange ((long *) &lock_counter
, 1, 0) == 0)
1626 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1627 result
= lock_recursive ();
1635 pthread_mutex::_unlock (pthread_t self
)
1637 if (!pthread::equal (owner
, self
))
1640 if (--recursion_counter
== 0)
1646 if (InterlockedDecrement ((long *)&lock_counter
))
1647 // Another thread is waiting
1648 ::ReleaseSemaphore (win32_obj_id
, 1, NULL
);
1655 pthread_mutex::_destroy (pthread_t self
)
1657 if (condwaits
|| _trylock (self
))
1658 // Do not destroy a condwaited or locked mutex
1660 else if (recursion_counter
!= 1)
1662 // Do not destroy a recursive locked mutex
1663 --recursion_counter
;
1672 pthread_mutex::_fixup_after_fork ()
1674 debug_printf ("mutex %x in _fixup_after_fork", this);
1675 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1676 api_fatal ("pthread_mutex::_fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's");
1680 /* mutex has no owner, reset to initial */
1686 else if (lock_counter
!= 0)
1688 /* All waiting threads are gone after a fork */
1691 tid
= 0xffffffff; /* Don't know the tid after a fork */
1695 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1697 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
1702 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1703 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_ERRORCHECK
)
1707 pthread_mutexattr::~pthread_mutexattr ()
1711 verifyable_object::verifyable_object (long verifyer
):
1716 verifyable_object::~verifyable_object ()
1722 pthread::thread_init_wrapper (void *arg
)
1724 pthread
*thread
= (pthread
*) arg
;
1725 set_tls_self_pointer (thread
);
1727 thread
->mutex
.lock ();
1729 // if thread is detached force cleanup on exit
1730 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
1731 thread
->joiner
= thread
;
1732 _my_tls
.sigmask
= thread
->parent_tls
->sigmask
;
1733 thread
->mutex
.unlock ();
1735 thread_printf ("started thread %p %p %p %p %p %p", arg
, &_my_tls
.local_clib
,
1736 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
1738 // call the user's thread
1739 void *ret
= thread
->function (thread
->arg
);
1743 return 0; // just for show. Never returns.
1747 pthread::getsequence_np ()
1749 return get_thread_id ();
1753 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
1754 void *(*start_routine
) (void *), void *arg
)
1756 if (attr
&& !pthread_attr::is_good_object (attr
))
1759 *thread
= new pthread ();
1760 if (!(*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
))
1771 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
1774 if (once_control
->state
)
1777 pthread_mutex_lock (&once_control
->mutex
);
1778 /* Here we must set a cancellation handler to unlock the mutex if needed */
1779 /* but a cancellation handler is not the right thing. We need this in the thread
1780 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
1781 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
1782 *on pthread_exit ();
1784 if (!once_control
->state
)
1787 once_control
->state
= 1;
1789 /* Here we must remove our cancellation handler */
1790 pthread_mutex_unlock (&once_control
->mutex
);
1795 pthread::cancel (pthread_t thread
)
1797 if (!is_good_object (&thread
))
1800 return thread
->cancel ();
1804 pthread::atforkprepare ()
1806 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
1815 MT_INTERFACE
->fixup_before_fork ();
1819 pthread::atforkparent ()
1823 callback
*cb
= MT_INTERFACE
->pthread_parent
;
1832 pthread::atforkchild ()
1834 MT_INTERFACE
->fixup_after_fork ();
1838 callback
*cb
= MT_INTERFACE
->pthread_child
;
1846 /* Register a set of functions to run before and after fork.
1847 prepare calls are called in LI-FC order.
1848 parent and child calls are called in FI-FC order. */
1850 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
1852 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
1855 prepcb
= new callback
;
1861 parentcb
= new callback
;
1871 childcb
= new callback
;
1884 prepcb
->cb
= prepare
;
1885 List_insert (MT_INTERFACE
->pthread_prepare
, prepcb
);
1889 parentcb
->cb
= parent
;
1890 callback
**t
= &MT_INTERFACE
->pthread_parent
;
1893 /* t = pointer to last next in the list */
1894 List_insert (*t
, parentcb
);
1898 childcb
->cb
= child
;
1899 callback
**t
= &MT_INTERFACE
->pthread_child
;
1902 /* t = pointer to last next in the list */
1903 List_insert (*t
, childcb
);
1909 pthread_attr_init (pthread_attr_t
*attr
)
1911 if (pthread_attr::is_good_object (attr
))
1914 *attr
= new pthread_attr
;
1915 if (!pthread_attr::is_good_object (attr
))
1925 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
1928 if (!pthread_attr::is_good_object (attr
))
1930 *inheritsched
= (*attr
)->inheritsched
;
1935 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
1936 struct sched_param
*param
)
1938 if (!pthread_attr::is_good_object (attr
))
1940 *param
= (*attr
)->schedparam
;
1944 /* From a pure code point of view, this should call a helper in sched.cc,
1945 to allow for someone adding scheduler policy changes to win32 in the future.
1946 However that's extremely unlikely, so short and sweet will do us */
1948 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
1950 if (!pthread_attr::is_good_object (attr
))
1952 *policy
= SCHED_FIFO
;
1958 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
1960 if (!pthread_attr::is_good_object (attr
))
1962 *contentionscope
= (*attr
)->contentionscope
;
1967 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
1969 if (!pthread_attr::is_good_object (attr
))
1971 if (detachstate
< 0 || detachstate
> 1)
1973 (*attr
)->joinable
= detachstate
;
1978 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
1980 if (!pthread_attr::is_good_object (attr
))
1982 *detachstate
= (*attr
)->joinable
;
1987 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
1989 if (!pthread_attr::is_good_object (attr
))
1991 if (inheritsched
!= PTHREAD_INHERIT_SCHED
1992 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
1994 (*attr
)->inheritsched
= inheritsched
;
1999 pthread_attr_setschedparam (pthread_attr_t
*attr
,
2000 const struct sched_param
*param
)
2002 if (!pthread_attr::is_good_object (attr
))
2004 if (!valid_sched_parameters (param
))
2006 (*attr
)->schedparam
= *param
;
2010 /* See __pthread_attr_getschedpolicy for some notes */
2012 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
2014 if (!pthread_attr::is_good_object (attr
))
2016 if (policy
!= SCHED_FIFO
)
2022 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
2024 if (!pthread_attr::is_good_object (attr
))
2026 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
2027 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2029 /* In future, we may be able to support system scope by escalating the thread
2030 priority to exceed the priority class. For now we only support PROCESS scope. */
2031 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2033 (*attr
)->contentionscope
= contentionscope
;
2038 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
2040 if (!pthread_attr::is_good_object (attr
))
2042 (*attr
)->stacksize
= size
;
2047 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
2049 if (!pthread_attr::is_good_object (attr
))
2051 *size
= (*attr
)->stacksize
;
2056 pthread_attr_destroy (pthread_attr_t
*attr
)
2058 if (!pthread_attr::is_good_object (attr
))
2066 pthread::join (pthread_t
*thread
, void **return_val
)
2068 pthread_t joiner
= self ();
2070 joiner
->testcancel ();
2072 // Initialize return val with NULL
2076 if (!is_good_object (&joiner
))
2079 if (!is_good_object (thread
))
2082 if (equal (*thread
,joiner
))
2085 (*thread
)->mutex
.lock ();
2087 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2089 (*thread
)->mutex
.unlock ();
2094 (*thread
)->joiner
= joiner
;
2095 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2096 (*thread
)->mutex
.unlock ();
2098 switch (cancelable_wait ((*thread
)->win32_obj_id
, INFINITE
, cw_no_cancel_self
, cw_sig_resume
))
2102 *return_val
= (*thread
)->return_ptr
;
2106 // set joined thread back to joinable since we got canceled
2107 (*thread
)->joiner
= NULL
;
2108 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2109 joiner
->cancel_self ();
2113 // should never happen
2122 pthread::detach (pthread_t
*thread
)
2124 if (!is_good_object (thread
))
2127 (*thread
)->mutex
.lock ();
2128 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2130 (*thread
)->mutex
.unlock ();
2134 // check if thread is still alive
2135 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2137 // force cleanup on exit
2138 (*thread
)->joiner
= *thread
;
2139 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2140 (*thread
)->mutex
.unlock ();
2144 // thread has already terminated.
2145 (*thread
)->mutex
.unlock ();
2153 pthread::suspend (pthread_t
*thread
)
2155 if (!is_good_object (thread
))
2158 if ((*thread
)->suspended
== false)
2160 (*thread
)->suspended
= true;
2161 SuspendThread ((*thread
)->win32_obj_id
);
2169 pthread::resume (pthread_t
*thread
)
2171 if (!is_good_object (thread
))
2174 if ((*thread
)->suspended
== true)
2175 ResumeThread ((*thread
)->win32_obj_id
);
2176 (*thread
)->suspended
= false;
2181 /* provided for source level compatability.
2182 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2185 pthread_getconcurrency ()
2187 return MT_INTERFACE
->concurrency
;
2190 /* keep this in sync with sched.cc */
2192 pthread_getschedparam (pthread_t thread
, int *policy
,
2193 struct sched_param
*param
)
2195 if (!pthread::is_good_object (&thread
))
2197 *policy
= SCHED_FIFO
;
2198 /* we don't return the current effective priority, we return the current
2199 requested priority */
2200 *param
= thread
->attr
.schedparam
;
2204 /* Thread Specific Data */
2206 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
2208 *key
= new pthread_key (destructor
);
2210 if (!pthread_key::is_good_object (key
))
2220 pthread_key_delete (pthread_key_t key
)
2222 if (!pthread_key::is_good_object (&key
))
2229 /* provided for source level compatability. See
2230 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2233 pthread_setconcurrency (int new_level
)
2237 MT_INTERFACE
->concurrency
= new_level
;
2241 /* keep syncronised with sched.cc */
2243 pthread_setschedparam (pthread_t thread
, int policy
,
2244 const struct sched_param
*param
)
2246 if (!pthread::is_good_object (&thread
))
2248 if (policy
!= SCHED_FIFO
)
2253 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
2255 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
2261 pthread_setspecific (pthread_key_t key
, const void *value
)
2263 if (!pthread_key::is_good_object (&key
))
2270 pthread_getspecific (pthread_key_t key
)
2272 if (!pthread_key::is_good_object (&key
))
2275 return (key
)->get ();
2280 pthread_cond_destroy (pthread_cond_t
*cond
)
2282 if (pthread_cond::is_good_initializer (cond
))
2284 if (!pthread_cond::is_good_object (cond
))
2287 /* reads are atomic */
2288 if ((*cond
)->waiting
)
2298 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2300 pthread_cond_t new_cond
;
2302 if (attr
&& !pthread_condattr::is_good_object (attr
))
2305 cond_initialization_lock
.lock ();
2307 new_cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2308 if (!is_good_object (&new_cond
))
2311 cond_initialization_lock
.unlock ();
2316 if (efault
.faulted ())
2319 cond_initialization_lock
.unlock ();
2324 cond_initialization_lock
.unlock ();
2330 pthread_cond_broadcast (pthread_cond_t
*cond
)
2332 if (pthread_cond::is_good_initializer (cond
))
2334 if (!pthread_cond::is_good_object (cond
))
2337 (*cond
)->unblock (true);
2343 pthread_cond_signal (pthread_cond_t
*cond
)
2345 if (pthread_cond::is_good_initializer (cond
))
2347 if (!pthread_cond::is_good_object (cond
))
2350 (*cond
)->unblock (false);
2356 __pthread_cond_dowait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2359 if (!pthread_mutex::is_good_object (mutex
))
2361 if (!pthread_mutex::can_be_unlocked (mutex
))
2364 if (pthread_cond::is_good_initializer (cond
))
2365 pthread_cond::init (cond
, NULL
);
2366 if (!pthread_cond::is_good_object (cond
))
2369 return (*cond
)->wait (*mutex
, waitlength
);
2373 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2374 const struct timespec
*abstime
)
2380 if (efault
.faulted ())
2383 pthread_testcancel ();
2385 /* According to SUSv3, the abstime value must be checked for validity. */
2386 if (abstime
->tv_sec
< 0
2387 || abstime
->tv_nsec
< 0
2388 || abstime
->tv_nsec
> 999999999)
2391 gettimeofday (&tv
, NULL
);
2392 /* Check for immediate timeout before converting to microseconds, since
2393 the resulting value can easily overflow long. This also allows to
2394 evaluate microseconds directly in DWORD. */
2395 if (tv
.tv_sec
> abstime
->tv_sec
2396 || (tv
.tv_sec
== abstime
->tv_sec
2397 && tv
.tv_usec
> abstime
->tv_nsec
/ 1000))
2400 waitlength
= (abstime
->tv_sec
- tv
.tv_sec
) * 1000;
2401 waitlength
+= (abstime
->tv_nsec
/ 1000 - tv
.tv_usec
) / 1000;
2402 return __pthread_cond_dowait (cond
, mutex
, waitlength
);
2406 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
2408 pthread_testcancel ();
2410 return __pthread_cond_dowait (cond
, mutex
, INFINITE
);
2414 pthread_condattr_init (pthread_condattr_t
*condattr
)
2416 if (pthread_condattr::is_good_object (condattr
))
2419 *condattr
= new pthread_condattr
;
2420 if (!pthread_condattr::is_good_object (condattr
))
2430 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
2432 if (!pthread_condattr::is_good_object (attr
))
2434 *pshared
= (*attr
)->shared
;
2439 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
2441 if (!pthread_condattr::is_good_object (attr
))
2443 if ((pshared
< 0) || (pshared
> 1))
2445 /* shared cond vars not currently supported */
2446 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2448 (*attr
)->shared
= pshared
;
2453 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
2455 if (!pthread_condattr::is_good_object (condattr
))
2463 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
2465 if (pthread_rwlock::is_good_initializer (rwlock
))
2467 if (!pthread_rwlock::is_good_object (rwlock
))
2470 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
2471 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
2481 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2483 pthread_rwlock_t new_rwlock
;
2485 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2488 rwlock_initialization_lock
.lock ();
2490 new_rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2491 if (!is_good_object (&new_rwlock
))
2494 rwlock_initialization_lock
.unlock ();
2499 if (efault
.faulted ())
2502 rwlock_initialization_lock
.unlock ();
2506 *rwlock
= new_rwlock
;
2507 rwlock_initialization_lock
.unlock ();
2513 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
2515 pthread_testcancel ();
2517 if (pthread_rwlock::is_good_initializer (rwlock
))
2518 pthread_rwlock::init (rwlock
, NULL
);
2519 if (!pthread_rwlock::is_good_object (rwlock
))
2522 return (*rwlock
)->rdlock ();
2526 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
2528 if (pthread_rwlock::is_good_initializer (rwlock
))
2529 pthread_rwlock::init (rwlock
, NULL
);
2530 if (!pthread_rwlock::is_good_object (rwlock
))
2533 return (*rwlock
)->tryrdlock ();
2537 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
2539 pthread_testcancel ();
2541 if (pthread_rwlock::is_good_initializer (rwlock
))
2542 pthread_rwlock::init (rwlock
, NULL
);
2543 if (!pthread_rwlock::is_good_object (rwlock
))
2546 return (*rwlock
)->wrlock ();
2550 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
2552 if (pthread_rwlock::is_good_initializer (rwlock
))
2553 pthread_rwlock::init (rwlock
, NULL
);
2554 if (!pthread_rwlock::is_good_object (rwlock
))
2557 return (*rwlock
)->trywrlock ();
2561 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
2563 if (pthread_rwlock::is_good_initializer (rwlock
))
2565 if (!pthread_rwlock::is_good_object (rwlock
))
2568 return (*rwlock
)->unlock ();
2572 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
2574 if (pthread_rwlockattr::is_good_object (rwlockattr
))
2577 *rwlockattr
= new pthread_rwlockattr
;
2578 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2580 delete (*rwlockattr
);
2588 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
2590 if (!pthread_rwlockattr::is_good_object (attr
))
2592 *pshared
= (*attr
)->shared
;
2597 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
2599 if (!pthread_rwlockattr::is_good_object (attr
))
2601 if ((pshared
< 0) || (pshared
> 1))
2603 /* shared rwlock vars not currently supported */
2604 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2606 (*attr
)->shared
= pshared
;
2611 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
2613 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2615 delete (*rwlockattr
);
2622 pthread_kill (pthread_t thread
, int sig
)
2624 // lock myself, for the use of thread2signal
2625 // two different kills might clash: FIXME
2627 if (!pthread::is_good_object (&thread
))
2632 si
.si_code
= SI_USER
;
2633 si
.si_pid
= myself
->pid
;
2634 si
.si_uid
= myself
->uid
;
2640 thread
->cygtls
->set_threadkill ();
2641 rval
= sig_send (NULL
, si
, thread
->cygtls
);
2644 switch (WaitForSingleObject (thread
->win32_obj_id
, 0))
2659 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
2661 return handle_sigprocmask (operation
, set
, old_set
, _my_tls
.sigmask
);
2667 pthread_equal (pthread_t t1
, pthread_t t2
)
2669 return pthread::equal (t1
, t2
);
2675 pthread_mutex::init (pthread_mutex_t
*mutex
,
2676 const pthread_mutexattr_t
*attr
,
2677 const pthread_mutex_t initializer
)
2679 pthread_mutex_t new_mutex
;
2681 if (attr
&& !pthread_mutexattr::is_good_object (attr
))
2684 mutex_initialization_lock
.lock ();
2686 new_mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2687 if (!is_good_object (&new_mutex
))
2690 mutex_initialization_lock
.unlock ();
2694 if (!attr
&& initializer
)
2696 if (initializer
== PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
)
2697 new_mutex
->type
= PTHREAD_MUTEX_RECURSIVE
;
2698 else if (initializer
== PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
)
2699 new_mutex
->type
= PTHREAD_MUTEX_NORMAL
;
2700 else if (initializer
== PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
)
2701 new_mutex
->type
= PTHREAD_MUTEX_ERRORCHECK
;
2705 if (efault
.faulted ())
2708 mutex_initialization_lock
.unlock ();
2713 mutex_initialization_lock
.unlock ();
2719 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
2722 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
2725 We can support mutex priorities in the future though:
2726 Store a priority with each mutex.
2727 When the mutex is optained, set the thread priority as appropriate
2728 When the mutex is released, reset the thread priority. */
2733 pthread_mutex_lock (pthread_mutex_t
*mutex
)
2735 if (pthread_mutex::is_good_initializer (mutex
))
2736 pthread_mutex::init (mutex
, NULL
, *mutex
);
2737 if (!pthread_mutex::is_good_object (mutex
))
2739 return (*mutex
)->lock ();
2743 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
2745 if (pthread_mutex::is_good_initializer (mutex
))
2746 pthread_mutex::init (mutex
, NULL
, *mutex
);
2747 if (!pthread_mutex::is_good_object (mutex
))
2749 return (*mutex
)->trylock ();
2753 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
2755 if (pthread_mutex::is_good_initializer (mutex
))
2757 if (!pthread_mutex::is_good_object (mutex
))
2759 return (*mutex
)->unlock ();
2763 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
2767 if (pthread_mutex::is_good_initializer (mutex
))
2769 if (!pthread_mutex::is_good_object (mutex
))
2772 rv
= (*mutex
)->destroy ();
2781 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
2787 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
2790 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
2793 if (!pthread_mutexattr::is_good_object (attr
))
2799 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
2802 if (!pthread_mutexattr::is_good_object (attr
))
2804 *pshared
= (*attr
)->pshared
;
2809 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
2811 if (!pthread_mutexattr::is_good_object (attr
))
2813 *type
= (*attr
)->mutextype
;
2817 /* FIXME: write and test process shared mutex's. */
2819 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
2821 if (pthread_mutexattr::is_good_object (attr
))
2824 *attr
= new pthread_mutexattr ();
2825 if (!pthread_mutexattr::is_good_object (attr
))
2835 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
2837 if (!pthread_mutexattr::is_good_object (attr
))
2845 /* Win32 doesn't support mutex priorities */
2847 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
2849 if (!pthread_mutexattr::is_good_object (attr
))
2854 /* Win32 doesn't support mutex priorities */
2856 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
2859 if (!pthread_mutexattr::is_good_object (attr
))
2865 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
2868 if (!pthread_mutexattr::is_good_object (attr
))
2874 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
2876 if (!pthread_mutexattr::is_good_object (attr
))
2878 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
2881 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2883 (*attr
)->pshared
= pshared
;
2887 /* see pthread_mutex_gettype */
2889 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
2891 if (!pthread_mutexattr::is_good_object (attr
))
2896 case PTHREAD_MUTEX_ERRORCHECK
:
2897 case PTHREAD_MUTEX_RECURSIVE
:
2898 case PTHREAD_MUTEX_NORMAL
:
2899 (*attr
)->mutextype
= type
;
2910 List
<semaphore
> semaphore::semaphores
;
2912 semaphore::semaphore (int pshared
, unsigned int value
)
2913 : verifyable_object (SEM_MAGIC
),
2915 currentvalue (value
),
2920 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2921 ? sec_all
: sec_none_nih
;
2922 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, NULL
);
2923 if (!this->win32_obj_id
)
2926 semaphores
.insert (this);
2929 semaphore::semaphore (unsigned long long shash
, LUID sluid
, int sfd
,
2930 sem_t
*ssem
, int oflag
, mode_t mode
, unsigned int value
)
2931 : verifyable_object (SEM_MAGIC
),
2932 shared (PTHREAD_PROCESS_SHARED
),
2933 currentvalue (value
), /* Unused for named semaphores. */
2939 char name
[MAX_PATH
];
2941 __small_sprintf (name
, "%scyg_psem/cyg%016X%08x%08x", cygheap
->shared_prefix
,
2942 hash
, luid
.HighPart
, luid
.LowPart
);
2943 this->win32_obj_id
= ::CreateSemaphore (&sec_all
, value
, LONG_MAX
, name
);
2944 if (!this->win32_obj_id
)
2946 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
2949 CloseHandle (this->win32_obj_id
);
2953 semaphores
.insert (this);
2956 semaphore::~semaphore ()
2959 CloseHandle (win32_obj_id
);
2961 semaphores
.remove (this);
2967 if (ReleaseSemaphore (win32_obj_id
, 1, ¤tvalue
))
2972 semaphore::_getvalue (int *sval
)
2976 switch (WaitForSingleObject (win32_obj_id
, 0))
2979 ReleaseSemaphore (win32_obj_id
, 1, &val
);
2993 semaphore::_trywait ()
2995 /* FIXME: signals should be able to interrupt semaphores...
2996 We probably need WaitForMultipleObjects here. */
2997 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
3007 semaphore::_timedwait (const struct timespec
*abstime
)
3013 if (efault
.faulted ())
3015 /* According to SUSv3, abstime need not be checked for validity,
3016 if the semaphore can be locked immediately. */
3023 gettimeofday (&tv
, NULL
);
3024 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
3025 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
3028 switch (cancelable_wait (win32_obj_id
, waitlength
, cw_cancel_self
, cw_sig_eintr
))
3037 set_errno (ETIMEDOUT
);
3040 debug_printf ("cancelable_wait failed. %E");
3050 switch (cancelable_wait (win32_obj_id
, INFINITE
, cw_cancel_self
, cw_sig_eintr
))
3059 debug_printf ("cancelable_wait failed. %E");
3066 semaphore::_fixup_after_fork ()
3068 if (shared
== PTHREAD_PROCESS_PRIVATE
)
3070 debug_printf ("sem %x in _fixup_after_fork", this);
3071 /* FIXME: duplicate code here and in the constructor. */
3072 this->win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
3075 api_fatal ("failed to create new win32 semaphore, error %d");
3080 semaphore::_terminate ()
3082 int _sem_close (sem_t
*, bool);
3085 _sem_close (sem
, false);
3088 /* static members */
3091 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
3093 /* opengroup calls this undefined */
3094 if (is_good_object (sem
))
3097 if (value
> SEM_VALUE_MAX
)
3100 *sem
= new semaphore (pshared
, value
);
3102 if (!is_good_object (sem
))
3112 semaphore::destroy (sem_t
*sem
)
3114 if (!is_good_object (sem
))
3117 /* It's invalid to destroy a semaphore not opened with sem_init. */
3118 if ((*sem
)->fd
!= -1)
3121 /* FIXME - new feature - test for busy against threads... */
3129 semaphore::close (sem_t
*sem
)
3131 if (!is_good_object (sem
))
3134 /* It's invalid to close a semaphore not opened with sem_open. */
3135 if ((*sem
)->fd
== -1)
3144 semaphore::open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
3145 mode_t mode
, unsigned int value
, bool &wasopen
)
3147 if (value
> SEM_VALUE_MAX
)
3153 /* sem_open is supposed to return the same pointer, if the same named
3154 semaphore is opened multiple times in the same process, as long as
3155 the semaphore hasn't been closed or unlinked in the meantime. */
3156 semaphores
.mx
.lock ();
3157 for (semaphore
*sema
= semaphores
.head
; sema
; sema
= sema
->next
)
3158 if (sema
->fd
>= 0 && sema
->hash
== hash
3159 && sema
->luid
.HighPart
== luid
.HighPart
3160 && sema
->luid
.LowPart
== sema
->luid
.LowPart
)
3163 semaphores
.mx
.unlock ();
3166 semaphores
.mx
.unlock ();
3169 sem_t
*sem
= new sem_t
;
3176 *sem
= new semaphore (hash
, luid
, fd
, sem
, oflag
, mode
, value
);
3178 if (!is_good_object (sem
))
3188 semaphore::wait (sem_t
*sem
)
3190 pthread_testcancel ();
3192 if (!is_good_object (sem
))
3198 return (*sem
)->_wait ();
3202 semaphore::trywait (sem_t
*sem
)
3204 if (!is_good_object (sem
))
3210 return (*sem
)->_trywait ();
3214 semaphore::timedwait (sem_t
*sem
, const struct timespec
*abstime
)
3216 if (!is_good_object (sem
))
3222 return (*sem
)->_timedwait (abstime
);
3226 semaphore::post (sem_t
*sem
)
3228 if (!is_good_object (sem
))
3239 semaphore::getvalue (sem_t
*sem
, int *sval
)
3242 if (efault
.faulted () || !is_good_object (sem
))
3248 return (*sem
)->_getvalue (sval
);
3252 semaphore::getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
3253 LUID
*sluid
, unsigned int *sval
)
3256 if (efault
.faulted () || !is_good_object (sem
))
3261 if ((*sfd
= (*sem
)->fd
) < 0)
3266 *shash
= (*sem
)->hash
;
3267 *sluid
= (*sem
)->luid
;
3268 /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3269 the sem_getvalue gets a pointer to int to return the value. Go figure! */
3270 return (*sem
)->_getvalue ((int *)sval
);
3275 pthread_null::get_null_pthread ()
3277 /* because of weird entry points */
3278 _instance
.magic
= 0;
3282 pthread_null::pthread_null ()
3284 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
3285 /* Mark ourselves as invalid */
3289 pthread_null::~pthread_null ()
3294 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
3300 pthread_null::exit (void *value_ptr
)
3302 _my_tls
.remove (INFINITE
);
3307 pthread_null::cancel ()
3313 pthread_null::testcancel ()
3318 pthread_null::setcancelstate (int state
, int *oldstate
)
3324 pthread_null::setcanceltype (int type
, int *oldtype
)
3330 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
3335 pthread_null::pop_cleanup_handler (int const execute
)
3340 pthread_null::getsequence_np ()
3345 pthread_null
pthread_null::_instance
;