1 /* thread.cc: Locking and threading module functions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003 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"
41 #include "exceptions.h"
42 #include <semaphore.h>
44 #include <sys/timeb.h>
45 #include <sys/fcntl.h>
47 extern int threadsafe
;
49 extern "C" struct _reent
*
52 struct __reent_t
*_r
=
53 (struct __reent_t
*) MT_INTERFACE
->reent_key
.get ();
57 #ifdef _CYG_THREAD_FAILSAFE
58 system_printf ("local thread storage not inited");
60 /* Return _impure_ptr as long as MTinterface is not initialized */
70 struct __reent_t
*_r
=
71 (struct __reent_t
*) MT_INTERFACE
->reent_key
.get ();
75 #ifdef _CYG_THREAD_FAILSAFE
76 system_printf ("local thread storage not inited");
84 inline LPCRITICAL_SECTION
85 ResourceLocks::Lock (int _resid
)
87 #ifdef _CYG_THREAD_FAILSAFE
89 system_printf ("lock called before initialization");
92 ("Get Resource lock %d ==> %p for %p , real : %d , threadid %d ", _resid
,
93 &lock
, user_data
, myself
->pid
, GetCurrentThreadId ());
99 SetResourceLock (int _res_id
, int _mode
, const char *_function
)
101 #ifdef _CYG_THREAD_FAILSAFE
102 thread_printf ("Set resource lock %d mode %d for %s start",
103 _res_id
, _mode
, _function
);
105 EnterCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
107 #ifdef _CYG_THREAD_FAILSAFE
108 user_data
->resourcelocks
->owner
= GetCurrentThreadId ();
109 user_data
->resourcelocks
->count
++;
114 ReleaseResourceLock (int _res_id
, int _mode
, const char *_function
)
116 #ifdef _CYG_THREAD_FAILSAFE
117 thread_printf ("Release resource lock %d mode %d for %s done", _res_id
,
120 AssertResourceOwner (_res_id
, _mode
);
121 user_data
->resourcelocks
->count
--;
122 if (user_data
->resourcelocks
->count
== 0)
123 user_data
->resourcelocks
->owner
= 0;
126 LeaveCriticalSection (user_data
->resourcelocks
->Lock (_res_id
));
129 #ifdef _CYG_THREAD_FAILSAFE
131 AssertResourceOwner (int _res_id
, int _mode
)
135 ("Assert Resource lock %d ==> for %p , real : %d , threadid %d count %d owner %d",
136 _res_id
, user_data
, myself
->pid
, GetCurrentThreadId (),
137 user_data
->resourcelocks
->count
, user_data
->resourcelocks
->owner
);
138 if (user_data
&& (user_data
->resourcelocks
->owner
!= GetCurrentThreadId ()))
139 system_printf ("assertion failed, not the resource owner");
145 ResourceLocks::Init ()
147 InitializeCriticalSection (&lock
);
150 #ifdef _CYG_THREAD_FAILSAFE
155 thread_printf ("lock %p inited by %p , %d", &lock
, user_data
, myself
->pid
);
159 ResourceLocks::Delete ()
163 thread_printf ("Close Resource Locks %p ", &lock
);
164 DeleteCriticalSection (&lock
);
172 reents
._clib
= _impure_ptr
;
173 reents
._winsup
= &winsup_reent
;
174 winsup_reent
._process_logmask
= LOG_UPTO (LOG_DEBUG
);
175 reent_key
.set (&reents
);
177 pthread_mutex::init_mutex ();
178 pthread_cond::init_mutex ();
179 pthread_rwlock::init_mutex ();
183 MTinterface::fixup_before_fork (void)
185 pthread_key::fixup_before_fork ();
188 /* This function is called from a single threaded process */
190 MTinterface::fixup_after_fork (void)
192 pthread_key::fixup_after_fork ();
194 #ifndef __SIGNALS_ARE_MULTITHREADED__
195 /* As long as the signal handling not multithreaded
196 switch reents storage back to _impure_ptr for the mainthread
197 to support fork from threads other than the mainthread */
198 reents
._clib
= _impure_ptr
;
199 reents
._winsup
= &winsup_reent
;
200 winsup_reent
._process_logmask
= LOG_UPTO (LOG_DEBUG
);
201 reent_key
.set (&reents
);
205 pthread::init_mainthread ();
207 pthread::fixup_after_fork ();
208 pthread_mutex::fixup_after_fork ();
209 pthread_cond::fixup_after_fork ();
210 pthread_rwlock::fixup_after_fork ();
211 semaphore::fixup_after_fork ();
218 pthread::init_mainthread ()
220 pthread
*thread
= get_tls_self_pointer ();
223 thread
= new pthread ();
225 api_fatal ("failed to create mainthread object");
228 thread
->init_current_thread ();
234 pthread
*thread
= get_tls_self_pointer ();
237 return pthread_null::get_null_pthread ();
241 pthread::set_tls_self_pointer (pthread
*thisThread
)
243 MT_INTERFACE
->thread_self_key
.set (thisThread
);
247 pthread::get_tls_self_pointer ()
249 return (pthread
*) MT_INTERFACE
->thread_self_key
.get ();
254 List
<pthread
> pthread::threads
;
257 pthread::pthread ():verifyable_object (PTHREAD_MAGIC
), win32_obj_id (0),
258 valid (false), suspended (false),
259 cancelstate (0), canceltype (0), cancel_event (0),
260 joiner (NULL
), next (NULL
), cleanup_stack (NULL
)
262 if (this != pthread_null::get_null_pthread ())
263 threads
.insert (this);
269 CloseHandle (win32_obj_id
);
271 CloseHandle (cancel_event
);
273 if (this != pthread_null::get_null_pthread ())
274 threads
.remove (this);
278 pthread::set_thread_id_to_current ()
280 thread_id
= GetCurrentThreadId ();
284 pthread::precreate (pthread_attr
*newattr
)
286 pthread_mutex
*verifyable_mutex_obj
= &mutex
;
288 /* already running ? */
294 attr
.joinable
= newattr
->joinable
;
295 attr
.contentionscope
= newattr
->contentionscope
;
296 attr
.inheritsched
= newattr
->inheritsched
;
297 attr
.stacksize
= newattr
->stacksize
;
300 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
302 thread_printf ("New thread object access mutex is not valid. this %p",
307 /* Change the mutex type to NORMAL to speed up mutex operations */
308 mutex
.type
= PTHREAD_MUTEX_NORMAL
;
310 cancel_event
= ::CreateEvent (&sec_none_nih
, TRUE
, FALSE
, NULL
);
313 system_printf ("couldn't create cancel event, this %p LastError %E", this);
314 /* we need the event for correct behaviour */
321 pthread::create (void *(*func
) (void *), pthread_attr
*newattr
,
331 win32_obj_id
= ::CreateThread (&sec_none_nih
, attr
.stacksize
,
332 (LPTHREAD_START_ROUTINE
) thread_init_wrapper
,
333 this, CREATE_SUSPENDED
, &thread_id
);
337 thread_printf ("CreateThread failed: this %p LastError %E", this);
343 ResumeThread (win32_obj_id
);
348 pthread::postcreate ()
352 InterlockedIncrement (&MT_INTERFACE
->threadcount
);
353 /* FIXME: set the priority appropriately for system contention scope */
354 if (attr
.inheritsched
== PTHREAD_EXPLICIT_SCHED
)
356 /* FIXME: set the scheduling settings for the new thread */
357 /* sched_thread_setparam (win32_obj_id, attr.schedparam); */
362 pthread::exit (void *value_ptr
)
364 class pthread
*thread
= this;
366 // run cleanup handlers
367 pop_all_cleanup_handlers ();
369 pthread_key::run_all_destructors ();
372 // cleanup if thread is in detached state and not joined
373 if (equal (joiner
, thread
))
378 return_ptr
= value_ptr
;
382 (_reclaim_reent
) (_REENT
);
384 if (InterlockedDecrement (&MT_INTERFACE
->threadcount
) == 0)
391 pthread::cancel (void)
393 class pthread
*thread
= this;
394 class pthread
*self
= pthread::self ();
404 if (canceltype
== PTHREAD_CANCEL_DEFERRED
||
405 cancelstate
== PTHREAD_CANCEL_DISABLE
)
409 SetEvent (cancel_event
);
412 else if (equal (thread
, self
))
416 return 0; // Never reached
419 // cancel asynchronous
420 SuspendThread (win32_obj_id
);
421 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
424 context
.ContextFlags
= CONTEXT_CONTROL
;
425 GetThreadContext (win32_obj_id
, &context
);
426 context
.Eip
= (DWORD
) pthread::static_cancel_self
;
427 SetThreadContext (win32_obj_id
, &context
);
430 ResumeThread (win32_obj_id
);
434 TODO: insert pthread_testcancel into the required functions
435 the required function list is: *indicates done, X indicates not present in cygwin.
454 *pthread_cond_timedwait ()
455 *pthread_cond_wait ()
457 *pthread_testcancel ()
481 the optional list is:
601 Note, that for fcntl (), for any value of the cmd argument.
603 And we must not introduce cancellation points anywhere else that's part of the posix or
609 pthread::testcancel (void)
611 if (cancelstate
== PTHREAD_CANCEL_DISABLE
)
614 if (WaitForSingleObject (cancel_event
, 0) == WAIT_OBJECT_0
)
619 pthread::static_cancel_self (void)
621 pthread::self ()->cancel_self ();
626 pthread::cancelable_wait (HANDLE object
, DWORD timeout
, const bool do_cancel
)
629 HANDLE wait_objects
[2];
630 pthread_t thread
= self ();
632 if (!is_good_object (&thread
) || thread
->cancelstate
== PTHREAD_CANCEL_DISABLE
)
633 return WaitForSingleObject (object
, timeout
);
635 // Do not change the wait order
636 // The object must have higher priority than the cancel event,
637 // because WaitForMultipleObjects will return the smallest index
638 // if both objects are signaled
639 wait_objects
[0] = object
;
640 wait_objects
[1] = thread
->cancel_event
;
642 res
= WaitForMultipleObjects (2, wait_objects
, FALSE
, timeout
);
643 if (do_cancel
&& res
== WAIT_CANCELED
)
644 pthread::static_cancel_self ();
649 pthread::setcancelstate (int state
, int *oldstate
)
655 if (state
!= PTHREAD_CANCEL_ENABLE
&& state
!= PTHREAD_CANCEL_DISABLE
)
660 *oldstate
= cancelstate
;
670 pthread::setcanceltype (int type
, int *oldtype
)
676 if (type
!= PTHREAD_CANCEL_DEFERRED
&& type
!= PTHREAD_CANCEL_ASYNCHRONOUS
)
681 *oldtype
= canceltype
;
691 pthread::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
695 api_fatal ("Attempt to push a cleanup handler across threads");
696 handler
->next
= cleanup_stack
;
697 cleanup_stack
= handler
;
701 pthread::pop_cleanup_handler (int const execute
)
704 // TODO: send a signal or something to the thread ?
705 api_fatal ("Attempt to execute a cleanup handler across threads");
709 if (cleanup_stack
!= NULL
)
711 __pthread_cleanup_handler
*handler
= cleanup_stack
;
714 (*handler
->function
) (handler
->arg
);
715 cleanup_stack
= handler
->next
;
722 pthread::pop_all_cleanup_handlers ()
724 while (cleanup_stack
!= NULL
)
725 pop_cleanup_handler (1);
729 pthread::cancel_self ()
731 exit (PTHREAD_CANCELED
);
735 pthread::get_thread_id ()
741 pthread::init_current_thread ()
743 cancel_event
= ::CreateEvent (&sec_none_nih
, TRUE
, FALSE
, NULL
);
744 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
745 GetCurrentProcess (), &win32_obj_id
,
746 0, FALSE
, DUPLICATE_SAME_ACCESS
))
748 set_thread_id_to_current ();
749 set_tls_self_pointer (this);
754 pthread::_fixup_after_fork ()
756 /* set thread to not running if it is not the forking thread */
757 if (this != pthread::self ())
767 pthread::suspend_except_self ()
769 if (valid
&& this != pthread::self ())
770 SuspendThread (win32_obj_id
);
777 ResumeThread (win32_obj_id
);
782 pthread_attr::is_good_object (pthread_attr_t
const *attr
)
784 if (verifyable_object_isvalid (attr
, PTHREAD_ATTR_MAGIC
) != VALID_OBJECT
)
789 /* instance members */
791 pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC
),
792 joinable (PTHREAD_CREATE_JOINABLE
), contentionscope (PTHREAD_SCOPE_PROCESS
),
793 inheritsched (PTHREAD_INHERIT_SCHED
), stacksize (0)
795 schedparam
.sched_priority
= 0;
798 pthread_attr::~pthread_attr ()
803 pthread_condattr::is_good_object (pthread_condattr_t
const *attr
)
805 if (verifyable_object_isvalid (attr
, PTHREAD_CONDATTR_MAGIC
) != VALID_OBJECT
)
810 pthread_condattr::pthread_condattr ():verifyable_object
811 (PTHREAD_CONDATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
815 pthread_condattr::~pthread_condattr ()
819 List
<pthread_cond
> pthread_cond::conds
;
821 /* This is used for cond creation protection within a single process only */
822 fast_mutex NO_COPY
pthread_cond::cond_initialization_lock
;
824 /* We can only be called once.
825 TODO: (no rush) use a non copied memory section to
826 hold an initialization flag. */
828 pthread_cond::init_mutex ()
830 if (!cond_initialization_lock
.init ())
831 api_fatal ("Could not create win32 Mutex for pthread cond static initializer support.");
834 pthread_cond::pthread_cond (pthread_condattr
*attr
) :
835 verifyable_object (PTHREAD_COND_MAGIC
),
836 shared (0), waiting (0), pending (0), sem_wait (NULL
),
837 mtx_cond(NULL
), next (NULL
)
839 pthread_mutex
*verifyable_mutex_obj
;
842 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
848 verifyable_mutex_obj
= &mtx_in
;
849 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
851 thread_printf ("Internal cond mutex is not valid. this %p", this);
856 * Change the mutex type to NORMAL.
857 * This mutex MUST be of type normal
859 mtx_in
.type
= PTHREAD_MUTEX_NORMAL
;
861 verifyable_mutex_obj
= &mtx_out
;
862 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
864 thread_printf ("Internal cond mutex is not valid. this %p", this);
868 /* Change the mutex type to NORMAL to speed up mutex operations */
869 mtx_out
.type
= PTHREAD_MUTEX_NORMAL
;
871 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
874 debug_printf ("CreateSemaphore failed. %E");
882 pthread_cond::~pthread_cond ()
885 CloseHandle (sem_wait
);
891 pthread_cond::unblock (const bool all
)
893 unsigned long releaseable
;
896 * Block outgoing threads (and avoid simultanous unblocks)
900 releaseable
= waiting
- pending
;
903 unsigned long released
;
908 * Block incoming threads until all waiting threads are released.
913 * Calculate releaseable again because threads can enter until
914 * the semaphore has been taken, but they can not leave, therefore pending
915 * is unchanged and releaseable can only get higher
917 releaseable
= waiting
- pending
;
920 released
= all
? releaseable
: 1;
925 ::ReleaseSemaphore (sem_wait
, released
, NULL
);
929 * And let the threads release.
935 pthread_cond::wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
)
940 if (InterlockedIncrement ((long *)&waiting
) == 1)
942 else if (mtx_cond
!= mutex
)
944 InterlockedDecrement ((long *)&waiting
);
951 * Release the mutex and wait on semaphore
956 rv
= pthread::cancelable_wait (sem_wait
, dwMilliseconds
, false);
960 if (rv
!= WAIT_OBJECT_0
)
963 * It might happen that a signal is sent while the thread got canceled
964 * or timed out. Try to take one.
965 * If the thread gets one than a signal|broadcast is in progress.
967 if (WaitForSingleObject (sem_wait
, 0) == WAIT_OBJECT_0
)
969 * thread got cancelled ot timed out while a signalling is in progress.
970 * Set wait result back to signaled
975 InterlockedDecrement ((long *)&waiting
);
977 if (rv
== WAIT_OBJECT_0
&& --pending
== 0)
979 * All signaled threads are released,
980 * new threads can enter Wait
989 if (rv
== WAIT_CANCELED
)
990 pthread::static_cancel_self ();
991 else if (rv
== WAIT_TIMEOUT
)
998 pthread_cond::_fixup_after_fork ()
1000 waiting
= pending
= 0;
1003 /* Unlock eventually locked mutexes */
1007 sem_wait
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1009 api_fatal ("pthread_cond::_fixup_after_fork () failed to recreate win32 semaphore");
1013 pthread_rwlockattr::is_good_object (pthread_rwlockattr_t
const *attr
)
1015 if (verifyable_object_isvalid (attr
, PTHREAD_RWLOCKATTR_MAGIC
) != VALID_OBJECT
)
1020 pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
1021 (PTHREAD_RWLOCKATTR_MAGIC
), shared (PTHREAD_PROCESS_PRIVATE
)
1025 pthread_rwlockattr::~pthread_rwlockattr ()
1029 List
<pthread_rwlock
> pthread_rwlock::rwlocks
;
1031 /* This is used for rwlock creation protection within a single process only */
1032 fast_mutex NO_COPY
pthread_rwlock::rwlock_initialization_lock
;
1034 /* We can only be called once.
1035 TODO: (no rush) use a non copied memory section to
1036 hold an initialization flag. */
1038 pthread_rwlock::init_mutex ()
1040 if (!rwlock_initialization_lock
.init ())
1041 api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
1044 pthread_rwlock::pthread_rwlock (pthread_rwlockattr
*attr
) :
1045 verifyable_object (PTHREAD_RWLOCK_MAGIC
),
1046 shared (0), waiting_readers (0), waiting_writers (0), writer (NULL
),
1047 readers (NULL
), readers_mx (), mtx (NULL
), cond_readers (NULL
), cond_writers (NULL
),
1050 pthread_mutex
*verifyable_mutex_obj
= &mtx
;
1051 pthread_cond
*verifyable_cond_obj
;
1053 if (!readers_mx
.init ())
1055 thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
1061 if (attr
->shared
!= PTHREAD_PROCESS_PRIVATE
)
1067 if (!pthread_mutex::is_good_object (&verifyable_mutex_obj
))
1069 thread_printf ("Internal rwlock mutex is not valid. this %p", this);
1073 /* Change the mutex type to NORMAL to speed up mutex operations */
1074 mtx
.type
= PTHREAD_MUTEX_NORMAL
;
1076 verifyable_cond_obj
= &cond_readers
;
1077 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1079 thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
1084 verifyable_cond_obj
= &cond_writers
;
1085 if (!pthread_cond::is_good_object (&verifyable_cond_obj
))
1087 thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
1093 rwlocks
.insert (this);
1096 pthread_rwlock::~pthread_rwlock ()
1098 rwlocks
.remove (this);
1102 pthread_rwlock::rdlock ()
1105 struct RWLOCK_READER
*reader
;
1106 pthread_t self
= pthread::self ();
1110 if (lookup_reader (self
))
1116 reader
= new struct RWLOCK_READER
;
1123 while (writer
|| waiting_writers
)
1125 pthread_cleanup_push (pthread_rwlock::rdlock_cleanup
, this);
1128 cond_readers
.wait (&mtx
);
1131 pthread_cleanup_pop (0);
1134 reader
->thread
= self
;
1135 add_reader (reader
);
1144 pthread_rwlock::tryrdlock ()
1147 pthread_t self
= pthread::self ();
1151 if (writer
|| waiting_writers
|| lookup_reader (self
))
1155 struct RWLOCK_READER
*reader
= new struct RWLOCK_READER
;
1158 reader
->thread
= self
;
1159 add_reader (reader
);
1171 pthread_rwlock::wrlock ()
1174 pthread_t self
= pthread::self ();
1178 if (writer
== self
|| lookup_reader (self
))
1184 while (writer
|| readers
)
1186 pthread_cleanup_push (pthread_rwlock::wrlock_cleanup
, this);
1189 cond_writers
.wait (&mtx
);
1192 pthread_cleanup_pop (0);
1204 pthread_rwlock::trywrlock ()
1207 pthread_t self
= pthread::self ();
1211 if (writer
|| readers
)
1222 pthread_rwlock::unlock ()
1225 pthread_t self
= pthread::self ();
1241 struct RWLOCK_READER
*reader
= lookup_reader (self
);
1249 remove_reader (reader
);
1262 pthread_rwlock::add_reader (struct RWLOCK_READER
*rd
)
1264 List_insert (readers_mx
, readers
, rd
);
1268 pthread_rwlock::remove_reader (struct RWLOCK_READER
*rd
)
1270 List_remove (readers_mx
, readers
, rd
);
1273 struct pthread_rwlock::RWLOCK_READER
*
1274 pthread_rwlock::lookup_reader (pthread_t thread
)
1278 struct RWLOCK_READER
*cur
= readers
;
1280 while (cur
&& cur
->thread
!= thread
)
1283 readers_mx
.unlock ();
1289 pthread_rwlock::rdlock_cleanup (void *arg
)
1291 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1293 --(rwlock
->waiting_readers
);
1295 rwlock
->mtx
.unlock ();
1299 pthread_rwlock::wrlock_cleanup (void *arg
)
1301 pthread_rwlock
*rwlock
= (pthread_rwlock
*) arg
;
1303 --(rwlock
->waiting_writers
);
1305 rwlock
->mtx
.unlock ();
1309 pthread_rwlock::_fixup_after_fork ()
1311 pthread_t self
= pthread::self ();
1312 struct RWLOCK_READER
**temp
= &readers
;
1314 waiting_readers
= 0;
1315 waiting_writers
= 0;
1317 if (!readers_mx
.init ())
1318 api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
1320 /* Unlock eventually locked mutex */
1323 * Remove all readers except self
1327 if ((*temp
)->thread
== self
)
1328 temp
= &((*temp
)->next
);
1331 struct RWLOCK_READER
*cur
= *temp
;
1332 *temp
= (*temp
)->next
;
1339 /* static members */
1340 /* This stores pthread_key information across fork() boundaries */
1341 List
<pthread_key
> pthread_key::keys
;
1344 pthread_key::is_good_object (pthread_key_t
const *key
)
1346 if (verifyable_object_isvalid (key
, PTHREAD_KEY_MAGIC
) != VALID_OBJECT
)
1351 /* non-static members */
1353 pthread_key::pthread_key (void (*aDestructor
) (void *)):verifyable_object (PTHREAD_KEY_MAGIC
), destructor (aDestructor
)
1355 tls_index
= TlsAlloc ();
1356 if (tls_index
== TLS_OUT_OF_INDEXES
)
1362 pthread_key::~pthread_key ()
1364 /* We may need to make the list code lock the list during operations
1369 TlsFree (tls_index
);
1374 pthread_key::set (const void *value
)
1376 /* the OS function doesn't perform error checking */
1377 TlsSetValue (tls_index
, (void *) value
);
1382 pthread_key::get () const
1384 int saved_error
= ::GetLastError ();
1385 void *result
= TlsGetValue (tls_index
);
1386 ::SetLastError (saved_error
);
1391 pthread_key::_fixup_before_fork ()
1397 pthread_key::_fixup_after_fork ()
1399 tls_index
= TlsAlloc ();
1400 if (tls_index
== TLS_OUT_OF_INDEXES
)
1401 api_fatal ("pthread_key::recreate_key_from_buffer () failed to reallocate Tls storage");
1406 pthread_key::run_destructor ()
1410 void *oldValue
= get ();
1414 destructor (oldValue
);
1421 REMOVED FROM CURRENT. These can be reinstated with the daemon, when all the
1422 gymnastics can be a lot easier.
1424 the mutex_t (size 4) is not used as a verifyable object because we cannot
1425 guarantee the same address space for all processes.
1426 we use the following:
1427 high bit set (never a valid address).
1428 second byte is reserved for the priority.
1429 third byte is reserved
1430 fourth byte is the mutex id. (max 255 cygwin mutexs system wide).
1431 creating mutex's does get slower and slower, but as creation is a one time
1432 job, it should never become an issue
1434 And if you're looking at this and thinking, why not an array in cygwin for all mutexs,
1435 - you incur a penalty on _every_ mutex call and you have toserialise them all.
1438 option 2? put everything in userspace and update the ABI?
1439 - bad karma as well - the HANDLE, while identical across process's,
1440 Isn't duplicated, it's reopened. */
1442 /* static members */
1444 pthread_mutex::is_good_object (pthread_mutex_t
const *mutex
)
1446 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
) != VALID_OBJECT
)
1452 pthread_mutex::is_good_initializer (pthread_mutex_t
const *mutex
)
1454 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
, PTHREAD_MUTEX_INITIALIZER
) != VALID_STATIC_OBJECT
)
1460 pthread_mutex::is_good_initializer_or_object (pthread_mutex_t
const *mutex
)
1462 if (verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
, PTHREAD_MUTEX_INITIALIZER
) == INVALID_OBJECT
)
1468 pthread_mutex::is_good_initializer_or_bad_object (pthread_mutex_t
const *mutex
)
1470 verifyable_object_state objectState
= verifyable_object_isvalid (mutex
, PTHREAD_MUTEX_MAGIC
, PTHREAD_MUTEX_INITIALIZER
);
1471 if (objectState
== VALID_OBJECT
)
1477 pthread_mutex::can_be_unlocked (pthread_mutex_t
const *mutex
)
1479 pthread_t self
= pthread::self ();
1481 if (!is_good_object (mutex
))
1484 * Check if the mutex is owned by the current thread and can be unlocked
1486 return ((*mutex
)->recursion_counter
== 1 && pthread::equal ((*mutex
)->owner
, self
));
1489 List
<pthread_mutex
> pthread_mutex::mutexes
;
1491 /* This is used for mutex creation protection within a single process only */
1492 fast_mutex NO_COPY
pthread_mutex::mutex_initialization_lock
;
1494 /* We can only be called once.
1495 TODO: (no rush) use a non copied memory section to
1496 hold an initialization flag. */
1498 pthread_mutex::init_mutex ()
1500 if (!mutex_initialization_lock
.init ())
1501 api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support.");
1504 pthread_mutex::pthread_mutex (pthread_mutexattr
*attr
) :
1505 verifyable_object (PTHREAD_MUTEX_MAGIC
),
1507 win32_obj_id (NULL
), recursion_counter (0),
1508 condwaits (0), owner (NULL
), type (PTHREAD_MUTEX_DEFAULT
),
1509 pshared (PTHREAD_PROCESS_PRIVATE
)
1511 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1517 /*attr checked in the C call */
1520 if (attr
->pshared
== PTHREAD_PROCESS_SHARED
)
1527 type
= attr
->mutextype
;
1530 mutexes
.insert (this);
1533 pthread_mutex::~pthread_mutex ()
1536 CloseHandle (win32_obj_id
);
1538 mutexes
.remove (this);
1542 pthread_mutex::_lock (pthread_t self
)
1546 if (InterlockedIncrement ((long *)&lock_counter
) == 1)
1548 else if (type
!= PTHREAD_MUTEX_NORMAL
&& pthread::equal (owner
, self
))
1550 InterlockedDecrement ((long *) &lock_counter
);
1551 if (type
== PTHREAD_MUTEX_RECURSIVE
)
1552 result
= lock_recursive ();
1558 WaitForSingleObject (win32_obj_id
, INFINITE
);
1566 pthread_mutex::_trylock (pthread_t self
)
1570 if (InterlockedCompareExchange ((long *) &lock_counter
, 1, 0) == 0)
1572 else if (type
== PTHREAD_MUTEX_RECURSIVE
&& pthread::equal (owner
, self
))
1573 result
= lock_recursive ();
1581 pthread_mutex::_unlock (pthread_t self
)
1583 if (!pthread::equal (owner
, self
))
1586 if (--recursion_counter
== 0)
1589 if (InterlockedDecrement ((long *)&lock_counter
))
1590 // Another thread is waiting
1591 ::ReleaseSemaphore (win32_obj_id
, 1, NULL
);
1598 pthread_mutex::_destroy (pthread_t self
)
1600 if (condwaits
|| _trylock (self
))
1601 // Do not destroy a condwaited or locked mutex
1603 else if (recursion_counter
!= 1)
1605 // Do not destroy a recursive locked mutex
1606 --recursion_counter
;
1615 pthread_mutex::_fixup_after_fork ()
1617 debug_printf ("mutex %x in _fixup_after_fork", this);
1618 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1619 api_fatal ("pthread_mutex::_fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's");
1622 /* mutex has no owner, reset to initial */
1624 else if (lock_counter
!= 0)
1625 /* All waiting threads are gone after a fork */
1628 win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, 0, LONG_MAX
, NULL
);
1630 api_fatal ("pthread_mutex::_fixup_after_fork () failed to recreate win32 semaphore for mutex");
1636 pthread_mutexattr::is_good_object (pthread_mutexattr_t
const * attr
)
1638 if (verifyable_object_isvalid (attr
, PTHREAD_MUTEXATTR_MAGIC
) != VALID_OBJECT
)
1643 pthread_mutexattr::pthread_mutexattr ():verifyable_object (PTHREAD_MUTEXATTR_MAGIC
),
1644 pshared (PTHREAD_PROCESS_PRIVATE
), mutextype (PTHREAD_MUTEX_DEFAULT
)
1648 pthread_mutexattr::~pthread_mutexattr ()
1652 List
<semaphore
> semaphore::semaphores
;
1654 semaphore::semaphore (int pshared
, unsigned int value
)
1655 : verifyable_object (SEM_MAGIC
),
1657 currentvalue (value
),
1660 SECURITY_ATTRIBUTES sa
= (pshared
!= PTHREAD_PROCESS_PRIVATE
)
1661 ? sec_all
: sec_none_nih
;
1662 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, NULL
);
1663 if (!this->win32_obj_id
)
1666 semaphores
.insert (this);
1669 semaphore::semaphore (const char *sem_name
, int oflag
, mode_t mode
,
1671 : verifyable_object (SEM_MAGIC
),
1672 shared (PTHREAD_PROCESS_SHARED
),
1673 currentvalue (value
), /* Unused for named semaphores. */
1676 if (oflag
& O_CREAT
)
1678 SECURITY_ATTRIBUTES sa
= sec_all
;
1680 set_security_attribute (mode
, &sa
, alloca (4096), 4096);
1681 this->win32_obj_id
= ::CreateSemaphore (&sa
, value
, LONG_MAX
, sem_name
);
1682 if (!this->win32_obj_id
)
1684 if (GetLastError () == ERROR_ALREADY_EXISTS
&& (oflag
& O_EXCL
))
1687 CloseHandle (this->win32_obj_id
);
1693 this->win32_obj_id
= ::OpenSemaphore (SEMAPHORE_ALL_ACCESS
, FALSE
,
1695 if (!this->win32_obj_id
)
1703 name
= new char [strlen (sem_name
+ 1)];
1707 CloseHandle (this->win32_obj_id
);
1711 strcpy (name
, sem_name
);
1714 semaphores
.insert (this);
1717 semaphore::~semaphore ()
1720 CloseHandle (win32_obj_id
);
1724 semaphores
.remove (this);
1730 if (ReleaseSemaphore (win32_obj_id
, 1, ¤tvalue
))
1735 semaphore::_getvalue (int *sval
)
1739 switch (WaitForSingleObject (win32_obj_id
, 0))
1742 ReleaseSemaphore (win32_obj_id
, 1, &val
);
1756 semaphore::_trywait ()
1758 /* FIXME: signals should be able to interrupt semaphores...
1759 *We probably need WaitForMultipleObjects here.
1761 if (WaitForSingleObject (win32_obj_id
, 0) == WAIT_TIMEOUT
)
1771 semaphore::_timedwait (const struct timespec
*abstime
)
1776 if (__check_invalid_read_ptr (abstime
, sizeof *abstime
))
1778 /* According to SUSv3, abstime need not be checked for validity,
1779 if the semaphore can be locked immediately. */
1786 gettimeofday (&tv
, NULL
);
1787 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
1788 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
1791 switch (pthread::cancelable_wait (win32_obj_id
, waitlength
))
1797 set_errno (ETIMEDOUT
);
1800 debug_printf ("cancelable_wait failed. %E");
1810 switch (pthread::cancelable_wait (win32_obj_id
, INFINITE
))
1816 debug_printf ("cancelable_wait failed. %E");
1822 semaphore::_fixup_after_fork ()
1824 if (shared
== PTHREAD_PROCESS_PRIVATE
)
1826 debug_printf ("sem %x in _fixup_after_fork", this);
1827 /* FIXME: duplicate code here and in the constructor. */
1828 this->win32_obj_id
= ::CreateSemaphore (&sec_none_nih
, currentvalue
,
1831 api_fatal ("failed to create new win32 semaphore, error %d");
1835 verifyable_object::verifyable_object (long verifyer
):
1840 verifyable_object::~verifyable_object ()
1845 /* Generic memory acccess routine - where should it live ? */
1847 check_valid_pointer (void const *pointer
)
1849 if (!pointer
|| IsBadWritePtr ((void *) pointer
, sizeof (verifyable_object
)))
1854 verifyable_object_state
1855 verifyable_object_isvalid (void const * objectptr
, long magic
, void *static_ptr
)
1857 verifyable_object
**object
= (verifyable_object
**)objectptr
;
1858 if (check_valid_pointer (object
))
1859 return INVALID_OBJECT
;
1860 if (static_ptr
&& *object
== static_ptr
)
1861 return VALID_STATIC_OBJECT
;
1863 return INVALID_OBJECT
;
1864 if (check_valid_pointer (*object
))
1865 return INVALID_OBJECT
;
1866 if ((*object
)->magic
!= magic
)
1867 return INVALID_OBJECT
;
1868 return VALID_OBJECT
;
1871 verifyable_object_state
1872 verifyable_object_isvalid (void const * objectptr
, long magic
)
1874 return verifyable_object_isvalid (objectptr
, magic
, NULL
);
1878 __reent_t::init_clib (struct _reent
& var
)
1880 var
= ((struct _reent
) _REENT_INIT (var
));
1881 var
._stdin
= _GLOBAL_REENT
->_stdin
;
1882 var
._stdout
= _GLOBAL_REENT
->_stdout
;
1883 var
._stderr
= _GLOBAL_REENT
->_stderr
;
1884 var
.__sdidinit
= _GLOBAL_REENT
->__sdidinit
;
1885 var
.__cleanup
= _GLOBAL_REENT
->__cleanup
;
1891 pthread::thread_init_wrapper (void *_arg
)
1893 // Setup the local/global storage of this thread
1895 pthread
*thread
= (pthread
*) _arg
;
1896 struct __reent_t local_reent
;
1897 struct _winsup_t local_winsup
;
1898 struct _reent local_clib
;
1900 struct sigaction _sigs
[NSIG
];
1901 sigset_t _sig_mask
; /* one set for everything to ignore. */
1903 /* According to onno@stack.urc.tue.nl, the exception handler record must
1905 exception_list cygwin_except_entry
;
1907 /* Initialize SIGSEGV handling, etc. */
1908 init_exceptions (&cygwin_except_entry
);
1910 // setup signal structures
1911 thread
->sigs
= _sigs
;
1912 thread
->sigmask
= &_sig_mask
;
1913 thread
->sigtodo
= NULL
;
1915 memset (&local_winsup
, 0, sizeof (struct _winsup_t
));
1917 local_reent
.init_clib (local_clib
);
1918 local_reent
._winsup
= &local_winsup
;
1920 local_winsup
._process_logmask
= LOG_UPTO (LOG_DEBUG
);
1922 MT_INTERFACE
->reent_key
.set (&local_reent
);
1924 thread
->set_thread_id_to_current ();
1925 set_tls_self_pointer (thread
);
1927 thread
->mutex
.lock ();
1928 // if thread is detached force cleanup on exit
1929 if (thread
->attr
.joinable
== PTHREAD_CREATE_DETACHED
&& thread
->joiner
== NULL
)
1930 thread
->joiner
= thread
;
1931 thread
->mutex
.unlock ();
1933 #ifdef _CYG_THREAD_FAILSAFE
1934 if (_REENT
== _impure_ptr
)
1935 system_printf ("local storage for thread isn't setup correctly");
1938 thread_printf ("started thread %p %p %p %p %p %p", _arg
, &local_clib
,
1939 _impure_ptr
, thread
, thread
->function
, thread
->arg
);
1941 // call the user's thread
1942 void *ret
= thread
->function (thread
->arg
);
1947 // ??? This code only runs if the thread exits by returning.
1948 // it's all now in __pthread_exit ();
1955 pthread::is_good_object (pthread_t
const *thread
)
1957 if (verifyable_object_isvalid (thread
, PTHREAD_MAGIC
) != VALID_OBJECT
)
1963 pthread::getsequence_np ()
1965 return get_thread_id ();
1969 pthread::create (pthread_t
*thread
, const pthread_attr_t
*attr
,
1970 void *(*start_routine
) (void *), void *arg
)
1972 DECLARE_TLS_STORAGE
;
1973 if (attr
&& !pthread_attr::is_good_object (attr
))
1976 *thread
= new pthread ();
1977 (*thread
)->create (start_routine
, attr
? *attr
: NULL
, arg
);
1978 if (!is_good_object (thread
))
1989 pthread::once (pthread_once_t
*once_control
, void (*init_routine
) (void))
1992 if (once_control
->state
)
1995 pthread_mutex_lock (&once_control
->mutex
);
1996 /* Here we must set a cancellation handler to unlock the mutex if needed */
1997 /* but a cancellation handler is not the right thing. We need this in the thread
1998 *cleanup routine. Assumption: a thread can only be in one pthread_once routine
1999 *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
2000 *on pthread_exit ();
2002 if (!once_control
->state
)
2005 once_control
->state
= 1;
2007 /* Here we must remove our cancellation handler */
2008 pthread_mutex_unlock (&once_control
->mutex
);
2013 pthread::cancel (pthread_t thread
)
2015 if (!is_good_object (&thread
))
2018 return thread
->cancel ();
2021 /* Races in pthread_atfork:
2022 We are race safe in that any additions to the lists are made via
2023 InterlockedExchangePointer.
2024 However, if the user application doesn't perform syncronisation of some sort
2025 It's not guaranteed that a near simultaneous call to pthread_atfork and fork
2026 will result in the new atfork handlers being calls.
2027 More rigorous internal syncronisation isn't needed as the user program isn't
2028 guaranteeing their own state.
2030 as far as multiple calls to pthread_atfork, the worst case is simultaneous calls
2031 will result in an indeterminate order for parent and child calls (what gets inserted
2032 first isn't guaranteed.)
2034 There is one potential race... Does the result of InterlockedExchangePointer
2035 get committed to the return location _before_ any context switches can occur?
2036 If yes, we're safe, if no, we're not. */
2038 pthread::atforkprepare (void)
2040 MT_INTERFACE
->fixup_before_fork ();
2042 callback
*cb
= MT_INTERFACE
->pthread_prepare
;
2051 pthread::atforkparent (void)
2053 callback
*cb
= MT_INTERFACE
->pthread_parent
;
2062 pthread::atforkchild (void)
2064 MT_INTERFACE
->fixup_after_fork ();
2066 callback
*cb
= MT_INTERFACE
->pthread_child
;
2074 /* Register a set of functions to run before and after fork.
2075 prepare calls are called in LI-FC order.
2076 parent and child calls are called in FI-FC order. */
2078 pthread::atfork (void (*prepare
)(void), void (*parent
)(void), void (*child
)(void))
2080 callback
*prepcb
= NULL
, *parentcb
= NULL
, *childcb
= NULL
;
2083 prepcb
= new callback
;
2089 parentcb
= new callback
;
2099 childcb
= new callback
;
2112 prepcb
->cb
= prepare
;
2113 prepcb
->next
= (callback
*) InterlockedExchangePointer ((LONG
*) &MT_INTERFACE
->pthread_prepare
, (long int) prepcb
);
2117 parentcb
->cb
= parent
;
2118 callback
**t
= &MT_INTERFACE
->pthread_parent
;
2121 /* t = pointer to last next in the list */
2122 parentcb
->next
= (callback
*) InterlockedExchangePointer ((LONG
*) t
, (long int) parentcb
);
2126 childcb
->cb
= child
;
2127 callback
**t
= &MT_INTERFACE
->pthread_child
;
2130 /* t = pointer to last next in the list */
2131 childcb
->next
= (callback
*) InterlockedExchangePointer ((LONG
*) t
, (long int) childcb
);
2137 pthread_attr_init (pthread_attr_t
*attr
)
2139 if (pthread_attr::is_good_object (attr
))
2142 *attr
= new pthread_attr
;
2143 if (!pthread_attr::is_good_object (attr
))
2153 pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
2156 if (!pthread_attr::is_good_object (attr
))
2158 *inheritsched
= (*attr
)->inheritsched
;
2163 pthread_attr_getschedparam (const pthread_attr_t
*attr
,
2164 struct sched_param
*param
)
2166 if (!pthread_attr::is_good_object (attr
))
2168 *param
= (*attr
)->schedparam
;
2172 /* From a pure code point of view, this should call a helper in sched.cc,
2173 to allow for someone adding scheduler policy changes to win32 in the future.
2174 However that's extremely unlikely, so short and sweet will do us */
2176 pthread_attr_getschedpolicy (const pthread_attr_t
*attr
, int *policy
)
2178 if (!pthread_attr::is_good_object (attr
))
2180 *policy
= SCHED_FIFO
;
2186 pthread_attr_getscope (const pthread_attr_t
*attr
, int *contentionscope
)
2188 if (!pthread_attr::is_good_object (attr
))
2190 *contentionscope
= (*attr
)->contentionscope
;
2195 pthread_attr_setdetachstate (pthread_attr_t
*attr
, int detachstate
)
2197 if (!pthread_attr::is_good_object (attr
))
2199 if (detachstate
< 0 || detachstate
> 1)
2201 (*attr
)->joinable
= detachstate
;
2206 pthread_attr_getdetachstate (const pthread_attr_t
*attr
, int *detachstate
)
2208 if (!pthread_attr::is_good_object (attr
))
2210 *detachstate
= (*attr
)->joinable
;
2215 pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inheritsched
)
2217 if (!pthread_attr::is_good_object (attr
))
2219 if (inheritsched
!= PTHREAD_INHERIT_SCHED
2220 && inheritsched
!= PTHREAD_EXPLICIT_SCHED
)
2222 (*attr
)->inheritsched
= inheritsched
;
2227 pthread_attr_setschedparam (pthread_attr_t
*attr
,
2228 const struct sched_param
*param
)
2230 if (!pthread_attr::is_good_object (attr
))
2232 if (!valid_sched_parameters (param
))
2234 (*attr
)->schedparam
= *param
;
2238 /* See __pthread_attr_getschedpolicy for some notes */
2240 pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
)
2242 if (!pthread_attr::is_good_object (attr
))
2244 if (policy
!= SCHED_FIFO
)
2250 pthread_attr_setscope (pthread_attr_t
*attr
, int contentionscope
)
2252 if (!pthread_attr::is_good_object (attr
))
2254 if (contentionscope
!= PTHREAD_SCOPE_SYSTEM
2255 && contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2257 /* In future, we may be able to support system scope by escalating the thread
2258 priority to exceed the priority class. For now we only support PROCESS scope. */
2259 if (contentionscope
!= PTHREAD_SCOPE_PROCESS
)
2261 (*attr
)->contentionscope
= contentionscope
;
2266 pthread_attr_setstacksize (pthread_attr_t
*attr
, size_t size
)
2268 if (!pthread_attr::is_good_object (attr
))
2270 (*attr
)->stacksize
= size
;
2275 pthread_attr_getstacksize (const pthread_attr_t
*attr
, size_t *size
)
2277 if (!pthread_attr::is_good_object (attr
))
2279 *size
= (*attr
)->stacksize
;
2284 pthread_attr_destroy (pthread_attr_t
*attr
)
2286 if (!pthread_attr::is_good_object (attr
))
2294 pthread::join (pthread_t
*thread
, void **return_val
)
2296 pthread_t joiner
= self ();
2298 joiner
->testcancel ();
2300 // Initialize return val with NULL
2304 if (!is_good_object (&joiner
))
2307 if (!is_good_object (thread
))
2310 if (equal (*thread
,joiner
))
2313 (*thread
)->mutex
.lock ();
2315 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2317 (*thread
)->mutex
.unlock ();
2322 (*thread
)->joiner
= joiner
;
2323 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2324 (*thread
)->mutex
.unlock ();
2326 switch (cancelable_wait ((*thread
)->win32_obj_id
, INFINITE
, false))
2330 *return_val
= (*thread
)->return_ptr
;
2334 // set joined thread back to joinable since we got canceled
2335 (*thread
)->joiner
= NULL
;
2336 (*thread
)->attr
.joinable
= PTHREAD_CREATE_JOINABLE
;
2337 joiner
->cancel_self ();
2341 // should never happen
2350 pthread::detach (pthread_t
*thread
)
2352 if (!is_good_object (thread
))
2355 (*thread
)->mutex
.lock ();
2356 if ((*thread
)->attr
.joinable
== PTHREAD_CREATE_DETACHED
)
2358 (*thread
)->mutex
.unlock ();
2362 // check if thread is still alive
2363 if ((*thread
)->valid
&& WaitForSingleObject ((*thread
)->win32_obj_id
, 0) == WAIT_TIMEOUT
)
2365 // force cleanup on exit
2366 (*thread
)->joiner
= *thread
;
2367 (*thread
)->attr
.joinable
= PTHREAD_CREATE_DETACHED
;
2368 (*thread
)->mutex
.unlock ();
2372 // thread has already terminated.
2373 (*thread
)->mutex
.unlock ();
2381 pthread::suspend (pthread_t
*thread
)
2383 if (!is_good_object (thread
))
2386 if ((*thread
)->suspended
== false)
2388 (*thread
)->suspended
= true;
2389 SuspendThread ((*thread
)->win32_obj_id
);
2397 pthread::resume (pthread_t
*thread
)
2399 if (!is_good_object (thread
))
2402 if ((*thread
)->suspended
== true)
2403 ResumeThread ((*thread
)->win32_obj_id
);
2404 (*thread
)->suspended
= false;
2409 /* provided for source level compatability.
2410 See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2413 pthread_getconcurrency (void)
2415 return MT_INTERFACE
->concurrency
;
2418 /* keep this in sync with sched.cc */
2420 pthread_getschedparam (pthread_t thread
, int *policy
,
2421 struct sched_param
*param
)
2423 if (!pthread::is_good_object (&thread
))
2425 *policy
= SCHED_FIFO
;
2426 /* we don't return the current effective priority, we return the current
2427 requested priority */
2428 *param
= thread
->attr
.schedparam
;
2432 /* Thread SpecificData */
2434 pthread_key_create (pthread_key_t
*key
, void (*destructor
) (void *))
2436 /* The opengroup docs don't define if we should check this or not,
2437 but creation is relatively rare. */
2438 if (pthread_key::is_good_object (key
))
2441 *key
= new pthread_key (destructor
);
2443 if (!pthread_key::is_good_object (key
))
2453 pthread_key_delete (pthread_key_t key
)
2455 if (!pthread_key::is_good_object (&key
))
2462 /* provided for source level compatability. See
2463 http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
2466 pthread_setconcurrency (int new_level
)
2470 MT_INTERFACE
->concurrency
= new_level
;
2474 /* keep syncronised with sched.cc */
2476 pthread_setschedparam (pthread_t thread
, int policy
,
2477 const struct sched_param
*param
)
2479 if (!pthread::is_good_object (&thread
))
2481 if (policy
!= SCHED_FIFO
)
2486 sched_set_thread_priority (thread
->win32_obj_id
, param
->sched_priority
);
2488 thread
->attr
.schedparam
.sched_priority
= param
->sched_priority
;
2494 pthread_setspecific (pthread_key_t key
, const void *value
)
2496 if (!pthread_key::is_good_object (&key
))
2503 pthread_getspecific (pthread_key_t key
)
2505 if (!pthread_key::is_good_object (&key
))
2508 return (key
)->get ();
2512 /* Thread synchronisation */
2514 pthread_cond::is_good_object (pthread_cond_t
const *cond
)
2516 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
) != VALID_OBJECT
)
2522 pthread_cond::is_good_initializer (pthread_cond_t
const *cond
)
2524 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) != VALID_STATIC_OBJECT
)
2530 pthread_cond::is_good_initializer_or_object (pthread_cond_t
const *cond
)
2532 if (verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
) == INVALID_OBJECT
)
2538 pthread_cond::is_good_initializer_or_bad_object (pthread_cond_t
const *cond
)
2540 verifyable_object_state objectState
= verifyable_object_isvalid (cond
, PTHREAD_COND_MAGIC
, PTHREAD_COND_INITIALIZER
);
2541 if (objectState
== VALID_OBJECT
)
2547 pthread_cond_destroy (pthread_cond_t
*cond
)
2549 if (pthread_cond::is_good_initializer (cond
))
2551 if (!pthread_cond::is_good_object (cond
))
2554 /* reads are atomic */
2555 if ((*cond
)->waiting
)
2565 pthread_cond::init (pthread_cond_t
*cond
, const pthread_condattr_t
*attr
)
2567 if (attr
&& !pthread_condattr::is_good_object (attr
))
2570 cond_initialization_lock
.lock ();
2572 if (!is_good_initializer_or_bad_object (cond
))
2574 cond_initialization_lock
.unlock ();
2578 *cond
= new pthread_cond (attr
? (*attr
) : NULL
);
2579 if (!is_good_object (cond
))
2583 cond_initialization_lock
.unlock ();
2586 cond_initialization_lock
.unlock ();
2591 pthread_cond_broadcast (pthread_cond_t
*cond
)
2593 if (pthread_cond::is_good_initializer (cond
))
2595 if (!pthread_cond::is_good_object (cond
))
2598 (*cond
)->unblock (true);
2604 pthread_cond_signal (pthread_cond_t
*cond
)
2606 if (pthread_cond::is_good_initializer (cond
))
2608 if (!pthread_cond::is_good_object (cond
))
2611 (*cond
)->unblock (false);
2617 __pthread_cond_dowait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2620 if (!pthread_mutex::is_good_object (mutex
))
2622 if (!pthread_mutex::can_be_unlocked (mutex
))
2625 if (pthread_cond::is_good_initializer (cond
))
2626 pthread_cond::init (cond
, NULL
);
2627 if (!pthread_cond::is_good_object (cond
))
2630 return (*cond
)->wait (*mutex
, waitlength
);
2634 pthread_cond_timedwait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
,
2635 const struct timespec
*abstime
)
2640 pthread_testcancel ();
2642 if (check_valid_pointer (abstime
))
2645 gettimeofday (&tv
, NULL
);
2646 waitlength
= abstime
->tv_sec
* 1000 + abstime
->tv_nsec
/ (1000 * 1000);
2647 waitlength
-= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
2650 return __pthread_cond_dowait (cond
, mutex
, waitlength
);
2654 pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
)
2656 pthread_testcancel ();
2658 return __pthread_cond_dowait (cond
, mutex
, INFINITE
);
2662 pthread_condattr_init (pthread_condattr_t
*condattr
)
2664 if (pthread_condattr::is_good_object (condattr
))
2667 *condattr
= new pthread_condattr
;
2668 if (!pthread_condattr::is_good_object (condattr
))
2678 pthread_condattr_getpshared (const pthread_condattr_t
*attr
, int *pshared
)
2680 if (!pthread_condattr::is_good_object (attr
))
2682 *pshared
= (*attr
)->shared
;
2687 pthread_condattr_setpshared (pthread_condattr_t
*attr
, int pshared
)
2689 if (!pthread_condattr::is_good_object (attr
))
2691 if ((pshared
< 0) || (pshared
> 1))
2693 /* shared cond vars not currently supported */
2694 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2696 (*attr
)->shared
= pshared
;
2701 pthread_condattr_destroy (pthread_condattr_t
*condattr
)
2703 if (!pthread_condattr::is_good_object (condattr
))
2712 pthread_rwlock::is_good_object (pthread_rwlock_t
const *rwlock
)
2714 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
) != VALID_OBJECT
)
2720 pthread_rwlock::is_good_initializer (pthread_rwlock_t
const *rwlock
)
2722 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) != VALID_STATIC_OBJECT
)
2728 pthread_rwlock::is_good_initializer_or_object (pthread_rwlock_t
const *rwlock
)
2730 if (verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
) == INVALID_OBJECT
)
2736 pthread_rwlock::is_good_initializer_or_bad_object (pthread_rwlock_t
const *rwlock
)
2738 verifyable_object_state objectState
= verifyable_object_isvalid (rwlock
, PTHREAD_RWLOCK_MAGIC
, PTHREAD_RWLOCK_INITIALIZER
);
2739 if (objectState
== VALID_OBJECT
)
2745 pthread_rwlock_destroy (pthread_rwlock_t
*rwlock
)
2747 if (pthread_rwlock::is_good_initializer (rwlock
))
2749 if (!pthread_rwlock::is_good_object (rwlock
))
2752 if ((*rwlock
)->writer
|| (*rwlock
)->readers
||
2753 (*rwlock
)->waiting_readers
|| (*rwlock
)->waiting_writers
)
2763 pthread_rwlock::init (pthread_rwlock_t
*rwlock
, const pthread_rwlockattr_t
*attr
)
2765 if (attr
&& !pthread_rwlockattr::is_good_object (attr
))
2768 rwlock_initialization_lock
.lock ();
2770 if (!is_good_initializer_or_bad_object (rwlock
))
2772 rwlock_initialization_lock
.unlock ();
2776 *rwlock
= new pthread_rwlock (attr
? (*attr
) : NULL
);
2777 if (!is_good_object (rwlock
))
2781 rwlock_initialization_lock
.unlock ();
2784 rwlock_initialization_lock
.unlock ();
2789 pthread_rwlock_rdlock (pthread_rwlock_t
*rwlock
)
2791 pthread_testcancel ();
2793 if (pthread_rwlock::is_good_initializer (rwlock
))
2794 pthread_rwlock::init (rwlock
, NULL
);
2795 if (!pthread_rwlock::is_good_object (rwlock
))
2798 return (*rwlock
)->rdlock ();
2802 pthread_rwlock_tryrdlock (pthread_rwlock_t
*rwlock
)
2804 if (pthread_rwlock::is_good_initializer (rwlock
))
2805 pthread_rwlock::init (rwlock
, NULL
);
2806 if (!pthread_rwlock::is_good_object (rwlock
))
2809 return (*rwlock
)->tryrdlock ();
2813 pthread_rwlock_wrlock (pthread_rwlock_t
*rwlock
)
2815 pthread_testcancel ();
2817 if (pthread_rwlock::is_good_initializer (rwlock
))
2818 pthread_rwlock::init (rwlock
, NULL
);
2819 if (!pthread_rwlock::is_good_object (rwlock
))
2822 return (*rwlock
)->wrlock ();
2826 pthread_rwlock_trywrlock (pthread_rwlock_t
*rwlock
)
2828 if (pthread_rwlock::is_good_initializer (rwlock
))
2829 pthread_rwlock::init (rwlock
, NULL
);
2830 if (!pthread_rwlock::is_good_object (rwlock
))
2833 return (*rwlock
)->trywrlock ();
2837 pthread_rwlock_unlock (pthread_rwlock_t
*rwlock
)
2839 if (pthread_rwlock::is_good_initializer (rwlock
))
2841 if (!pthread_rwlock::is_good_object (rwlock
))
2844 return (*rwlock
)->unlock ();
2848 pthread_rwlockattr_init (pthread_rwlockattr_t
*rwlockattr
)
2850 if (pthread_rwlockattr::is_good_object (rwlockattr
))
2853 *rwlockattr
= new pthread_rwlockattr
;
2854 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2856 delete (*rwlockattr
);
2864 pthread_rwlockattr_getpshared (const pthread_rwlockattr_t
*attr
, int *pshared
)
2866 if (!pthread_rwlockattr::is_good_object (attr
))
2868 *pshared
= (*attr
)->shared
;
2873 pthread_rwlockattr_setpshared (pthread_rwlockattr_t
*attr
, int pshared
)
2875 if (!pthread_rwlockattr::is_good_object (attr
))
2877 if ((pshared
< 0) || (pshared
> 1))
2879 /* shared rwlock vars not currently supported */
2880 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
2882 (*attr
)->shared
= pshared
;
2887 pthread_rwlockattr_destroy (pthread_rwlockattr_t
*rwlockattr
)
2889 if (!pthread_rwlockattr::is_good_object (rwlockattr
))
2891 delete (*rwlockattr
);
2898 pthread_kill (pthread_t thread
, int sig
)
2900 // lock myself, for the use of thread2signal
2901 // two different kills might clash: FIXME
2903 if (!pthread::is_good_object (&thread
))
2906 int rval
= raise (sig
);
2913 pthread_sigmask (int operation
, const sigset_t
*set
, sigset_t
*old_set
)
2915 int rval
= sigprocmask (operation
, set
, old_set
);
2917 // unlock this myself
2925 pthread_equal (pthread_t t1
, pthread_t t2
)
2927 return pthread::equal (t1
, t2
);
2932 /* FIXME: there's a potential race with PTHREAD_MUTEX_INITALIZER:
2933 the mutex is not actually inited until the first use.
2934 So two threads trying to lock/trylock may collide.
2935 Solution: we need a global mutex on mutex creation, or possibly simply
2936 on all constructors that allow INITIALIZER macros.
2937 the lock should be very small: only around the init routine, not
2938 every test, or all mutex access will be synchronised. */
2941 pthread_mutex::init (pthread_mutex_t
*mutex
,
2942 const pthread_mutexattr_t
*attr
)
2944 if (attr
&& !pthread_mutexattr::is_good_object (attr
) || check_valid_pointer (mutex
))
2947 mutex_initialization_lock
.lock ();
2949 if (!is_good_initializer_or_bad_object (mutex
))
2951 mutex_initialization_lock
.unlock ();
2955 *mutex
= new pthread_mutex (attr
? (*attr
) : NULL
);
2956 if (!is_good_object (mutex
))
2960 mutex_initialization_lock
.unlock ();
2963 mutex_initialization_lock
.unlock ();
2968 pthread_mutex_getprioceiling (const pthread_mutex_t
*mutex
,
2971 pthread_mutex_t
*themutex
= (pthread_mutex_t
*) mutex
;
2972 if (pthread_mutex::is_good_initializer (mutex
))
2973 pthread_mutex::init ((pthread_mutex_t
*) mutex
, NULL
);
2974 if (!pthread_mutex::is_good_object (themutex
))
2976 /* We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support
2979 We can support mutex priorities in the future though:
2980 Store a priority with each mutex.
2981 When the mutex is optained, set the thread priority as appropriate
2982 When the mutex is released, reset the thread priority. */
2987 pthread_mutex_lock (pthread_mutex_t
*mutex
)
2989 pthread_mutex_t
*themutex
= mutex
;
2990 /* This could be simplified via is_good_initializer_or_object
2991 and is_good_initializer, but in a performance critical call like this....
2993 switch (verifyable_object_isvalid (themutex
, PTHREAD_MUTEX_MAGIC
, PTHREAD_MUTEX_INITIALIZER
))
2995 case INVALID_OBJECT
:
2998 case VALID_STATIC_OBJECT
:
2999 if (pthread_mutex::is_good_initializer (mutex
))
3001 int rv
= pthread_mutex::init (mutex
, NULL
);
3002 if (rv
&& rv
!= EBUSY
)
3005 /* No else needed. If it's been initialized while we waited,
3006 we can just attempt to lock it */
3011 return (*themutex
)->lock ();
3015 pthread_mutex_trylock (pthread_mutex_t
*mutex
)
3017 pthread_mutex_t
*themutex
= mutex
;
3018 if (pthread_mutex::is_good_initializer (mutex
))
3019 pthread_mutex::init (mutex
, NULL
);
3020 if (!pthread_mutex::is_good_object (themutex
))
3022 return (*themutex
)->trylock ();
3026 pthread_mutex_unlock (pthread_mutex_t
*mutex
)
3028 if (pthread_mutex::is_good_initializer (mutex
))
3029 pthread_mutex::init (mutex
, NULL
);
3030 if (!pthread_mutex::is_good_object (mutex
))
3032 return (*mutex
)->unlock ();
3036 pthread_mutex_destroy (pthread_mutex_t
*mutex
)
3040 if (pthread_mutex::is_good_initializer (mutex
))
3042 if (!pthread_mutex::is_good_object (mutex
))
3045 rv
= (*mutex
)->destroy ();
3054 pthread_mutex_setprioceiling (pthread_mutex_t
*mutex
, int prioceiling
,
3057 pthread_mutex_t
*themutex
= mutex
;
3058 if (pthread_mutex::is_good_initializer (mutex
))
3059 pthread_mutex::init (mutex
, NULL
);
3060 if (!pthread_mutex::is_good_object (themutex
))
3065 /* Win32 doesn't support mutex priorities - see __pthread_mutex_getprioceiling
3068 pthread_mutexattr_getprotocol (const pthread_mutexattr_t
*attr
,
3071 if (!pthread_mutexattr::is_good_object (attr
))
3077 pthread_mutexattr_getpshared (const pthread_mutexattr_t
*attr
,
3080 if (!pthread_mutexattr::is_good_object (attr
))
3082 *pshared
= (*attr
)->pshared
;
3087 pthread_mutexattr_gettype (const pthread_mutexattr_t
*attr
, int *type
)
3089 if (!pthread_mutexattr::is_good_object (attr
))
3091 *type
= (*attr
)->mutextype
;
3095 /* FIXME: write and test process shared mutex's. */
3097 pthread_mutexattr_init (pthread_mutexattr_t
*attr
)
3099 if (pthread_mutexattr::is_good_object (attr
))
3102 *attr
= new pthread_mutexattr ();
3103 if (!pthread_mutexattr::is_good_object (attr
))
3113 pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
)
3115 if (!pthread_mutexattr::is_good_object (attr
))
3123 /* Win32 doesn't support mutex priorities */
3125 pthread_mutexattr_setprotocol (pthread_mutexattr_t
*attr
, int protocol
)
3127 if (!pthread_mutexattr::is_good_object (attr
))
3132 /* Win32 doesn't support mutex priorities */
3134 pthread_mutexattr_setprioceiling (pthread_mutexattr_t
*attr
,
3137 if (!pthread_mutexattr::is_good_object (attr
))
3143 pthread_mutexattr_getprioceiling (const pthread_mutexattr_t
*attr
,
3146 if (!pthread_mutexattr::is_good_object (attr
))
3152 pthread_mutexattr_setpshared (pthread_mutexattr_t
*attr
, int pshared
)
3154 if (!pthread_mutexattr::is_good_object (attr
))
3156 /* we don't use pshared for anything as yet. We need to test PROCESS_SHARED
3159 if (pshared
!= PTHREAD_PROCESS_PRIVATE
)
3161 (*attr
)->pshared
= pshared
;
3165 /* see pthread_mutex_gettype */
3167 pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int type
)
3169 if (!pthread_mutexattr::is_good_object (attr
))
3174 case PTHREAD_MUTEX_ERRORCHECK
:
3175 case PTHREAD_MUTEX_RECURSIVE
:
3176 case PTHREAD_MUTEX_NORMAL
:
3177 (*attr
)->mutextype
= type
;
3188 /* static members */
3190 semaphore::is_good_object (sem_t
const * sem
)
3192 if (verifyable_object_isvalid (sem
, SEM_MAGIC
) != VALID_OBJECT
)
3198 semaphore::init (sem_t
*sem
, int pshared
, unsigned int value
)
3200 /* opengroup calls this undefined */
3201 if (is_good_object (sem
))
3204 if (value
> SEM_VALUE_MAX
)
3207 *sem
= new semaphore (pshared
, value
);
3209 if (!is_good_object (sem
))
3219 semaphore::destroy (sem_t
*sem
)
3221 if (!is_good_object (sem
))
3224 /* FIXME - new feature - test for busy against threads... */
3232 semaphore::open (const char *name
, int oflag
, mode_t mode
, unsigned int value
)
3234 if (value
> SEM_VALUE_MAX
)
3240 sem_t
*sem
= new sem_t
;
3247 *sem
= new semaphore (name
, oflag
, mode
, value
);
3249 if (!is_good_object (sem
))
3259 semaphore::wait (sem_t
*sem
)
3261 pthread_testcancel ();
3263 if (!is_good_object (sem
))
3274 semaphore::trywait (sem_t
*sem
)
3276 if (!is_good_object (sem
))
3282 return (*sem
)->_trywait ();
3286 semaphore::timedwait (sem_t
*sem
, const struct timespec
*abstime
)
3288 if (!is_good_object (sem
))
3294 return (*sem
)->_timedwait (abstime
);
3298 semaphore::post (sem_t
*sem
)
3300 if (!is_good_object (sem
))
3311 semaphore::getvalue (sem_t
*sem
, int *sval
)
3314 if (!is_good_object (sem
)
3315 || __check_null_invalid_struct (sval
, sizeof (int)))
3321 return (*sem
)->_getvalue (sval
);
3326 pthread_null::get_null_pthread ()
3328 /* because of weird entry points */
3329 _instance
.magic
= 0;
3333 pthread_null::pthread_null ()
3335 attr
.joinable
= PTHREAD_CREATE_DETACHED
;
3336 /* Mark ourselves as invalid */
3340 pthread_null::~pthread_null ()
3345 pthread_null::create (void *(*)(void *), pthread_attr
*, void *)
3350 pthread_null::exit (void *value_ptr
)
3356 pthread_null::cancel ()
3362 pthread_null::testcancel ()
3367 pthread_null::setcancelstate (int state
, int *oldstate
)
3373 pthread_null::setcanceltype (int type
, int *oldtype
)
3379 pthread_null::push_cleanup_handler (__pthread_cleanup_handler
*handler
)
3384 pthread_null::pop_cleanup_handler (int const execute
)
3389 pthread_null::getsequence_np ()
3394 pthread_null
pthread_null::_instance
;