1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007 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. */
38 #include "perprocess.h"
44 #include <semaphore.h>
46 #include <sys/timeb.h>
47 #include <exceptions.h>
48 #include <sys/fcntl.h>
51 extern "C" void __fp_lock_all ();
52 extern "C" void __fp_unlock_all ();
53 static inline verifyable_object_state
54 verifyable_object_isvalid (void const * objectptr
, long magic
,
55 void *static_ptr1
= NULL
,
56 void *static_ptr2
= NULL
,
57 void *static_ptr3
= NULL
);
59 extern int threadsafe
;
62 extern "C" struct _reent
*
65 return &_my_tls
.local_clib
;
69 __cygwin_lock_init (_LOCK_T
*lock
)
71 *lock
= _LOCK_T_INITIALIZER
;
75 __cygwin_lock_init_recursive (_LOCK_T
*lock
)
77 *lock
= _LOCK_T_RECURSIVE_INITIALIZER
;
81 __cygwin_lock_fini (_LOCK_T
*lock
)
83 pthread_mutex_destroy ((pthread_mutex_t
*) lock
);
87 __cygwin_lock_lock (_LOCK_T
*lock
)
89 if (MT_INTERFACE
->threadcount
<= 1)
90 paranoid_printf ("threadcount %d. not locking", MT_INTERFACE
->threadcount
);
93 paranoid_printf ("threadcount %d. locking", MT_INTERFACE
->threadcount
);
94 pthread_mutex_lock ((pthread_mutex_t
*) lock
);
99 __cygwin_lock_trylock (_LOCK_T
*lock
)
101 return pthread_mutex_trylock ((pthread_mutex_t
*) lock
);
106 __cygwin_lock_unlock (_LOCK_T
*lock
)
108 if (MT_INTERFACE
->threadcount
<= 1)
109 paranoid_printf ("threadcount %d. not unlocking", MT_INTERFACE
->threadcount
);
112 pthread_mutex_unlock ((pthread_mutex_t
*) lock
);
113 paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE
->threadcount
);
117 static inline verifyable_object_state
118 verifyable_object_isvalid (void const *objectptr
, long magic
, void *static_ptr1
,
119 void *static_ptr2
, void *static_ptr3
)
122 /* Check for NULL pointer specifically since it is a cheap test and avoids the
123 overhead of setting up the fault handler. */
124 if (!objectptr
|| efault
.faulted ())
125 return INVALID_OBJECT
;
127 verifyable_object
**object
= (verifyable_object
**) objectptr
;
129 if ((static_ptr1
&& *object
== static_ptr1
) ||
130 (static_ptr2
&& *object
== static_ptr2
) ||
131 (static_ptr3
&& *object
== static_ptr3
))
132 return VALID_STATIC_OBJECT
;
133 if ((*object
)->magic
!= magic
)
134 return INVALID_OBJECT
;
140 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
142 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
148 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
150 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
156 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
158 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
164 pthread_key::is_good_object (pthread_key_t
const *key
)
166 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
172 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
174 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
180 pthread_mutex::is_good_initializer (pthread_mutex_t
const *mutex
)
182 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
183 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
184 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
185 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) != VALID_STATIC_OBJECT
)
191 pthread_mutex::is_good_initializer_or_object (pthread_mutex_t
const *mutex
)
193 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
194 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
195 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
196 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == INVALID_OBJECT
)
202 pthread_mutex::can_be_unlocked (pthread_mutex_t
const *mutex
)
204 pthread_t self
= pthread::self ();
206 if (!is_good_object (mutex
))
208 /* Check if the mutex is owned by the current thread and can be unlocked.
209 * Also check for the ANONYMOUS owner to cover NORMAL mutexes as well. */
210 return ((*mutex
)->recursion_counter
== 1
211 && ((*mutex
)->owner
== MUTEX_OWNER_ANONYMOUS
212 || pthread::equal ((*mutex
)->owner
, self
)));
216 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
218 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
223 inline bool __attribute__ ((used
))
224 pthread::is_good_object (pthread_t
const *thread
)
226 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
231 /* Thread synchronisation */
233 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
235 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
241 pthread_cond::is_good_initializer (pthread_cond_t
const *cond
)
243 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
249 pthread_cond::is_good_initializer_or_object (pthread_cond_t
const *cond
)
251 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
258 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
260 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
266 pthread_rwlock::is_good_initializer (pthread_rwlock_t
const *rwlock
)
268 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
274 pthread_rwlock::is_good_initializer_or_object (pthread_rwlock_t
const *rwlock
)
276 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
282 semaphore::is_good_object (sem_t
const * sem
)
284 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
290 ResourceLocks::Lock (int _resid
)
296 SetResourceLock (int _res_id
, int _mode
, const char *_function
)
298 EnterCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
302 ReleaseResourceLock (int _res_id
, int _mode
, const char *_function
)
304 LeaveCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
308 ResourceLocks::Init ()
310 InitializeCriticalSection (&lock
);
312 thread_printf ("lock %p inited by %p , %d", &lock
, user_data
, myself
->pid
);
316 ResourceLocks::Delete ()
320 thread_printf ("Close Resource Locks %p ", &lock
);
321 DeleteCriticalSection (&lock
);
329 pthread_mutex::init_mutex ();
330 pthread_cond::init_mutex ();
331 pthread_rwlock::init_mutex ();
335 MTinterface::fixup_before_fork ()
337 pthread_key::fixup_before_fork ();
340 /* This function is called from a single threaded process */
342 MTinterface::fixup_after_fork ()
344 pthread_key::fixup_after_fork ();
347 pthread::init_mainthread ();
349 pthread::fixup_after_fork ();
350 pthread_mutex::fixup_after_fork ();
351 pthread_cond::fixup_after_fork ();
352 pthread_rwlock::fixup_after_fork ();
353 semaphore::fixup_after_fork ();
360 pthread::init_mainthread ()
362 pthread
*thread
= get_tls_self_pointer ();
365 thread
= new pthread ();
367 api_fatal ("failed to create mainthread object");
370 set_tls_self_pointer (thread
);
371 thread
->thread_id
= GetCurrentThreadId ();
372 if (!DuplicateHandle (hMainProc
, GetCurrentThread (), hMainProc
,
373 &thread
->win32_obj_id
, 0, FALSE
, DUPLICATE_SAME_ACCESS
))
374 api_fatal ("failed to create mainthread handle");
375 if (!thread
->create_cancel_event ())
376 api_fatal ("couldn't create cancel event for main thread");
377 VerifyHandle (thread
->win32_obj_id
);
378 thread
->postcreate ();
384 pthread
*thread
= get_tls_self_pointer ();
387 thread
= pthread_null::get_null_pthread ();
388 set_tls_self_pointer (thread
);
394 pthread::get_tls_self_pointer ()
400 pthread::set_tls_self_pointer (pthread
*thread
)
402 thread
->cygtls
= &_my_tls
;
403 _my_tls
.tid
= thread
;
406 List
<pthread
> pthread::threads
;
409 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
410 valid (false), suspended (false),
411 cancelstate (0), canceltype (0), cancel_event (0),
412 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
414 if (this != pthread_null::get_null_pthread ())
415 threads
.insert (this);
421 CloseHandle (win32_obj_id
);
423 CloseHandle (cancel_event
);
425 if (this != pthread_null::get_null_pthread ())
426 threads
.remove (this);
430 pthread::create_cancel_event ()
432 cancel_event
= ::CreateEvent (&sec_none_nih
, TRUE
, FALSE
, NULL
);
435 system_printf ("couldn't create cancel event, %E");
436 /* we need the event for correct behaviour */
443 pthread::precreate (pthread_attr
*newattr
)
445 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
447 /* already running ? */
453 attr
.joinable
= newattr
->joinable
;
454 attr
.contentionscope
= newattr
->contentionscope
;
455 attr
.inheritsched
= newattr
->inheritsched
;
456 attr
.stacksize
= newattr
->stacksize
;
459 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
461 thread_printf ("New thread object access mutex is not valid. this %p",
466 /* Change the mutex type to NORMAL to speed up mutex operations */
467 mutex
.type
= PTHREAD_MUTEX_NORMAL
;
468 if (!create_cancel_event ())
473 pthread::create (void *(*func
) (void *), pthread_attr
*newattr
,
486 win32_obj_id
= ::CreateThread (&sec_none_nih
, attr
.stacksize
,
487 thread_init_wrapper
, this, 0, &thread_id
);
491 thread_printf ("CreateThread failed: this %p, %E", this);
498 low_priority_sleep (0);
506 pthread::postcreate ()
510 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
511 /* FIXME: set the priority appropriately for system contention scope */
512 if (attr
.inheritsched
== PTHREAD_EXPLICIT_SCHED
)
514 /* FIXME: set the scheduling settings for the new thread */
515 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
520 pthread::exit (void *value_ptr
)
522 class pthread
*thread
= this;
524 // run cleanup handlers
525 pop_all_cleanup_handlers ();
527 pthread_key::run_all_destructors ();
530 // cleanup if thread is in detached state and not joined
531 if (equal (joiner
, thread
))
536 return_ptr
= value_ptr
;
540 if (_my_tls
.local_clib
.__sdidinit
< 0)
541 _my_tls
.local_clib
.__sdidinit
= 0;
542 (_reclaim_reent
) (_REENT
);
545 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
549 _my_tls
.remove (INFINITE
);
557 class pthread
*thread
= this;
558 class pthread
*self
= pthread::self ();
568 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
569 cancelstate
== PTHREAD_CANCEL_DISABLE
)
573 SetEvent (cancel_event
);
576 else if (equal (thread
, self
))
580 return 0; // Never reached
583 // cancel asynchronous
584 SuspendThread (win32_obj_id
);
585 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
588 context
.ContextFlags
= CONTEXT_CONTROL
;
589 GetThreadContext (win32_obj_id
, &context
);
590 context
.Eip
= (DWORD
) pthread::static_cancel_self
;
591 SetThreadContext (win32_obj_id
, &context
);
594 ResumeThread (win32_obj_id
);
598 TODO: insert pthread_testcancel into the required functions
599 the required function list is: *indicates done, X indicates not present in cygwin.
618 *pthread_cond_timedwait ()
619 *pthread_cond_wait ()
621 *pthread_testcancel ()
645 the optional list is:
765 Note, that for fcntl (), for any value of the cmd argument.
767 And we must not introduce cancellation points anywhere else that's part of the posix or
773 pthread::testcancel ()
775 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
778 if (WaitForSingleObject (cancel_event
, 0) == WAIT_OBJECT_0
)
783 pthread::static_cancel_self ()
785 pthread::self ()->cancel_self ();
789 cancelable_wait (HANDLE object
, DWORD timeout
,
790 const cw_cancel_action cancel_action
,
791 const enum cw_sig_wait sig_wait
)
795 HANDLE wait_objects
[3];
796 pthread_t thread
= pthread::self ();
798 /* Do not change the wait order.
799 The object must have higher priority than the cancel event,
800 because WaitForMultipleObjects will return the smallest index
801 if both objects are signaled. */
802 wait_objects
[num
++] = object
;
804 if (cancel_action
== cw_no_cancel
|| !pthread::is_good_object (&thread
) ||
805 thread
->cancelstate
== PTHREAD_CANCEL_DISABLE
)
806 cancel_n
= (DWORD
) -1;
809 cancel_n
= WAIT_OBJECT_0
+ num
++;
810 wait_objects
[cancel_n
] = thread
->cancel_event
;
814 if (sig_wait
== cw_sig_nosig
|| &_my_tls
!= _main_tls
)
818 sig_n
= WAIT_OBJECT_0
+ num
++;
819 wait_objects
[sig_n
] = signal_arrived
;
824 res
= WaitForMultipleObjects (num
, wait_objects
, FALSE
, timeout
);
827 if (cancel_action
== cw_cancel_self
)
828 pthread::static_cancel_self ();
831 else if (res
!= sig_n
)
833 else if (sig_wait
== cw_sig_eintr
)
837 _my_tls
.call_signal_handler ();
846 pthread::setcancelstate (int state
, int *oldstate
)
852 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
857 *oldstate
= cancelstate
;
867 pthread::setcanceltype (int type
, int *oldtype
)
873 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
878 *oldtype
= canceltype
;
888 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
892 api_fatal ("Attempt to push a cleanup handler across threads");
893 handler
->next
= cleanup_stack
;
894 cleanup_stack
= handler
;
898 pthread::pop_cleanup_handler (int const execute
)
901 // TODO: send a signal or something to the thread ?
902 api_fatal ("Attempt to execute a cleanup handler across threads");
906 if (cleanup_stack
!= NULL
)
908 __pthread_cleanup_handler
*handler
= cleanup_stack
;
911 (*handler
->function
) (handler
->arg
);
912 cleanup_stack
= handler
->next
;
919 pthread::pop_all_cleanup_handlers ()
921 while (cleanup_stack
!= NULL
)
922 pop_cleanup_handler (1);
926 pthread::cancel_self ()
928 exit (PTHREAD_CANCELED
);
932 pthread::get_thread_id ()
938 pthread::_fixup_after_fork ()
940 /* set thread to not running if it is not the forking thread */
941 if (this != pthread::self ())
951 pthread::suspend_except_self ()
953 if (valid
&& this != pthread::self ())
954 SuspendThread (win32_obj_id
);
961 ResumeThread (win32_obj_id
);
964 /* instance members */
966 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
967 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
968 inheritsched (PTHREAD_INHERIT_SCHED
), stacksize (0)
970 schedparam
.sched_priority
= 0;
973 pthread_attr::~pthread_attr ()
977 pthread_condattr::pthread_condattr ():verifyable_object
978 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
982 pthread_condattr::~pthread_condattr ()
986 List
<pthread_cond
> pthread_cond::conds
;
988 /* This is used for cond creation protection within a single process only */
989 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
991 /* We can only be called once.
992 TODO: (no rush) use a non copied memory section to
993 hold an initialization flag. */
995 pthread_cond::init_mutex ()
997 if (!cond_initialization_lock
.init ())
998 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
1001 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
1002 verifyable_object (PTHREAD_COND_MAGIC
),
1003 shared (0), waiting (0), pending (0), sem_wait (NULL
),
1004 mtx_cond(NULL
), next (NULL
)
1006 pthread_mutex
*verifyable_mutex_obj
;
1009 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1015 verifyable_mutex_obj
= &mtx_in
;
1016 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1018 thread_printf ("Internal cond mutex is not valid. this %p", this);
1023 * Change the mutex type to NORMAL.
1024 * This mutex MUST be of type normal
1026 mtx_in
.type
= PTHREAD_MUTEX_NORMAL
;
1028 verifyable_mutex_obj
= &mtx_out
;
1029 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1031 thread_printf ("Internal cond mutex is not valid. this %p", this);
1035 /* Change the mutex type to NORMAL to speed up mutex operations */
1036 mtx_out
.type
= PTHREAD_MUTEX_NORMAL
;
1038 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1041 debug_printf ("CreateSemaphore failed. %E");
1046 conds
.insert (this);
1049 pthread_cond::~pthread_cond ()
1052 CloseHandle (sem_wait
);
1054 conds
.remove (this);
1058 pthread_cond::unblock (const bool all
)
1060 unsigned long releaseable
;
1063 * Block outgoing threads (and avoid simultanous unblocks)
1067 releaseable
= waiting
- pending
;
1070 unsigned long released
;
1075 * Block incoming threads until all waiting threads are released.
1080 * Calculate releaseable again because threads can enter until
1081 * the semaphore has been taken, but they can not leave, therefore pending
1082 * is unchanged and releaseable can only get higher
1084 releaseable
= waiting
- pending
;
1087 released
= all
? releaseable
: 1;
1088 pending
+= released
;
1092 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
1096 * And let the threads release.
1102 pthread_cond::wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
)
1107 if (InterlockedIncrement ((long *)&waiting
) == 1)
1109 else if (mtx_cond
!= mutex
)
1111 InterlockedDecrement ((long *)&waiting
);
1118 * Release the mutex and wait on semaphore
1123 rv
= cancelable_wait (sem_wait
, dwMilliseconds
, cw_no_cancel_self
, cw_sig_eintr
);
1127 if (rv
!= WAIT_OBJECT_0
)
1130 * It might happen that a signal is sent while the thread got canceled
1131 * or timed out. Try to take one.
1132 * If the thread gets one than a signal|broadcast is in progress.
1134 if (WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
1136 * thread got cancelled ot timed out while a signalling is in progress.
1137 * Set wait result back to signaled
1142 InterlockedDecrement ((long *)&waiting
);
1144 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
1146 * All signaled threads are released,
1147 * new threads can enter Wait
1156 if (rv
== WAIT_CANCELED
)
1157 pthread::static_cancel_self ();
1158 else if (rv
== WAIT_SIGNALED
)
1159 /* SUSv3 states: If a signal is delivered to a thread waiting for a
1160 condition variable, upon return from the signal handler the thread
1161 resumes waiting for the condition variable as if it was not
1162 interrupted, or it shall return zero due to spurious wakeup.
1163 We opt for the latter choice here. */
1165 else if (rv
== WAIT_TIMEOUT
)
1172 pthread_cond::_fixup_after_fork ()
1174 waiting
= pending
= 0;
1177 /* Unlock eventually locked mutexes */
1181 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1183 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1186 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1187 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1191 pthread_rwlockattr::~pthread_rwlockattr ()
1195 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
1197 /* This is used for rwlock creation protection within a single process only */
1198 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
1200 /* We can only be called once.
1201 TODO: (no rush) use a non copied memory section to
1202 hold an initialization flag. */
1204 pthread_rwlock::init_mutex ()
1206 if (!rwlock_initialization_lock
.init ())
1207 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1210 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
1211 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
1212 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
1213 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
1216 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
1217 pthread_cond
*verifyable_cond_obj
;
1219 if (!readers_mx
.init ())
1221 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1227 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1233 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1235 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1239 /* Change the mutex type to NORMAL to speed up mutex operations */
1240 mtx
.type
= PTHREAD_MUTEX_NORMAL
;
1242 verifyable_cond_obj
= &cond_readers
;
1243 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1245 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1250 verifyable_cond_obj
= &cond_writers
;
1251 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1253 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1259 rwlocks
.insert (this);
1262 pthread_rwlock::~pthread_rwlock ()
1264 rwlocks
.remove (this);
1268 pthread_rwlock::rdlock ()
1271 struct RWLOCK_READER
*reader
;
1272 pthread_t self
= pthread::self ();
1276 if (lookup_reader (self
))
1282 reader
= new struct RWLOCK_READER
;
1289 while (writer
|| waiting_writers
)
1291 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1294 cond_readers
.wait (&mtx
);
1297 pthread_cleanup_pop (0);
1300 reader
->thread
= self
;
1301 add_reader (reader
);
1310 pthread_rwlock::tryrdlock ()
1313 pthread_t self
= pthread::self ();
1317 if (writer
|| waiting_writers
|| lookup_reader (self
))
1321 struct RWLOCK_READER
*reader
= new struct RWLOCK_READER
;
1324 reader
->thread
= self
;
1325 add_reader (reader
);
1337 pthread_rwlock::wrlock ()
1340 pthread_t self
= pthread::self ();
1344 if (writer
== self
|| lookup_reader (self
))
1350 while (writer
|| readers
)
1352 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1355 cond_writers
.wait (&mtx
);
1358 pthread_cleanup_pop (0);
1370 pthread_rwlock::trywrlock ()
1373 pthread_t self
= pthread::self ();
1377 if (writer
|| readers
)
1388 pthread_rwlock::unlock ()
1391 pthread_t self
= pthread::self ();
1407 struct RWLOCK_READER
*reader
= lookup_reader (self
);
1415 remove_reader (reader
);
1428 pthread_rwlock::add_reader (struct RWLOCK_READER
*rd
)
1430 List_insert (readers
, rd
);
1434 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1436 List_remove (readers_mx
, readers
, rd
);
1439 struct pthread_rwlock::RWLOCK_READER
*
1440 pthread_rwlock::lookup_reader (pthread_t thread
)
1444 struct RWLOCK_READER
*cur
= readers
;
1446 while (cur
&& cur
->thread
!= thread
)
1449 readers_mx
.unlock ();
1455 pthread_rwlock::rdlock_cleanup (void *arg
)
1457 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1459 --(rwlock
->waiting_readers
);
1461 rwlock
->mtx
.unlock ();
1465 pthread_rwlock::wrlock_cleanup (void *arg
)
1467 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1469 --(rwlock
->waiting_writers
);
1471 rwlock
->mtx
.unlock ();
1475 pthread_rwlock::_fixup_after_fork ()
1477 pthread_t self
= pthread::self ();
1478 struct RWLOCK_READER
**temp
= &readers
;
1480 waiting_readers
= 0;
1481 waiting_writers
= 0;
1483 if (!readers_mx
.init ())
1484 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1486 /* Unlock eventually locked mutex */
1489 * Remove all readers except self
1493 if ((*temp
)->thread
== self
)
1494 temp
= &((*temp
)->next
);
1497 struct RWLOCK_READER
*cur
= *temp
;
1498 *temp
= (*temp
)->next
;
1505 /* static members */
1506 /* This stores pthread_key information across fork() boundaries */
1507 List
<pthread_key
> pthread_key::keys
;
1509 /* non-static members */
1511 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1513 tls_index
= TlsAlloc ();
1514 if (tls_index
== TLS_OUT_OF_INDEXES
)
1520 pthread_key::~pthread_key ()
1522 /* We may need to make the list code lock the list during operations
1527 TlsFree (tls_index
);
1532 pthread_key::_fixup_before_fork ()
1538 pthread_key::_fixup_after_fork ()
1540 tls_index
= TlsAlloc ();
1541 if (tls_index
== TLS_OUT_OF_INDEXES
)
1542 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1547 pthread_key::run_destructor ()
1551 void *oldValue
= get ();
1555 destructor (oldValue
);
1562 REMOVED FROM CURRENT. These can be reinstated with the daemon, when all the
1563 gymnastics can be a lot easier.
1565 the mutex_t (size 4) is not used as a verifyable object because we cannot
1566 guarantee the same address space for all processes.
1567 we use the following:
1568 high bit set (never a valid address).
1569 second byte is reserved for the priority.
1570 third byte is reserved
1571 fourth byte is the mutex id. (max 255 cygwin mutexs system wide).
1572 creating mutex's does get slower and slower, but as creation is a one time
1573 job, it should never become an issue
1575 And if you're looking at this and thinking, why not an array in cygwin for all mutexs,
1576 - you incur a penalty on _every_ mutex call and you have toserialise them all.
1579 option 2? put everything in userspace and update the ABI?
1580 - bad karma as well - the HANDLE, while identical across process's,
1581 Isn't duplicated, it's reopened. */
1583 /* static members */
1585 List
<pthread_mutex
> pthread_mutex::mutexes
;
1587 /* This is used for mutex creation protection within a single process only */
1588 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1590 /* We can only be called once.
1591 TODO: (no rush) use a non copied memory section to
1592 hold an initialization flag. */
1594 pthread_mutex::init_mutex ()
1596 if (!mutex_initialization_lock
.init ())
1597 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1600 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1601 verifyable_object (PTHREAD_MUTEX_MAGIC
),
1603 win32_obj_id (NULL
), recursion_counter (0),
1604 condwaits (0), owner (NULL
),
1608 type (PTHREAD_MUTEX_ERRORCHECK
),
1609 pshared (PTHREAD_PROCESS_PRIVATE
)
1611 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1617 /*attr checked in the C call */
1620 if (attr
->pshared
== PTHREAD_PROCESS_SHARED
)
1627 type
= attr
->mutextype
;
1630 mutexes
.insert (this);
1633 pthread_mutex::~pthread_mutex ()
1636 CloseHandle (win32_obj_id
);
1638 mutexes
.remove (this);
1642 pthread_mutex::_lock (pthread_t self
)
1646 if (InterlockedIncrement ((long *)&lock_counter
) == 1)
1648 else if (type
== PTHREAD_MUTEX_NORMAL
|| !pthread::equal (owner
, self
))
1650 cancelable_wait (win32_obj_id
, INFINITE
, cw_no_cancel
, cw_sig_resume
);
1655 InterlockedDecrement ((long *) &lock_counter
);
1656 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1657 result
= lock_recursive ();
1666 pthread_mutex::_trylock (pthread_t self
)
1670 if (InterlockedCompareExchange ((long *) &lock_counter
, 1, 0) == 0)
1672 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1673 result
= lock_recursive ();
1681 pthread_mutex::_unlock (pthread_t self
)
1683 if (!pthread::equal (owner
, self
))
1686 if (--recursion_counter
== 0)
1692 if (InterlockedDecrement ((long *)&lock_counter
))
1693 // Another thread is waiting
1694 ::ReleaseSemaphore (win32_obj_id
, 1, NULL
);
1701 pthread_mutex::_destroy (pthread_t self
)
1703 if (condwaits
|| _trylock (self
))
1704 // Do not destroy a condwaited or locked mutex
1706 else if (recursion_counter
!= 1)
1708 // Do not destroy a recursive locked mutex
1709 --recursion_counter
;
1718 pthread_mutex::_fixup_after_fork ()
1720 debug_printf ("mutex %x in _fixup_after_fork", this);
1721 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1722 api_fatal ("pthread_mutex::_fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's");
1726 /* mutex has no owner, reset to initial */
1732 else if (lock_counter
!= 0)
1734 /* All waiting threads are gone after a fork */
1737 tid
= 0xffffffff; /* Don't know the tid after a fork */
1741 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1743 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
1748 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1749 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_ERRORCHECK
)
1753 pthread_mutexattr::~pthread_mutexattr ()
1757 verifyable_object::verifyable_object (long verifyer
):
1762 verifyable_object::~verifyable_object ()
1768 pthread::thread_init_wrapper (void *arg
)
1770 pthread
*thread
= (pthread
*) arg
;
1771 set_tls_self_pointer (thread
);
1773 thread
->mutex
.lock ();
1775 // if thread is detached force cleanup on exit
1776 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
1777 thread
->joiner
= thread
;
1778 thread
->mutex
.unlock ();
1780 thread_printf ("started thread %p %p %p %p %p %p", arg
, &_my_tls
.local_clib
,
1781 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
1783 // call the user's thread
1784 void *ret
= thread
->function (thread
->arg
);
1788 return 0; // just for show. Never returns.
1792 pthread::getsequence_np ()
1794 return get_thread_id ();
1798 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
1799 void *(*start_routine
) (void *), void *arg
)
1801 if (attr
&& !pthread_attr::is_good_object (attr
))
1804 *thread
= new pthread ();
1805 if (!(*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
))
1816 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
1819 if (once_control
->state
)
1822 pthread_mutex_lock (&once_control
->mutex
);
1823 /* Here we must set a cancellation handler to unlock the mutex if needed */
1824 /* but a cancellation handler is not the right thing. We need this in the thread
1825 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
1826 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
1827 *on pthread_exit ();
1829 if (!once_control
->state
)
1832 once_control
->state
= 1;
1834 /* Here we must remove our cancellation handler */
1835 pthread_mutex_unlock (&once_control
->mutex
);
1840 pthread::cancel (pthread_t thread
)
1842 if (!is_good_object (&thread
))
1845 return thread
->cancel ();
1849 pthread::atforkprepare ()
1851 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
1860 MT_INTERFACE
->fixup_before_fork ();
1864 pthread::atforkparent ()
1868 callback
*cb
= MT_INTERFACE
->pthread_parent
;
1877 pthread::atforkchild ()
1879 MT_INTERFACE
->fixup_after_fork ();
1883 callback
*cb
= MT_INTERFACE
->pthread_child
;
1891 /* Register a set of functions to run before and after fork.
1892 prepare calls are called in LI-FC order.
1893 parent and child calls are called in FI-FC order. */
1895 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
1897 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
1900 prepcb
= new callback
;
1906 parentcb
= new callback
;
1916 childcb
= new callback
;
1929 prepcb
->cb
= prepare
;
1930 List_insert (MT_INTERFACE
->pthread_prepare
, prepcb
);
1934 parentcb
->cb
= parent
;
1935 callback
**t
= &MT_INTERFACE
->pthread_parent
;
1938 /* t = pointer to last next in the list */
1939 List_insert (*t
, parentcb
);
1943 childcb
->cb
= child
;
1944 callback
**t
= &MT_INTERFACE
->pthread_child
;
1947 /* t = pointer to last next in the list */
1948 List_insert (*t
, childcb
);
1954 pthread_attr_init (pthread_attr_t
*attr
)
1956 if (pthread_attr::is_good_object (attr
))
1959 *attr
= new pthread_attr
;
1960 if (!pthread_attr::is_good_object (attr
))
1970 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
1973 if (!pthread_attr::is_good_object (attr
))
1975 *inheritsched
= (*attr
)->inheritsched
;
1980 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
1981 struct sched_param
*param
)
1983 if (!pthread_attr::is_good_object (attr
))
1985 *param
= (*attr
)->schedparam
;
1989 /* From a pure code point of view, this should call a helper in sched.cc,
1990 to allow for someone adding scheduler policy changes to win32 in the future.
1991 However that's extremely unlikely, so short and sweet will do us */
1993 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
1995 if (!pthread_attr::is_good_object (attr
))
1997 *policy
= SCHED_FIFO
;
2003 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
2005 if (!pthread_attr::is_good_object (attr
))
2007 *contentionscope
= (*attr
)->contentionscope
;
2012 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
2014 if (!pthread_attr::is_good_object (attr
))
2016 if (detachstate
< 0 || detachstate
> 1)
2018 (*attr
)->joinable
= detachstate
;
2023 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
2025 if (!pthread_attr::is_good_object (attr
))
2027 *detachstate
= (*attr
)->joinable
;
2032 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
2034 if (!pthread_attr::is_good_object (attr
))
2036 if (inheritsched
!= PTHREAD_INHERIT_SCHED
2037 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
2039 (*attr
)->inheritsched
= inheritsched
;
2044 pthread_attr_setschedparam (pthread_attr_t
*attr
,
2045 const struct sched_param
*param
)
2047 if (!pthread_attr::is_good_object (attr
))
2049 if (!valid_sched_parameters (param
))
2051 (*attr
)->schedparam
= *param
;
2055 /* See __pthread_attr_getschedpolicy for some notes */
2057 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
2059 if (!pthread_attr::is_good_object (attr
))
2061 if (policy
!= SCHED_FIFO
)
2067 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
2069 if (!pthread_attr::is_good_object (attr
))
2071 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
2072 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2074 /* In future, we may be able to support system scope by escalating the thread
2075 priority to exceed the priority class. For now we only support PROCESS scope. */
2076 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2078 (*attr
)->contentionscope
= contentionscope
;
2083 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
2085 if (!pthread_attr::is_good_object (attr
))
2087 (*attr
)->stacksize
= size
;
2092 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
2094 if (!pthread_attr::is_good_object (attr
))
2096 *size
= (*attr
)->stacksize
;
2101 pthread_attr_destroy (pthread_attr_t
*attr
)
2103 if (!pthread_attr::is_good_object (attr
))
2111 pthread::join (pthread_t
*thread
, void **return_val
)
2113 pthread_t joiner
= self ();
2115 joiner
->testcancel ();
2117 // Initialize return val with NULL
2121 if (!is_good_object (&joiner
))
2124 if (!is_good_object (thread
))
2127 if (equal (*thread
,joiner
))
2130 (*thread
)->mutex
.lock ();
2132 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2134 (*thread
)->mutex
.unlock ();
2139 (*thread
)->joiner
= joiner
;
2140 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2141 (*thread
)->mutex
.unlock ();
2143 switch (cancelable_wait ((*thread
)->win32_obj_id
, INFINITE
, cw_no_cancel_self
, cw_sig_resume
))
2147 *return_val
= (*thread
)->return_ptr
;
2151 // set joined thread back to joinable since we got canceled
2152 (*thread
)->joiner
= NULL
;
2153 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2154 joiner
->cancel_self ();
2158 // should never happen
2167 pthread::detach (pthread_t
*thread
)
2169 if (!is_good_object (thread
))
2172 (*thread
)->mutex
.lock ();
2173 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2175 (*thread
)->mutex
.unlock ();
2179 // check if thread is still alive
2180 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2182 // force cleanup on exit
2183 (*thread
)->joiner
= *thread
;
2184 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2185 (*thread
)->mutex
.unlock ();
2189 // thread has already terminated.
2190 (*thread
)->mutex
.unlock ();
2198 pthread::suspend (pthread_t
*thread
)
2200 if (!is_good_object (thread
))
2203 if ((*thread
)->suspended
== false)
2205 (*thread
)->suspended
= true;
2206 SuspendThread ((*thread
)->win32_obj_id
);
2214 pthread::resume (pthread_t
*thread
)
2216 if (!is_good_object (thread
))
2219 if ((*thread
)->suspended
== true)
2220 ResumeThread ((*thread
)->win32_obj_id
);
2221 (*thread
)->suspended
= false;
2226 /* provided for source level compatability.
2227 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2230 pthread_getconcurrency ()
2232 return MT_INTERFACE
->concurrency
;
2235 /* keep this in sync with sched.cc */
2237 pthread_getschedparam (pthread_t thread
, int *policy
,
2238 struct sched_param
*param
)
2240 if (!pthread::is_good_object (&thread
))
2242 *policy
= SCHED_FIFO
;
2243 /* we don't return the current effective priority, we return the current
2244 requested priority */
2245 *param
= thread
->attr
.schedparam
;
2249 /* Thread Specific Data */
2251 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
2253 *key
= new pthread_key (destructor
);
2255 if (!pthread_key::is_good_object (key
))
2265 pthread_key_delete (pthread_key_t key
)
2267 if (!pthread_key::is_good_object (&key
))
2274 /* provided for source level compatability. See
2275 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2278 pthread_setconcurrency (int new_level
)
2282 MT_INTERFACE
->concurrency
= new_level
;
2286 /* keep syncronised with sched.cc */
2288 pthread_setschedparam (pthread_t thread
, int policy
,
2289 const struct sched_param
*param
)
2291 if (!pthread::is_good_object (&thread
))
2293 if (policy
!= SCHED_FIFO
)
2298 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
2300 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
2306 pthread_setspecific (pthread_key_t key
, const void *value
)
2308 if (!pthread_key::is_good_object (&key
))
2315 pthread_getspecific (pthread_key_t key
)
2317 if (!pthread_key::is_good_object (&key
))
2320 return (key
)->get ();
2325 pthread_cond_destroy (pthread_cond_t
*cond
)
2327 if (pthread_cond::is_good_initializer (cond
))
2329 if (!pthread_cond::is_good_object (cond
))
2332 /* reads are atomic */
2333 if ((*cond
)->waiting
)
2343 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2345 pthread_cond_t new_cond
;
2347 if (attr
&& !pthread_condattr::is_good_object (attr
))
2350 cond_initialization_lock
.lock ();
2352 new_cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2353 if (!is_good_object (&new_cond
))
2356 cond_initialization_lock
.unlock ();
2361 if (efault
.faulted ())
2364 cond_initialization_lock
.unlock ();
2369 cond_initialization_lock
.unlock ();
2375 pthread_cond_broadcast (pthread_cond_t
*cond
)
2377 if (pthread_cond::is_good_initializer (cond
))
2379 if (!pthread_cond::is_good_object (cond
))
2382 (*cond
)->unblock (true);
2388 pthread_cond_signal (pthread_cond_t
*cond
)
2390 if (pthread_cond::is_good_initializer (cond
))
2392 if (!pthread_cond::is_good_object (cond
))
2395 (*cond
)->unblock (false);
2401 __pthread_cond_dowait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2404 if (!pthread_mutex::is_good_object (mutex
))
2406 if (!pthread_mutex::can_be_unlocked (mutex
))
2409 if (pthread_cond::is_good_initializer (cond
))
2410 pthread_cond::init (cond
, NULL
);
2411 if (!pthread_cond::is_good_object (cond
))
2414 return (*cond
)->wait (*mutex
, waitlength
);
2418 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2419 const struct timespec
*abstime
)
2425 if (efault
.faulted ())
2428 pthread_testcancel ();
2430 /* According to SUSv3, the abstime value must be checked for validity. */
2431 if (abstime
->tv_sec
< 0
2432 || abstime
->tv_nsec
< 0
2433 || abstime
->tv_nsec
> 999999999)
2436 gettimeofday (&tv
, NULL
);
2437 /* Check for immediate timeout before converting to microseconds, since
2438 the resulting value can easily overflow long. This also allows to
2439 evaluate microseconds directly in DWORD. */
2440 if (tv
.tv_sec
> abstime
->tv_sec
2441 || (tv
.tv_sec
== abstime
->tv_sec
2442 && tv
.tv_usec
> abstime
->tv_nsec
/ 1000))
2445 waitlength
= (abstime
->tv_sec
- tv
.tv_sec
) * 1000;
2446 waitlength
+= (abstime
->tv_nsec
/ 1000 - tv
.tv_usec
) / 1000;
2447 return __pthread_cond_dowait (cond
, mutex
, waitlength
);
2451 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
2453 pthread_testcancel ();
2455 return __pthread_cond_dowait (cond
, mutex
, INFINITE
);
2459 pthread_condattr_init (pthread_condattr_t
*condattr
)
2461 if (pthread_condattr::is_good_object (condattr
))
2464 *condattr
= new pthread_condattr
;
2465 if (!pthread_condattr::is_good_object (condattr
))
2475 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
2477 if (!pthread_condattr::is_good_object (attr
))
2479 *pshared
= (*attr
)->shared
;
2484 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
2486 if (!pthread_condattr::is_good_object (attr
))
2488 if ((pshared
< 0) || (pshared
> 1))
2490 /* shared cond vars not currently supported */
2491 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2493 (*attr
)->shared
= pshared
;
2498 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
2500 if (!pthread_condattr::is_good_object (condattr
))
2508 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
2510 if (pthread_rwlock::is_good_initializer (rwlock
))
2512 if (!pthread_rwlock::is_good_object (rwlock
))
2515 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
2516 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
2526 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2528 pthread_rwlock_t new_rwlock
;
2530 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2533 rwlock_initialization_lock
.lock ();
2535 new_rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2536 if (!is_good_object (&new_rwlock
))
2539 rwlock_initialization_lock
.unlock ();
2544 if (efault
.faulted ())
2547 rwlock_initialization_lock
.unlock ();
2551 *rwlock
= new_rwlock
;
2552 rwlock_initialization_lock
.unlock ();
2558 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
2560 pthread_testcancel ();
2562 if (pthread_rwlock::is_good_initializer (rwlock
))
2563 pthread_rwlock::init (rwlock
, NULL
);
2564 if (!pthread_rwlock::is_good_object (rwlock
))
2567 return (*rwlock
)->rdlock ();
2571 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
2573 if (pthread_rwlock::is_good_initializer (rwlock
))
2574 pthread_rwlock::init (rwlock
, NULL
);
2575 if (!pthread_rwlock::is_good_object (rwlock
))
2578 return (*rwlock
)->tryrdlock ();
2582 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
2584 pthread_testcancel ();
2586 if (pthread_rwlock::is_good_initializer (rwlock
))
2587 pthread_rwlock::init (rwlock
, NULL
);
2588 if (!pthread_rwlock::is_good_object (rwlock
))
2591 return (*rwlock
)->wrlock ();
2595 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
2597 if (pthread_rwlock::is_good_initializer (rwlock
))
2598 pthread_rwlock::init (rwlock
, NULL
);
2599 if (!pthread_rwlock::is_good_object (rwlock
))
2602 return (*rwlock
)->trywrlock ();
2606 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
2608 if (pthread_rwlock::is_good_initializer (rwlock
))
2610 if (!pthread_rwlock::is_good_object (rwlock
))
2613 return (*rwlock
)->unlock ();
2617 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
2619 if (pthread_rwlockattr::is_good_object (rwlockattr
))
2622 *rwlockattr
= new pthread_rwlockattr
;
2623 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2625 delete (*rwlockattr
);
2633 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
2635 if (!pthread_rwlockattr::is_good_object (attr
))
2637 *pshared
= (*attr
)->shared
;
2642 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
2644 if (!pthread_rwlockattr::is_good_object (attr
))
2646 if ((pshared
< 0) || (pshared
> 1))
2648 /* shared rwlock vars not currently supported */
2649 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2651 (*attr
)->shared
= pshared
;
2656 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
2658 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2660 delete (*rwlockattr
);
2667 pthread_kill (pthread_t thread
, int sig
)
2669 // lock myself, for the use of thread2signal
2670 // two different kills might clash: FIXME
2672 if (!pthread::is_good_object (&thread
))
2677 si
.si_code
= SI_USER
;
2678 si
.si_pid
= myself
->pid
;
2679 si
.si_uid
= myself
->uid
;
2680 thread
->cygtls
->set_threadkill ();
2681 int rval
= sig
? sig_send (NULL
, si
, thread
->cygtls
) : 0;
2688 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
2690 return handle_sigprocmask (operation
, set
, old_set
, _my_tls
.sigmask
);
2696 pthread_equal (pthread_t t1
, pthread_t t2
)
2698 return pthread::equal (t1
, t2
);
2704 pthread_mutex::init (pthread_mutex_t
*mutex
,
2705 const pthread_mutexattr_t
*attr
,
2706 const pthread_mutex_t initializer
)
2708 pthread_mutex_t new_mutex
;
2710 if (attr
&& !pthread_mutexattr::is_good_object (attr
))
2713 mutex_initialization_lock
.lock ();
2715 new_mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2716 if (!is_good_object (&new_mutex
))
2719 mutex_initialization_lock
.unlock ();
2723 if (!attr
&& initializer
)
2725 if (initializer
== PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
)
2726 new_mutex
->type
= PTHREAD_MUTEX_RECURSIVE
;
2727 else if (initializer
== PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
)
2728 new_mutex
->type
= PTHREAD_MUTEX_NORMAL
;
2729 else if (initializer
== PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
)
2730 new_mutex
->type
= PTHREAD_MUTEX_ERRORCHECK
;
2734 if (efault
.faulted ())
2737 mutex_initialization_lock
.unlock ();
2742 mutex_initialization_lock
.unlock ();
2748 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
2751 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
2754 We can support mutex priorities in the future though:
2755 Store a priority with each mutex.
2756 When the mutex is optained, set the thread priority as appropriate
2757 When the mutex is released, reset the thread priority. */
2762 pthread_mutex_lock (pthread_mutex_t
*mutex
)
2764 if (pthread_mutex::is_good_initializer (mutex
))
2765 pthread_mutex::init (mutex
, NULL
, *mutex
);
2766 if (!pthread_mutex::is_good_object (mutex
))
2768 return (*mutex
)->lock ();
2772 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
2774 if (pthread_mutex::is_good_initializer (mutex
))
2775 pthread_mutex::init (mutex
, NULL
, *mutex
);
2776 if (!pthread_mutex::is_good_object (mutex
))
2778 return (*mutex
)->trylock ();
2782 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
2784 if (pthread_mutex::is_good_initializer (mutex
))
2786 if (!pthread_mutex::is_good_object (mutex
))
2788 return (*mutex
)->unlock ();
2792 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
2796 if (pthread_mutex::is_good_initializer (mutex
))
2798 if (!pthread_mutex::is_good_object (mutex
))
2801 rv
= (*mutex
)->destroy ();
2810 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
2816 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
2819 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
2822 if (!pthread_mutexattr::is_good_object (attr
))
2828 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
2831 if (!pthread_mutexattr::is_good_object (attr
))
2833 *pshared
= (*attr
)->pshared
;
2838 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
2840 if (!pthread_mutexattr::is_good_object (attr
))
2842 *type
= (*attr
)->mutextype
;
2846 /* FIXME: write and test process shared mutex's. */
2848 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
2850 if (pthread_mutexattr::is_good_object (attr
))
2853 *attr
= new pthread_mutexattr ();
2854 if (!pthread_mutexattr::is_good_object (attr
))
2864 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
2866 if (!pthread_mutexattr::is_good_object (attr
))
2874 /* Win32 doesn't support mutex priorities */
2876 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
2878 if (!pthread_mutexattr::is_good_object (attr
))
2883 /* Win32 doesn't support mutex priorities */
2885 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
2888 if (!pthread_mutexattr::is_good_object (attr
))
2894 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
2897 if (!pthread_mutexattr::is_good_object (attr
))
2903 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
2905 if (!pthread_mutexattr::is_good_object (attr
))
2907 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
2910 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2912 (*attr
)->pshared
= pshared
;
2916 /* see pthread_mutex_gettype */
2918 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
2920 if (!pthread_mutexattr::is_good_object (attr
))
2925 case PTHREAD_MUTEX_ERRORCHECK
:
2926 case PTHREAD_MUTEX_RECURSIVE
:
2927 case PTHREAD_MUTEX_NORMAL
:
2928 (*attr
)->mutextype
= type
;
2939 List
<semaphore
> semaphore::semaphores
;
2941 semaphore::semaphore (int pshared
, unsigned int value
)
2942 : verifyable_object (SEM_MAGIC
),
2944 currentvalue (value
),
2949 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2950 ? sec_all
: sec_none_nih
;
2951 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, NULL
);
2952 if (!this->win32_obj_id
)
2955 semaphores
.insert (this);
2958 semaphore::semaphore (unsigned long long shash
, LUID sluid
, int sfd
,
2959 sem_t
*ssem
, int oflag
, mode_t mode
, unsigned int value
)
2960 : verifyable_object (SEM_MAGIC
),
2961 shared (PTHREAD_PROCESS_SHARED
),
2962 currentvalue (value
), /* Unused for named semaphores. */
2968 char name
[CYG_MAX_PATH
];
2970 __small_sprintf (name
, "%scyg_psem/cyg%016X%08x%08x", cygheap
->shared_prefix
,
2971 hash
, luid
.HighPart
, luid
.LowPart
);
2972 this->win32_obj_id
= ::CreateSemaphore (&sec_all
, value
, LONG_MAX
, name
);
2973 if (!this->win32_obj_id
)
2975 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
2978 CloseHandle (this->win32_obj_id
);
2982 semaphores
.insert (this);
2985 semaphore::~semaphore ()
2988 CloseHandle (win32_obj_id
);
2990 semaphores
.remove (this);
2996 if (ReleaseSemaphore (win32_obj_id
, 1, ¤tvalue
))
3001 semaphore::_getvalue (int *sval
)
3005 switch (WaitForSingleObject (win32_obj_id
, 0))
3008 ReleaseSemaphore (win32_obj_id
, 1, &val
);
3022 semaphore::_trywait ()
3024 /* FIXME: signals should be able to interrupt semaphores...
3025 We probably need WaitForMultipleObjects here. */
3026 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
3036 semaphore::_timedwait (const struct timespec
*abstime
)
3042 if (efault
.faulted ())
3044 /* According to SUSv3, abstime need not be checked for validity,
3045 if the semaphore can be locked immediately. */
3052 gettimeofday (&tv
, NULL
);
3053 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
3054 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
3057 switch (cancelable_wait (win32_obj_id
, waitlength
, cw_cancel_self
, cw_sig_eintr
))
3066 set_errno (ETIMEDOUT
);
3069 debug_printf ("cancelable_wait failed. %E");
3079 switch (cancelable_wait (win32_obj_id
, INFINITE
, cw_cancel_self
, cw_sig_eintr
))
3088 debug_printf ("cancelable_wait failed. %E");
3095 semaphore::_fixup_after_fork ()
3097 if (shared
== PTHREAD_PROCESS_PRIVATE
)
3099 debug_printf ("sem %x in _fixup_after_fork", this);
3100 /* FIXME: duplicate code here and in the constructor. */
3101 this->win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
3104 api_fatal ("failed to create new win32 semaphore, error %d");
3109 semaphore::_terminate ()
3111 int _sem_close (sem_t
*, bool);
3114 _sem_close (sem
, false);
3117 /* static members */
3120 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
3122 /* opengroup calls this undefined */
3123 if (is_good_object (sem
))
3126 if (value
> SEM_VALUE_MAX
)
3129 *sem
= new semaphore (pshared
, value
);
3131 if (!is_good_object (sem
))
3141 semaphore::destroy (sem_t
*sem
)
3143 if (!is_good_object (sem
))
3146 /* It's invalid to destroy a semaphore not opened with sem_init. */
3147 if ((*sem
)->fd
!= -1)
3150 /* FIXME - new feature - test for busy against threads... */
3158 semaphore::close (sem_t
*sem
)
3160 if (!is_good_object (sem
))
3163 /* It's invalid to close a semaphore not opened with sem_open. */
3164 if ((*sem
)->fd
== -1)
3173 semaphore::open (unsigned long long hash
, LUID luid
, int fd
, int oflag
,
3174 mode_t mode
, unsigned int value
, bool &wasopen
)
3176 if (value
> SEM_VALUE_MAX
)
3182 /* sem_open is supposed to return the same pointer, if the same named
3183 semaphore is opened multiple times in the same process, as long as
3184 the semaphore hasn't been closed or unlinked in the meantime. */
3185 semaphores
.mx
.lock ();
3186 for (semaphore
*sema
= semaphores
.head
; sema
; sema
= sema
->next
)
3187 if (sema
->fd
>= 0 && sema
->hash
== hash
3188 && sema
->luid
.HighPart
== luid
.HighPart
3189 && sema
->luid
.LowPart
== sema
->luid
.LowPart
)
3192 semaphores
.mx
.unlock ();
3195 semaphores
.mx
.unlock ();
3198 sem_t
*sem
= new sem_t
;
3205 *sem
= new semaphore (hash
, luid
, fd
, sem
, oflag
, mode
, value
);
3207 if (!is_good_object (sem
))
3217 semaphore::wait (sem_t
*sem
)
3219 pthread_testcancel ();
3221 if (!is_good_object (sem
))
3227 return (*sem
)->_wait ();
3231 semaphore::trywait (sem_t
*sem
)
3233 if (!is_good_object (sem
))
3239 return (*sem
)->_trywait ();
3243 semaphore::timedwait (sem_t
*sem
, const struct timespec
*abstime
)
3245 if (!is_good_object (sem
))
3251 return (*sem
)->_timedwait (abstime
);
3255 semaphore::post (sem_t
*sem
)
3257 if (!is_good_object (sem
))
3268 semaphore::getvalue (sem_t
*sem
, int *sval
)
3271 if (efault
.faulted () || !is_good_object (sem
))
3277 return (*sem
)->_getvalue (sval
);
3281 semaphore::getinternal (sem_t
*sem
, int *sfd
, unsigned long long *shash
,
3282 LUID
*sluid
, unsigned int *sval
)
3285 if (efault
.faulted () || !is_good_object (sem
))
3290 if ((*sfd
= (*sem
)->fd
) < 0)
3295 *shash
= (*sem
)->hash
;
3296 *sluid
= (*sem
)->luid
;
3297 /* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
3298 the sem_getvalue gets a pointer to int to return the value. Go figure! */
3299 return (*sem
)->_getvalue ((int *)sval
);
3304 pthread_null::get_null_pthread ()
3306 /* because of weird entry points */
3307 _instance
.magic
= 0;
3311 pthread_null::pthread_null ()
3313 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
3314 /* Mark ourselves as invalid */
3318 pthread_null::~pthread_null ()
3323 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
3329 pthread_null::exit (void *value_ptr
)
3331 _my_tls
.remove (INFINITE
);
3336 pthread_null::cancel ()
3342 pthread_null::testcancel ()
3347 pthread_null::setcancelstate (int state
, int *oldstate
)
3353 pthread_null::setcanceltype (int type
, int *oldtype
)
3359 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
3364 pthread_null::pop_cleanup_handler (int const execute
)
3369 pthread_null::getsequence_np ()
3374 pthread_null
pthread_null::_instance
;