1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
5 Originally written by Marco Fuykschot <marco@ddi.nl>
6 Substantialy enhanced by Robert Collins <rbtcollins@hotmail.com>
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 /* Implementation overview and caveats:
16 Win32 puts some contraints on what can and cannot be implemented. Where
17 possible we work around those contrainsts. Where we cannot work around
18 the constraints we either pretend to be conformant, or return an error
21 Some caveats: PROCESS_SHARED objects while they pretend to be process
22 shared, may not actually work. Some test cases are needed to determine
23 win32's behaviour. My suspicion is that the win32 handle needs to be
24 opened with different flags for proper operation.
26 R.Collins, April 2001. */
39 #include "perprocess.h"
42 #include <semaphore.h>
44 #include <sys/timeb.h>
45 #include <exceptions.h>
46 #include <sys/fcntl.h>
48 extern int threadsafe
;
51 extern "C" struct _reent
*
54 return &_my_tls
.local_clib
;
57 inline LPCRITICAL_SECTION
58 ResourceLocks::Lock (int _resid
)
64 SetResourceLock (int _res_id
, int _mode
, const char *_function
)
66 EnterCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
70 ReleaseResourceLock (int _res_id
, int _mode
, const char *_function
)
72 LeaveCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
76 ResourceLocks::Init ()
78 InitializeCriticalSection (&lock
);
80 thread_printf ("lock %p inited by %p , %d", &lock
, user_data
, myself
->pid
);
84 ResourceLocks::Delete ()
88 thread_printf ("Close Resource Locks %p ", &lock
);
89 DeleteCriticalSection (&lock
);
97 pthread_mutex::init_mutex ();
98 pthread_cond::init_mutex ();
99 pthread_rwlock::init_mutex ();
103 MTinterface::fixup_before_fork (void)
105 pthread_key::fixup_before_fork ();
108 /* This function is called from a single threaded process */
110 MTinterface::fixup_after_fork (void)
112 pthread_key::fixup_after_fork ();
115 pthread::init_mainthread ();
117 pthread::fixup_after_fork ();
118 pthread_mutex::fixup_after_fork ();
119 pthread_cond::fixup_after_fork ();
120 pthread_rwlock::fixup_after_fork ();
121 semaphore::fixup_after_fork ();
128 pthread::init_mainthread ()
130 pthread
*thread
= get_tls_self_pointer ();
133 thread
= new pthread ();
135 api_fatal ("failed to create mainthread object");
138 thread
->cygtls
= &_my_tls
;
139 _my_tls
.tid
= thread
;
140 thread
->thread_id
= GetCurrentThreadId ();
141 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
142 GetCurrentProcess (), &thread
->win32_obj_id
,
143 0, FALSE
, DUPLICATE_SAME_ACCESS
))
144 api_fatal ("failed to create mainthread handle");
145 if (!thread
->create_cancel_event ())
146 api_fatal ("couldn't create cancel event for main thread");
147 VerifyHandle (thread
->win32_obj_id
);
148 thread
->postcreate ();
154 pthread
*thread
= get_tls_self_pointer ();
157 return pthread_null::get_null_pthread ();
161 pthread::get_tls_self_pointer ()
166 List
<pthread
> pthread::threads
;
169 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
170 valid (false), suspended (false),
171 cancelstate (0), canceltype (0), cancel_event (0),
172 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
174 if (this != pthread_null::get_null_pthread ())
175 threads
.insert (this);
181 CloseHandle (win32_obj_id
);
183 CloseHandle (cancel_event
);
185 if (this != pthread_null::get_null_pthread ())
186 threads
.remove (this);
190 pthread::create_cancel_event ()
192 cancel_event
= ::CreateEvent (&sec_none_nih
, TRUE
, FALSE
, NULL
);
195 system_printf ("couldn't create cancel event, %E");
196 /* we need the event for correct behaviour */
203 pthread::precreate (pthread_attr
*newattr
)
205 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
207 /* already running ? */
213 attr
.joinable
= newattr
->joinable
;
214 attr
.contentionscope
= newattr
->contentionscope
;
215 attr
.inheritsched
= newattr
->inheritsched
;
216 attr
.stacksize
= newattr
->stacksize
;
219 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
221 thread_printf ("New thread object access mutex is not valid. this %p",
226 /* Change the mutex type to NORMAL to speed up mutex operations */
227 mutex
.type
= PTHREAD_MUTEX_NORMAL
;
228 if (!create_cancel_event ())
233 pthread::create (void *(*func
) (void *), pthread_attr
*newattr
,
243 win32_obj_id
= ::CreateThread (&sec_none_nih
, attr
.stacksize
,
244 thread_init_wrapper
, this, CREATE_SUSPENDED
,
249 thread_printf ("CreateThread failed: this %p, %E", this);
255 ResumeThread (win32_obj_id
);
260 pthread::postcreate ()
264 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
265 /* FIXME: set the priority appropriately for system contention scope */
266 if (attr
.inheritsched
== PTHREAD_EXPLICIT_SCHED
)
268 /* FIXME: set the scheduling settings for the new thread */
269 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
274 pthread::exit (void *value_ptr
)
276 class pthread
*thread
= this;
278 // run cleanup handlers
279 pop_all_cleanup_handlers ();
281 pthread_key::run_all_destructors ();
284 // cleanup if thread is in detached state and not joined
285 if (equal (joiner
, thread
))
290 return_ptr
= value_ptr
;
294 (_reclaim_reent
) (_REENT
);
297 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
301 _my_tls
.remove (INFINITE
);
307 pthread::cancel (void)
309 class pthread
*thread
= this;
310 class pthread
*self
= pthread::self ();
320 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
321 cancelstate
== PTHREAD_CANCEL_DISABLE
)
325 SetEvent (cancel_event
);
328 else if (equal (thread
, self
))
332 return 0; // Never reached
335 // cancel asynchronous
336 SuspendThread (win32_obj_id
);
337 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
340 context
.ContextFlags
= CONTEXT_CONTROL
;
341 GetThreadContext (win32_obj_id
, &context
);
342 context
.Eip
= (DWORD
) pthread::static_cancel_self
;
343 SetThreadContext (win32_obj_id
, &context
);
346 ResumeThread (win32_obj_id
);
350 TODO: insert pthread_testcancel into the required functions
351 the required function list is: *indicates done, X indicates not present in cygwin.
370 *pthread_cond_timedwait ()
371 *pthread_cond_wait ()
373 *pthread_testcancel ()
397 the optional list is:
517 Note, that for fcntl (), for any value of the cmd argument.
519 And we must not introduce cancellation points anywhere else that's part of the posix or
525 pthread::testcancel (void)
527 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
530 if (WaitForSingleObject (cancel_event
, 0) == WAIT_OBJECT_0
)
535 pthread::static_cancel_self (void)
537 pthread::self ()->cancel_self ();
541 pthread::cancelable_wait (HANDLE object
, DWORD timeout
, const bool do_cancel
,
542 const bool do_sig_wait
)
546 HANDLE wait_objects
[3];
547 pthread_t thread
= self ();
549 /* Do not change the wait order.
550 The object must have higher priority than the cancel event,
551 because WaitForMultipleObjects will return the smallest index
552 if both objects are signaled. */
553 wait_objects
[num
++] = object
;
554 if (is_good_object (&thread
) &&
555 thread
->cancelstate
!= PTHREAD_CANCEL_DISABLE
)
556 wait_objects
[num
++] = thread
->cancel_event
;
558 wait_objects
[num
++] = signal_arrived
;
560 res
= WaitForMultipleObjects (num
, wait_objects
, FALSE
, timeout
);
561 if (res
== WAIT_CANCELED
)
563 if (num
== 3 || !do_sig_wait
)
566 pthread::static_cancel_self ();
575 pthread::setcancelstate (int state
, int *oldstate
)
581 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
586 *oldstate
= cancelstate
;
596 pthread::setcanceltype (int type
, int *oldtype
)
602 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
607 *oldtype
= canceltype
;
617 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
621 api_fatal ("Attempt to push a cleanup handler across threads");
622 handler
->next
= cleanup_stack
;
623 cleanup_stack
= handler
;
627 pthread::pop_cleanup_handler (int const execute
)
630 // TODO: send a signal or something to the thread ?
631 api_fatal ("Attempt to execute a cleanup handler across threads");
635 if (cleanup_stack
!= NULL
)
637 __pthread_cleanup_handler
*handler
= cleanup_stack
;
640 (*handler
->function
) (handler
->arg
);
641 cleanup_stack
= handler
->next
;
648 pthread::pop_all_cleanup_handlers ()
650 while (cleanup_stack
!= NULL
)
651 pop_cleanup_handler (1);
655 pthread::cancel_self ()
657 exit (PTHREAD_CANCELED
);
661 pthread::get_thread_id ()
667 pthread::_fixup_after_fork ()
669 /* set thread to not running if it is not the forking thread */
670 if (this != pthread::self ())
680 pthread::suspend_except_self ()
682 if (valid
&& this != pthread::self ())
683 SuspendThread (win32_obj_id
);
690 ResumeThread (win32_obj_id
);
695 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
697 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
702 /* instance members */
704 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
705 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
706 inheritsched (PTHREAD_INHERIT_SCHED
), stacksize (0)
708 schedparam
.sched_priority
= 0;
711 pthread_attr::~pthread_attr ()
716 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
718 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
723 pthread_condattr::pthread_condattr ():verifyable_object
724 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
728 pthread_condattr::~pthread_condattr ()
732 List
<pthread_cond
> pthread_cond::conds
;
734 /* This is used for cond creation protection within a single process only */
735 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
737 /* We can only be called once.
738 TODO: (no rush) use a non copied memory section to
739 hold an initialization flag. */
741 pthread_cond::init_mutex ()
743 if (!cond_initialization_lock
.init ())
744 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
747 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
748 verifyable_object (PTHREAD_COND_MAGIC
),
749 shared (0), waiting (0), pending (0), sem_wait (NULL
),
750 mtx_cond(NULL
), next (NULL
)
752 pthread_mutex
*verifyable_mutex_obj
;
755 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
761 verifyable_mutex_obj
= &mtx_in
;
762 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
764 thread_printf ("Internal cond mutex is not valid. this %p", this);
769 * Change the mutex type to NORMAL.
770 * This mutex MUST be of type normal
772 mtx_in
.type
= PTHREAD_MUTEX_NORMAL
;
774 verifyable_mutex_obj
= &mtx_out
;
775 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
777 thread_printf ("Internal cond mutex is not valid. this %p", this);
781 /* Change the mutex type to NORMAL to speed up mutex operations */
782 mtx_out
.type
= PTHREAD_MUTEX_NORMAL
;
784 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
787 debug_printf ("CreateSemaphore failed. %E");
795 pthread_cond::~pthread_cond ()
798 CloseHandle (sem_wait
);
804 pthread_cond::unblock (const bool all
)
806 unsigned long releaseable
;
809 * Block outgoing threads (and avoid simultanous unblocks)
813 releaseable
= waiting
- pending
;
816 unsigned long released
;
821 * Block incoming threads until all waiting threads are released.
826 * Calculate releaseable again because threads can enter until
827 * the semaphore has been taken, but they can not leave, therefore pending
828 * is unchanged and releaseable can only get higher
830 releaseable
= waiting
- pending
;
833 released
= all
? releaseable
: 1;
838 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
842 * And let the threads release.
848 pthread_cond::wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
)
853 if (InterlockedIncrement ((long *)&waiting
) == 1)
855 else if (mtx_cond
!= mutex
)
857 InterlockedDecrement ((long *)&waiting
);
864 * Release the mutex and wait on semaphore
869 rv
= pthread::cancelable_wait (sem_wait
, dwMilliseconds
, false, true);
873 if (rv
!= WAIT_OBJECT_0
)
876 * It might happen that a signal is sent while the thread got canceled
877 * or timed out. Try to take one.
878 * If the thread gets one than a signal|broadcast is in progress.
880 if (WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
882 * thread got cancelled ot timed out while a signalling is in progress.
883 * Set wait result back to signaled
888 InterlockedDecrement ((long *)&waiting
);
890 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
892 * All signaled threads are released,
893 * new threads can enter Wait
902 if (rv
== WAIT_CANCELED
)
903 pthread::static_cancel_self ();
904 else if (rv
== WAIT_SIGNALED
)
905 /* SUSv3 states: If a signal is delivered to a thread waiting for a
906 condition variable, upon return from the signal handler the thread
907 resumes waiting for the condition variable as if it was not
908 interrupted, or it shall return zero due to spurious wakeup.
909 We opt for the latter choice here. */
911 else if (rv
== WAIT_TIMEOUT
)
918 pthread_cond::_fixup_after_fork ()
920 waiting
= pending
= 0;
923 /* Unlock eventually locked mutexes */
927 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
929 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
933 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
935 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
940 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
941 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
945 pthread_rwlockattr::~pthread_rwlockattr ()
949 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
951 /* This is used for rwlock creation protection within a single process only */
952 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
954 /* We can only be called once.
955 TODO: (no rush) use a non copied memory section to
956 hold an initialization flag. */
958 pthread_rwlock::init_mutex ()
960 if (!rwlock_initialization_lock
.init ())
961 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
964 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
965 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
966 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
967 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
970 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
971 pthread_cond
*verifyable_cond_obj
;
973 if (!readers_mx
.init ())
975 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
981 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
987 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
989 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
993 /* Change the mutex type to NORMAL to speed up mutex operations */
994 mtx
.type
= PTHREAD_MUTEX_NORMAL
;
996 verifyable_cond_obj
= &cond_readers
;
997 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
999 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1004 verifyable_cond_obj
= &cond_writers
;
1005 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1007 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1013 rwlocks
.insert (this);
1016 pthread_rwlock::~pthread_rwlock ()
1018 rwlocks
.remove (this);
1022 pthread_rwlock::rdlock ()
1025 struct RWLOCK_READER
*reader
;
1026 pthread_t self
= pthread::self ();
1030 if (lookup_reader (self
))
1036 reader
= new struct RWLOCK_READER
;
1043 while (writer
|| waiting_writers
)
1045 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1048 cond_readers
.wait (&mtx
);
1051 pthread_cleanup_pop (0);
1054 reader
->thread
= self
;
1055 add_reader (reader
);
1064 pthread_rwlock::tryrdlock ()
1067 pthread_t self
= pthread::self ();
1071 if (writer
|| waiting_writers
|| lookup_reader (self
))
1075 struct RWLOCK_READER
*reader
= new struct RWLOCK_READER
;
1078 reader
->thread
= self
;
1079 add_reader (reader
);
1091 pthread_rwlock::wrlock ()
1094 pthread_t self
= pthread::self ();
1098 if (writer
== self
|| lookup_reader (self
))
1104 while (writer
|| readers
)
1106 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1109 cond_writers
.wait (&mtx
);
1112 pthread_cleanup_pop (0);
1124 pthread_rwlock::trywrlock ()
1127 pthread_t self
= pthread::self ();
1131 if (writer
|| readers
)
1142 pthread_rwlock::unlock ()
1145 pthread_t self
= pthread::self ();
1161 struct RWLOCK_READER
*reader
= lookup_reader (self
);
1169 remove_reader (reader
);
1182 pthread_rwlock::add_reader (struct RWLOCK_READER
*rd
)
1184 List_insert (readers
, rd
);
1188 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1190 List_remove (readers_mx
, readers
, rd
);
1193 struct pthread_rwlock::RWLOCK_READER
*
1194 pthread_rwlock::lookup_reader (pthread_t thread
)
1198 struct RWLOCK_READER
*cur
= readers
;
1200 while (cur
&& cur
->thread
!= thread
)
1203 readers_mx
.unlock ();
1209 pthread_rwlock::rdlock_cleanup (void *arg
)
1211 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1213 --(rwlock
->waiting_readers
);
1215 rwlock
->mtx
.unlock ();
1219 pthread_rwlock::wrlock_cleanup (void *arg
)
1221 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1223 --(rwlock
->waiting_writers
);
1225 rwlock
->mtx
.unlock ();
1229 pthread_rwlock::_fixup_after_fork ()
1231 pthread_t self
= pthread::self ();
1232 struct RWLOCK_READER
**temp
= &readers
;
1234 waiting_readers
= 0;
1235 waiting_writers
= 0;
1237 if (!readers_mx
.init ())
1238 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1240 /* Unlock eventually locked mutex */
1243 * Remove all readers except self
1247 if ((*temp
)->thread
== self
)
1248 temp
= &((*temp
)->next
);
1251 struct RWLOCK_READER
*cur
= *temp
;
1252 *temp
= (*temp
)->next
;
1259 /* static members */
1260 /* This stores pthread_key information across fork() boundaries */
1261 List
<pthread_key
> pthread_key::keys
;
1264 pthread_key::is_good_object (pthread_key_t
const *key
)
1266 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
1271 /* non-static members */
1273 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1275 tls_index
= TlsAlloc ();
1276 if (tls_index
== TLS_OUT_OF_INDEXES
)
1282 pthread_key::~pthread_key ()
1284 /* We may need to make the list code lock the list during operations
1289 TlsFree (tls_index
);
1294 pthread_key::set (const void *value
)
1296 /* the OS function doesn't perform error checking */
1297 TlsSetValue (tls_index
, (void *) value
);
1302 pthread_key::get () const
1304 int saved_error
= ::GetLastError ();
1305 void *result
= TlsGetValue (tls_index
);
1306 ::SetLastError (saved_error
);
1311 pthread_key::_fixup_before_fork ()
1317 pthread_key::_fixup_after_fork ()
1319 tls_index
= TlsAlloc ();
1320 if (tls_index
== TLS_OUT_OF_INDEXES
)
1321 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1326 pthread_key::run_destructor ()
1330 void *oldValue
= get ();
1334 destructor (oldValue
);
1341 REMOVED FROM CURRENT. These can be reinstated with the daemon, when all the
1342 gymnastics can be a lot easier.
1344 the mutex_t (size 4) is not used as a verifyable object because we cannot
1345 guarantee the same address space for all processes.
1346 we use the following:
1347 high bit set (never a valid address).
1348 second byte is reserved for the priority.
1349 third byte is reserved
1350 fourth byte is the mutex id. (max 255 cygwin mutexs system wide).
1351 creating mutex's does get slower and slower, but as creation is a one time
1352 job, it should never become an issue
1354 And if you're looking at this and thinking, why not an array in cygwin for all mutexs,
1355 - you incur a penalty on _every_ mutex call and you have toserialise them all.
1358 option 2? put everything in userspace and update the ABI?
1359 - bad karma as well - the HANDLE, while identical across process's,
1360 Isn't duplicated, it's reopened. */
1362 /* static members */
1364 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
1366 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
1372 pthread_mutex::is_good_initializer (pthread_mutex_t
const *mutex
)
1374 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
1375 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
1376 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
1377 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) != VALID_STATIC_OBJECT
)
1383 pthread_mutex::is_good_initializer_or_object (pthread_mutex_t
const *mutex
)
1385 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
1386 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
1387 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
1388 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == INVALID_OBJECT
)
1394 pthread_mutex::is_good_initializer_or_bad_object (pthread_mutex_t
const *mutex
)
1396 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
,
1397 PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
,
1398 PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
,
1399 PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
) == VALID_OBJECT
)
1405 pthread_mutex::can_be_unlocked (pthread_mutex_t
const *mutex
)
1407 pthread_t self
= pthread::self ();
1409 if (!is_good_object (mutex
))
1412 * Check if the mutex is owned by the current thread and can be unlocked
1414 return ((*mutex
)->recursion_counter
== 1 && pthread::equal ((*mutex
)->owner
, self
));
1417 List
<pthread_mutex
> pthread_mutex::mutexes
;
1419 /* This is used for mutex creation protection within a single process only */
1420 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1422 /* We can only be called once.
1423 TODO: (no rush) use a non copied memory section to
1424 hold an initialization flag. */
1426 pthread_mutex::init_mutex ()
1428 if (!mutex_initialization_lock
.init ())
1429 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1432 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1433 verifyable_object (PTHREAD_MUTEX_MAGIC
),
1435 win32_obj_id (NULL
), recursion_counter (0),
1436 condwaits (0), owner (NULL
), type (PTHREAD_MUTEX_DEFAULT
),
1437 pshared (PTHREAD_PROCESS_PRIVATE
)
1439 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1445 /*attr checked in the C call */
1448 if (attr
->pshared
== PTHREAD_PROCESS_SHARED
)
1455 type
= attr
->mutextype
;
1458 mutexes
.insert (this);
1461 pthread_mutex::~pthread_mutex ()
1464 CloseHandle (win32_obj_id
);
1466 mutexes
.remove (this);
1470 pthread_mutex::_lock (pthread_t self
)
1474 if (InterlockedIncrement ((long *)&lock_counter
) == 1)
1476 else if (type
!= PTHREAD_MUTEX_NORMAL
&& pthread::equal (owner
, self
))
1478 InterlockedDecrement ((long *) &lock_counter
);
1479 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1480 result
= lock_recursive ();
1486 WaitForSingleObject (win32_obj_id
, INFINITE
);
1494 pthread_mutex::_trylock (pthread_t self
)
1498 if (InterlockedCompareExchange ((long *) &lock_counter
, 1, 0) == 0)
1500 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1501 result
= lock_recursive ();
1509 pthread_mutex::_unlock (pthread_t self
)
1511 if (!pthread::equal (owner
, self
))
1514 if (--recursion_counter
== 0)
1517 if (InterlockedDecrement ((long *)&lock_counter
))
1518 // Another thread is waiting
1519 ::ReleaseSemaphore (win32_obj_id
, 1, NULL
);
1526 pthread_mutex::_destroy (pthread_t self
)
1528 if (condwaits
|| _trylock (self
))
1529 // Do not destroy a condwaited or locked mutex
1531 else if (recursion_counter
!= 1)
1533 // Do not destroy a recursive locked mutex
1534 --recursion_counter
;
1543 pthread_mutex::_fixup_after_fork ()
1545 debug_printf ("mutex %x in _fixup_after_fork", this);
1546 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1547 api_fatal ("pthread_mutex::_fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's");
1550 /* mutex has no owner, reset to initial */
1552 else if (lock_counter
!= 0)
1553 /* All waiting threads are gone after a fork */
1556 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1558 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
1564 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
1566 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
1571 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1572 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_DEFAULT
)
1576 pthread_mutexattr::~pthread_mutexattr ()
1580 List
<semaphore
> semaphore::semaphores
;
1582 semaphore::semaphore (int pshared
, unsigned int value
)
1583 : verifyable_object (SEM_MAGIC
),
1585 currentvalue (value
),
1588 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1589 ? sec_all
: sec_none_nih
;
1590 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, NULL
);
1591 if (!this->win32_obj_id
)
1594 semaphores
.insert (this);
1597 semaphore::semaphore (const char *sem_name
, int oflag
, mode_t mode
,
1599 : verifyable_object (SEM_MAGIC
),
1600 shared (PTHREAD_PROCESS_SHARED
),
1601 currentvalue (value
), /* Unused for named semaphores. */
1604 if (oflag
& O_CREAT
)
1606 SECURITY_ATTRIBUTES sa
= sec_all
;
1607 security_descriptor sd
;
1609 set_security_attribute (mode
, &sa
, sd
);
1610 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, sem_name
);
1611 if (!this->win32_obj_id
)
1613 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
1616 CloseHandle (this->win32_obj_id
);
1622 this->win32_obj_id
= ::OpenSemaphore (SEMAPHORE_ALL_ACCESS
, FALSE
,
1624 if (!this->win32_obj_id
)
1632 name
= new char [strlen (sem_name
+ 1)];
1636 CloseHandle (this->win32_obj_id
);
1640 strcpy (name
, sem_name
);
1643 semaphores
.insert (this);
1646 semaphore::~semaphore ()
1649 CloseHandle (win32_obj_id
);
1653 semaphores
.remove (this);
1659 if (ReleaseSemaphore (win32_obj_id
, 1, ¤tvalue
))
1664 semaphore::_getvalue (int *sval
)
1668 switch (WaitForSingleObject (win32_obj_id
, 0))
1671 ReleaseSemaphore (win32_obj_id
, 1, &val
);
1685 semaphore::_trywait ()
1687 /* FIXME: signals should be able to interrupt semaphores...
1688 *We probably need WaitForMultipleObjects here.
1690 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
1700 semaphore::_timedwait (const struct timespec
*abstime
)
1705 if (__check_invalid_read_ptr (abstime
, sizeof *abstime
))
1707 /* According to SUSv3, abstime need not be checked for validity,
1708 if the semaphore can be locked immediately. */
1715 gettimeofday (&tv
, NULL
);
1716 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
1717 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
1720 switch (pthread::cancelable_wait (win32_obj_id
, waitlength
, true, true))
1729 set_errno (ETIMEDOUT
);
1732 debug_printf ("cancelable_wait failed. %E");
1742 switch (pthread::cancelable_wait (win32_obj_id
, INFINITE
, true, true))
1751 debug_printf ("cancelable_wait failed. %E");
1758 semaphore::_fixup_after_fork ()
1760 if (shared
== PTHREAD_PROCESS_PRIVATE
)
1762 debug_printf ("sem %x in _fixup_after_fork", this);
1763 /* FIXME: duplicate code here and in the constructor. */
1764 this->win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
1767 api_fatal ("failed to create new win32 semaphore, error %d");
1771 verifyable_object::verifyable_object (long verifyer
):
1776 verifyable_object::~verifyable_object ()
1781 /* Generic memory acccess routine - where should it live ? */
1783 check_valid_pointer (void const *pointer
)
1785 if (!pointer
|| IsBadWritePtr ((void *) pointer
, sizeof (verifyable_object
)))
1790 verifyable_object_state
1791 verifyable_object_isvalid (void const * objectptr
, long magic
, void *static_ptr1
,
1792 void *static_ptr2
, void *static_ptr3
)
1794 verifyable_object
**object
= (verifyable_object
**)objectptr
;
1795 if (check_valid_pointer (object
))
1796 return INVALID_OBJECT
;
1797 if ((static_ptr1
&& *object
== static_ptr1
) ||
1798 (static_ptr2
&& *object
== static_ptr2
) ||
1799 (static_ptr3
&& *object
== static_ptr3
))
1800 return VALID_STATIC_OBJECT
;
1802 return INVALID_OBJECT
;
1803 if (check_valid_pointer (*object
))
1804 return INVALID_OBJECT
;
1805 if ((*object
)->magic
!= magic
)
1806 return INVALID_OBJECT
;
1807 return VALID_OBJECT
;
1811 pthread::thread_init_wrapper (void *arg
)
1813 pthread
*thread
= (pthread
*) arg
;
1814 _my_tls
.tid
= thread
;
1816 thread
->mutex
.lock ();
1818 // if thread is detached force cleanup on exit
1819 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
1820 thread
->joiner
= thread
;
1821 thread
->mutex
.unlock ();
1823 thread_printf ("started thread %p %p %p %p %p %p", arg
, &_my_tls
.local_clib
,
1824 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
1826 // call the user's thread
1827 void *ret
= thread
->function (thread
->arg
);
1831 return 0; // just for show. Never returns.
1835 pthread::is_good_object (pthread_t
const *thread
)
1837 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
1843 pthread::getsequence_np ()
1845 return get_thread_id ();
1849 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
1850 void *(*start_routine
) (void *), void *arg
)
1852 if (attr
&& !pthread_attr::is_good_object (attr
))
1855 *thread
= new pthread ();
1856 (*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
);
1857 if (!is_good_object (thread
))
1868 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
1871 if (once_control
->state
)
1874 pthread_mutex_lock (&once_control
->mutex
);
1875 /* Here we must set a cancellation handler to unlock the mutex if needed */
1876 /* but a cancellation handler is not the right thing. We need this in the thread
1877 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
1878 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
1879 *on pthread_exit ();
1881 if (!once_control
->state
)
1884 once_control
->state
= 1;
1886 /* Here we must remove our cancellation handler */
1887 pthread_mutex_unlock (&once_control
->mutex
);
1892 pthread::cancel (pthread_t thread
)
1894 if (!is_good_object (&thread
))
1897 return thread
->cancel ();
1901 pthread::atforkprepare (void)
1903 MT_INTERFACE
->fixup_before_fork ();
1905 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
1914 pthread::atforkparent (void)
1916 callback
*cb
= MT_INTERFACE
->pthread_parent
;
1925 pthread::atforkchild (void)
1927 MT_INTERFACE
->fixup_after_fork ();
1929 callback
*cb
= MT_INTERFACE
->pthread_child
;
1937 /* Register a set of functions to run before and after fork.
1938 prepare calls are called in LI-FC order.
1939 parent and child calls are called in FI-FC order. */
1941 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
1943 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
1946 prepcb
= new callback
;
1952 parentcb
= new callback
;
1962 childcb
= new callback
;
1975 prepcb
->cb
= prepare
;
1976 List_insert (MT_INTERFACE
->pthread_prepare
, prepcb
);
1980 parentcb
->cb
= parent
;
1981 callback
**t
= &MT_INTERFACE
->pthread_parent
;
1984 /* t = pointer to last next in the list */
1985 List_insert (*t
, parentcb
);
1989 childcb
->cb
= child
;
1990 callback
**t
= &MT_INTERFACE
->pthread_child
;
1993 /* t = pointer to last next in the list */
1994 List_insert (*t
, childcb
);
2000 pthread_attr_init (pthread_attr_t
*attr
)
2002 if (pthread_attr::is_good_object (attr
))
2005 *attr
= new pthread_attr
;
2006 if (!pthread_attr::is_good_object (attr
))
2016 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
2019 if (!pthread_attr::is_good_object (attr
))
2021 *inheritsched
= (*attr
)->inheritsched
;
2026 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
2027 struct sched_param
*param
)
2029 if (!pthread_attr::is_good_object (attr
))
2031 *param
= (*attr
)->schedparam
;
2035 /* From a pure code point of view, this should call a helper in sched.cc,
2036 to allow for someone adding scheduler policy changes to win32 in the future.
2037 However that's extremely unlikely, so short and sweet will do us */
2039 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
2041 if (!pthread_attr::is_good_object (attr
))
2043 *policy
= SCHED_FIFO
;
2049 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
2051 if (!pthread_attr::is_good_object (attr
))
2053 *contentionscope
= (*attr
)->contentionscope
;
2058 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
2060 if (!pthread_attr::is_good_object (attr
))
2062 if (detachstate
< 0 || detachstate
> 1)
2064 (*attr
)->joinable
= detachstate
;
2069 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
2071 if (!pthread_attr::is_good_object (attr
))
2073 *detachstate
= (*attr
)->joinable
;
2078 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
2080 if (!pthread_attr::is_good_object (attr
))
2082 if (inheritsched
!= PTHREAD_INHERIT_SCHED
2083 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
2085 (*attr
)->inheritsched
= inheritsched
;
2090 pthread_attr_setschedparam (pthread_attr_t
*attr
,
2091 const struct sched_param
*param
)
2093 if (!pthread_attr::is_good_object (attr
))
2095 if (!valid_sched_parameters (param
))
2097 (*attr
)->schedparam
= *param
;
2101 /* See __pthread_attr_getschedpolicy for some notes */
2103 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
2105 if (!pthread_attr::is_good_object (attr
))
2107 if (policy
!= SCHED_FIFO
)
2113 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
2115 if (!pthread_attr::is_good_object (attr
))
2117 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
2118 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2120 /* In future, we may be able to support system scope by escalating the thread
2121 priority to exceed the priority class. For now we only support PROCESS scope. */
2122 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2124 (*attr
)->contentionscope
= contentionscope
;
2129 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
2131 if (!pthread_attr::is_good_object (attr
))
2133 (*attr
)->stacksize
= size
;
2138 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
2140 if (!pthread_attr::is_good_object (attr
))
2142 *size
= (*attr
)->stacksize
;
2147 pthread_attr_destroy (pthread_attr_t
*attr
)
2149 if (!pthread_attr::is_good_object (attr
))
2157 pthread::join (pthread_t
*thread
, void **return_val
)
2159 pthread_t joiner
= self ();
2161 joiner
->testcancel ();
2163 // Initialize return val with NULL
2167 if (!is_good_object (&joiner
))
2170 if (!is_good_object (thread
))
2173 if (equal (*thread
,joiner
))
2176 (*thread
)->mutex
.lock ();
2178 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2180 (*thread
)->mutex
.unlock ();
2185 (*thread
)->joiner
= joiner
;
2186 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2187 (*thread
)->mutex
.unlock ();
2191 switch (cancelable_wait ((*thread
)->win32_obj_id
, INFINITE
, false, true))
2195 *return_val
= (*thread
)->return_ptr
;
2199 _my_tls
.call_signal_handler ();
2203 // set joined thread back to joinable since we got canceled
2204 (*thread
)->joiner
= NULL
;
2205 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2206 joiner
->cancel_self ();
2210 // should never happen
2220 pthread::detach (pthread_t
*thread
)
2222 if (!is_good_object (thread
))
2225 (*thread
)->mutex
.lock ();
2226 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2228 (*thread
)->mutex
.unlock ();
2232 // check if thread is still alive
2233 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2235 // force cleanup on exit
2236 (*thread
)->joiner
= *thread
;
2237 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2238 (*thread
)->mutex
.unlock ();
2242 // thread has already terminated.
2243 (*thread
)->mutex
.unlock ();
2251 pthread::suspend (pthread_t
*thread
)
2253 if (!is_good_object (thread
))
2256 if ((*thread
)->suspended
== false)
2258 (*thread
)->suspended
= true;
2259 SuspendThread ((*thread
)->win32_obj_id
);
2267 pthread::resume (pthread_t
*thread
)
2269 if (!is_good_object (thread
))
2272 if ((*thread
)->suspended
== true)
2273 ResumeThread ((*thread
)->win32_obj_id
);
2274 (*thread
)->suspended
= false;
2279 /* provided for source level compatability.
2280 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2283 pthread_getconcurrency (void)
2285 return MT_INTERFACE
->concurrency
;
2288 /* keep this in sync with sched.cc */
2290 pthread_getschedparam (pthread_t thread
, int *policy
,
2291 struct sched_param
*param
)
2293 if (!pthread::is_good_object (&thread
))
2295 *policy
= SCHED_FIFO
;
2296 /* we don't return the current effective priority, we return the current
2297 requested priority */
2298 *param
= thread
->attr
.schedparam
;
2302 /* Thread Specific Data */
2304 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
2306 /* The opengroup docs don't define if we should check this or not,
2307 but creation is relatively rare. */
2308 if (pthread_key::is_good_object (key
))
2311 *key
= new pthread_key (destructor
);
2313 if (!pthread_key::is_good_object (key
))
2323 pthread_key_delete (pthread_key_t key
)
2325 if (!pthread_key::is_good_object (&key
))
2332 /* provided for source level compatability. See
2333 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2336 pthread_setconcurrency (int new_level
)
2340 MT_INTERFACE
->concurrency
= new_level
;
2344 /* keep syncronised with sched.cc */
2346 pthread_setschedparam (pthread_t thread
, int policy
,
2347 const struct sched_param
*param
)
2349 if (!pthread::is_good_object (&thread
))
2351 if (policy
!= SCHED_FIFO
)
2356 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
2358 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
2364 pthread_setspecific (pthread_key_t key
, const void *value
)
2366 if (!pthread_key::is_good_object (&key
))
2373 pthread_getspecific (pthread_key_t key
)
2375 if (!pthread_key::is_good_object (&key
))
2378 return (key
)->get ();
2382 /* Thread synchronisation */
2384 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
2386 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
2392 pthread_cond::is_good_initializer (pthread_cond_t
const *cond
)
2394 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
2400 pthread_cond::is_good_initializer_or_object (pthread_cond_t
const *cond
)
2402 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
2408 pthread_cond::is_good_initializer_or_bad_object (pthread_cond_t
const *cond
)
2410 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == VALID_OBJECT
)
2416 pthread_cond_destroy (pthread_cond_t
*cond
)
2418 if (pthread_cond::is_good_initializer (cond
))
2420 if (!pthread_cond::is_good_object (cond
))
2423 /* reads are atomic */
2424 if ((*cond
)->waiting
)
2434 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2437 pthread_cond_t new_cond
;
2439 if (attr
&& !pthread_condattr::is_good_object (attr
))
2442 cond_initialization_lock
.lock ();
2444 if (!is_good_initializer_or_bad_object (cond
))
2446 cond_initialization_lock
.unlock ();
2450 new_cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2451 if (!is_good_object (&new_cond
))
2454 cond_initialization_lock
.unlock ();
2459 cond_initialization_lock
.unlock ();
2465 pthread_cond_broadcast (pthread_cond_t
*cond
)
2467 if (pthread_cond::is_good_initializer (cond
))
2469 if (!pthread_cond::is_good_object (cond
))
2472 (*cond
)->unblock (true);
2478 pthread_cond_signal (pthread_cond_t
*cond
)
2480 if (pthread_cond::is_good_initializer (cond
))
2482 if (!pthread_cond::is_good_object (cond
))
2485 (*cond
)->unblock (false);
2491 __pthread_cond_dowait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2494 if (!pthread_mutex::is_good_object (mutex
))
2496 if (!pthread_mutex::can_be_unlocked (mutex
))
2499 if (pthread_cond::is_good_initializer (cond
))
2500 pthread_cond::init (cond
, NULL
);
2501 if (!pthread_cond::is_good_object (cond
))
2504 return (*cond
)->wait (*mutex
, waitlength
);
2508 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2509 const struct timespec
*abstime
)
2514 pthread_testcancel ();
2516 if (check_valid_pointer (abstime
))
2519 gettimeofday (&tv
, NULL
);
2520 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
2521 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
2524 return __pthread_cond_dowait (cond
, mutex
, waitlength
);
2528 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
2530 pthread_testcancel ();
2532 return __pthread_cond_dowait (cond
, mutex
, INFINITE
);
2536 pthread_condattr_init (pthread_condattr_t
*condattr
)
2538 if (pthread_condattr::is_good_object (condattr
))
2541 *condattr
= new pthread_condattr
;
2542 if (!pthread_condattr::is_good_object (condattr
))
2552 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
2554 if (!pthread_condattr::is_good_object (attr
))
2556 *pshared
= (*attr
)->shared
;
2561 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
2563 if (!pthread_condattr::is_good_object (attr
))
2565 if ((pshared
< 0) || (pshared
> 1))
2567 /* shared cond vars not currently supported */
2568 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2570 (*attr
)->shared
= pshared
;
2575 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
2577 if (!pthread_condattr::is_good_object (condattr
))
2586 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
2588 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
2594 pthread_rwlock::is_good_initializer (pthread_rwlock_t
const *rwlock
)
2596 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
2602 pthread_rwlock::is_good_initializer_or_object (pthread_rwlock_t
const *rwlock
)
2604 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
2610 pthread_rwlock::is_good_initializer_or_bad_object (pthread_rwlock_t
const *rwlock
)
2612 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == VALID_OBJECT
)
2618 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
2620 if (pthread_rwlock::is_good_initializer (rwlock
))
2622 if (!pthread_rwlock::is_good_object (rwlock
))
2625 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
2626 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
2636 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2638 pthread_rwlock_t new_rwlock
;
2640 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2643 rwlock_initialization_lock
.lock ();
2645 if (!is_good_initializer_or_bad_object (rwlock
))
2647 rwlock_initialization_lock
.unlock ();
2651 new_rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2652 if (!is_good_object (&new_rwlock
))
2655 rwlock_initialization_lock
.unlock ();
2659 *rwlock
= new_rwlock
;
2660 rwlock_initialization_lock
.unlock ();
2666 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
2668 pthread_testcancel ();
2670 if (pthread_rwlock::is_good_initializer (rwlock
))
2671 pthread_rwlock::init (rwlock
, NULL
);
2672 if (!pthread_rwlock::is_good_object (rwlock
))
2675 return (*rwlock
)->rdlock ();
2679 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
2681 if (pthread_rwlock::is_good_initializer (rwlock
))
2682 pthread_rwlock::init (rwlock
, NULL
);
2683 if (!pthread_rwlock::is_good_object (rwlock
))
2686 return (*rwlock
)->tryrdlock ();
2690 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
2692 pthread_testcancel ();
2694 if (pthread_rwlock::is_good_initializer (rwlock
))
2695 pthread_rwlock::init (rwlock
, NULL
);
2696 if (!pthread_rwlock::is_good_object (rwlock
))
2699 return (*rwlock
)->wrlock ();
2703 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
2705 if (pthread_rwlock::is_good_initializer (rwlock
))
2706 pthread_rwlock::init (rwlock
, NULL
);
2707 if (!pthread_rwlock::is_good_object (rwlock
))
2710 return (*rwlock
)->trywrlock ();
2714 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
2716 if (pthread_rwlock::is_good_initializer (rwlock
))
2718 if (!pthread_rwlock::is_good_object (rwlock
))
2721 return (*rwlock
)->unlock ();
2725 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
2727 if (pthread_rwlockattr::is_good_object (rwlockattr
))
2730 *rwlockattr
= new pthread_rwlockattr
;
2731 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2733 delete (*rwlockattr
);
2741 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
2743 if (!pthread_rwlockattr::is_good_object (attr
))
2745 *pshared
= (*attr
)->shared
;
2750 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
2752 if (!pthread_rwlockattr::is_good_object (attr
))
2754 if ((pshared
< 0) || (pshared
> 1))
2756 /* shared rwlock vars not currently supported */
2757 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2759 (*attr
)->shared
= pshared
;
2764 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
2766 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2768 delete (*rwlockattr
);
2775 pthread_kill (pthread_t thread
, int sig
)
2777 // lock myself, for the use of thread2signal
2778 // two different kills might clash: FIXME
2780 if (!pthread::is_good_object (&thread
))
2785 si
.si_code
= SI_USER
;
2786 si
.si_pid
= si
.si_uid
= si
.si_errno
= 0;
2787 thread
->cygtls
->set_threadkill ();
2788 int rval
= sig
? sig_send (NULL
, si
, thread
->cygtls
) : 0;
2795 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
2797 return handle_sigprocmask (operation
, set
, old_set
, _my_tls
.sigmask
);
2803 pthread_equal (pthread_t t1
, pthread_t t2
)
2805 return pthread::equal (t1
, t2
);
2811 pthread_mutex::init (pthread_mutex_t
*mutex
,
2812 const pthread_mutexattr_t
*attr
,
2813 const pthread_mutex_t initializer
)
2815 pthread_mutex_t new_mutex
;
2817 if (attr
&& !pthread_mutexattr::is_good_object (attr
) || check_valid_pointer (mutex
))
2820 mutex_initialization_lock
.lock ();
2822 if (!is_good_initializer_or_bad_object (mutex
))
2824 mutex_initialization_lock
.unlock ();
2828 new_mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2829 if (!is_good_object (&new_mutex
))
2832 mutex_initialization_lock
.unlock ();
2836 if (!attr
&& initializer
)
2838 if (initializer
== PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
)
2839 new_mutex
->type
= PTHREAD_MUTEX_RECURSIVE
;
2840 else if (initializer
== PTHREAD_NORMAL_MUTEX_INITIALIZER_NP
)
2841 new_mutex
->type
= PTHREAD_MUTEX_NORMAL
;
2842 else if (initializer
== PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
)
2843 new_mutex
->type
= PTHREAD_MUTEX_ERRORCHECK
;
2847 mutex_initialization_lock
.unlock ();
2853 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
2856 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
2859 We can support mutex priorities in the future though:
2860 Store a priority with each mutex.
2861 When the mutex is optained, set the thread priority as appropriate
2862 When the mutex is released, reset the thread priority. */
2867 pthread_mutex_lock (pthread_mutex_t
*mutex
)
2869 if (pthread_mutex::is_good_initializer (mutex
))
2870 pthread_mutex::init (mutex
, NULL
, *mutex
);
2871 if (!pthread_mutex::is_good_object (mutex
))
2873 return (*mutex
)->lock ();
2877 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
2879 if (pthread_mutex::is_good_initializer (mutex
))
2880 pthread_mutex::init (mutex
, NULL
, *mutex
);
2881 if (!pthread_mutex::is_good_object (mutex
))
2883 return (*mutex
)->trylock ();
2887 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
2889 if (pthread_mutex::is_good_initializer (mutex
))
2891 if (!pthread_mutex::is_good_object (mutex
))
2893 return (*mutex
)->unlock ();
2897 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
2901 if (pthread_mutex::is_good_initializer (mutex
))
2903 if (!pthread_mutex::is_good_object (mutex
))
2906 rv
= (*mutex
)->destroy ();
2915 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
2921 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
2924 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
2927 if (!pthread_mutexattr::is_good_object (attr
))
2933 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
2936 if (!pthread_mutexattr::is_good_object (attr
))
2938 *pshared
= (*attr
)->pshared
;
2943 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
2945 if (!pthread_mutexattr::is_good_object (attr
))
2947 *type
= (*attr
)->mutextype
;
2951 /* FIXME: write and test process shared mutex's. */
2953 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
2955 if (pthread_mutexattr::is_good_object (attr
))
2958 *attr
= new pthread_mutexattr ();
2959 if (!pthread_mutexattr::is_good_object (attr
))
2969 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
2971 if (!pthread_mutexattr::is_good_object (attr
))
2979 /* Win32 doesn't support mutex priorities */
2981 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
2983 if (!pthread_mutexattr::is_good_object (attr
))
2988 /* Win32 doesn't support mutex priorities */
2990 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
2993 if (!pthread_mutexattr::is_good_object (attr
))
2999 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
3002 if (!pthread_mutexattr::is_good_object (attr
))
3008 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
3010 if (!pthread_mutexattr::is_good_object (attr
))
3012 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3015 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
3017 (*attr
)->pshared
= pshared
;
3021 /* see pthread_mutex_gettype */
3023 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
3025 if (!pthread_mutexattr::is_good_object (attr
))
3030 case PTHREAD_MUTEX_ERRORCHECK
:
3031 case PTHREAD_MUTEX_RECURSIVE
:
3032 case PTHREAD_MUTEX_NORMAL
:
3033 (*attr
)->mutextype
= type
;
3044 /* static members */
3046 semaphore::is_good_object (sem_t
const * sem
)
3048 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
3054 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
3056 /* opengroup calls this undefined */
3057 if (is_good_object (sem
))
3060 if (value
> SEM_VALUE_MAX
)
3063 *sem
= new semaphore (pshared
, value
);
3065 if (!is_good_object (sem
))
3075 semaphore::destroy (sem_t
*sem
)
3077 if (!is_good_object (sem
))
3080 /* FIXME - new feature - test for busy against threads... */
3088 semaphore::open (const char *name
, int oflag
, mode_t mode
, unsigned int value
)
3090 if (value
> SEM_VALUE_MAX
)
3096 sem_t
*sem
= new sem_t
;
3103 *sem
= new semaphore (name
, oflag
, mode
, value
);
3105 if (!is_good_object (sem
))
3115 semaphore::wait (sem_t
*sem
)
3117 pthread_testcancel ();
3119 if (!is_good_object (sem
))
3125 return (*sem
)->_wait ();
3129 semaphore::trywait (sem_t
*sem
)
3131 if (!is_good_object (sem
))
3137 return (*sem
)->_trywait ();
3141 semaphore::timedwait (sem_t
*sem
, const struct timespec
*abstime
)
3143 if (!is_good_object (sem
))
3149 return (*sem
)->_timedwait (abstime
);
3153 semaphore::post (sem_t
*sem
)
3155 if (!is_good_object (sem
))
3166 semaphore::getvalue (sem_t
*sem
, int *sval
)
3169 if (!is_good_object (sem
)
3170 || __check_null_invalid_struct (sval
, sizeof (int)))
3176 return (*sem
)->_getvalue (sval
);
3181 pthread_null::get_null_pthread ()
3183 /* because of weird entry points */
3184 _instance
.magic
= 0;
3188 pthread_null::pthread_null ()
3190 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
3191 /* Mark ourselves as invalid */
3195 pthread_null::~pthread_null ()
3200 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
3205 pthread_null::exit (void *value_ptr
)
3211 pthread_null::cancel ()
3217 pthread_null::testcancel ()
3222 pthread_null::setcancelstate (int state
, int *oldstate
)
3228 pthread_null::setcanceltype (int type
, int *oldtype
)
3234 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
3239 pthread_null::pop_cleanup_handler (int const execute
)
3244 pthread_null::getsequence_np ()
3249 pthread_null
pthread_null::_instance
;