1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxThread (Posix) Implementation 
   4 // Author:      Original from Wolfram Gloger/Guilhem Lavaux 
   5 // Modified by: K. S. Sreeram (2002): POSIXified wxCondition, added wxSemaphore 
   8 // Copyright:   (c) Wolfram Gloger (1996, 1997) 
   9 //                  Guilhem Lavaux (1998) 
  10 //                  Vadim Zeitlin (1999-2002) 
  11 //                  Robert Roebling (1999) 
  12 //                  K. S. Sreeram (2002) 
  13 // Licence:     wxWindows licence 
  14 ///////////////////////////////////////////////////////////////////////////// 
  16 // ============================================================================ 
  18 // ============================================================================ 
  20 // ---------------------------------------------------------------------------- 
  22 // ---------------------------------------------------------------------------- 
  25     #pragma implementation "thread.h" 
  32 #include "wx/thread.h" 
  33 #include "wx/module.h" 
  37 #include "wx/dynarray.h" 
  49 #ifdef HAVE_THR_SETCONCURRENCY 
  53 // we use wxFFile under Linux in GetCPUCount() 
  58 // ---------------------------------------------------------------------------- 
  60 // ---------------------------------------------------------------------------- 
  62 // the possible states of the thread and transitions from them 
  65     STATE_NEW
,          // didn't start execution yet (=> RUNNING) 
  66     STATE_RUNNING
,      // running (=> PAUSED or EXITED) 
  67     STATE_PAUSED
,       // suspended (=> RUNNING or EXITED) 
  68     STATE_EXITED        
// thread doesn't exist any more 
  71 // the exit value of a thread which has been cancelled 
  72 static const wxThread::ExitCode EXITCODE_CANCELLED 
= (wxThread::ExitCode
)-1; 
  75 #define TRACE_THREADS   _T("thread") 
  77 // ---------------------------------------------------------------------------- 
  79 // ---------------------------------------------------------------------------- 
  81 static void ScheduleThreadForDeletion(); 
  82 static void DeleteThread(wxThread 
*This
); 
  84 // ---------------------------------------------------------------------------- 
  86 // ---------------------------------------------------------------------------- 
  88 WX_DEFINE_ARRAY(wxThread 
*, wxArrayThread
); 
  90 // ----------------------------------------------------------------------------- 
  92 // ----------------------------------------------------------------------------- 
  94 // we keep the list of all threads created by the application to be able to 
  95 // terminate them on exit if there are some left - otherwise the process would 
  97 static wxArrayThread gs_allThreads
; 
  99 // the id of the main thread 
 100 static pthread_t gs_tidMain
; 
 102 // the key for the pointer to the associated wxThread object 
 103 static pthread_key_t gs_keySelf
; 
 105 // the number of threads which are being deleted - the program won't exit 
 106 // until there are any left 
 107 static size_t gs_nThreadsBeingDeleted 
= 0; 
 109 // a mutex to protect gs_nThreadsBeingDeleted 
 110 static wxMutex 
*gs_mutexDeleteThread 
= (wxMutex 
*)NULL
; 
 112 // and a condition variable which will be signaled when all 
 113 // gs_nThreadsBeingDeleted will have been deleted 
 114 static wxCondition 
*gs_condAllDeleted 
= (wxCondition 
*)NULL
; 
 117     // this mutex must be acquired before any call to a GUI function 
 118     static wxMutex 
*gs_mutexGui
; 
 121 // ============================================================================ 
 122 // wxMutex implementation 
 123 // ============================================================================ 
 125 // ---------------------------------------------------------------------------- 
 127 // ---------------------------------------------------------------------------- 
 129 class wxMutexInternal
 
 136     wxMutexError 
TryLock(); 
 137     wxMutexError 
Unlock(); 
 140     pthread_mutex_t m_mutex
; 
 142     friend class wxConditionInternal
; 
 145 wxMutexInternal::wxMutexInternal() 
 147     // support recursive locks like Win32, i.e. a thread can lock a mutex which 
 148     // it had itself already locked 
 150     // but initialization of recursive mutexes is non portable <sigh>, so try 
 152 #ifdef HAVE_PTHREAD_MUTEXATTR_T 
 153     pthread_mutexattr_t attr
; 
 154     pthread_mutexattr_init(&attr
); 
 155     pthread_mutexattr_settype(&attr
, PTHREAD_MUTEX_RECURSIVE
); 
 157     pthread_mutex_init(&m_mutex
, &attr
); 
 158 #elif defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER) 
 159     // we can use this only as initializer so we have to assign it first to a 
 160     // temp var - assigning directly to m_mutex wouldn't even compile 
 161     pthread_mutex_t mutex 
= PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
; 
 163 #else // no recursive mutexes 
 164     pthread_mutex_init(&m_mutex
, NULL
); 
 166     // used by TryLock() below 
 167     #define NO_RECURSIVE_MUTEXES 
 168 #endif // HAVE_PTHREAD_MUTEXATTR_T/... 
 171 wxMutexInternal::~wxMutexInternal() 
 173     pthread_mutex_destroy(&m_mutex
); 
 176 wxMutexError 
wxMutexInternal::Lock() 
 178     int err 
= pthread_mutex_lock(&m_mutex
); 
 182             wxLogDebug(wxT("Locking this mutex would lead to deadlock!")); 
 183             return wxMUTEX_DEAD_LOCK
; 
 186             wxFAIL_MSG( _T("unexpected pthread_mutex_lock() return") ); 
 190             wxLogDebug(_T("Failed to lock the mutex.")); 
 191             return wxMUTEX_MISC_ERROR
; 
 194             return wxMUTEX_NO_ERROR
; 
 198 wxMutexError 
wxMutexInternal::TryLock() 
 200     int err 
= pthread_mutex_trylock(&m_mutex
); 
 207             wxFAIL_MSG( _T("unexpected pthread_mutex_trylock() return") ); 
 211             wxLogDebug(_T("Failed to try to lock the mutex.")); 
 212             return wxMUTEX_MISC_ERROR
; 
 215             return wxMUTEX_NO_ERROR
; 
 219 wxMutexError 
wxMutexInternal::Unlock() 
 221     int err 
= pthread_mutex_unlock(&m_mutex
); 
 225             // we don't own the mutex 
 226             return wxMUTEX_UNLOCKED
; 
 229             wxFAIL_MSG( _T("unexpected pthread_mutex_unlock() return") ); 
 233             wxLogDebug(_T("Failed to unlock the mutex.")); 
 234             return wxMUTEX_MISC_ERROR
; 
 237             return wxMUTEX_NO_ERROR
; 
 241 // ---------------------------------------------------------------------------- 
 243 // ---------------------------------------------------------------------------- 
 245 // TODO: this is completely generic, move it to common code? 
 249     m_internal 
= new wxMutexInternal
; 
 257         wxLogDebug(wxT("Freeing a locked mutex (%d locks)"), m_locked
); 
 262 wxMutexError 
wxMutex::Lock() 
 264     wxMutexError err 
= m_internal
->Lock(); 
 274 wxMutexError 
wxMutex::TryLock() 
 278 #ifdef NO_RECURSIVE_MUTEXES 
 279         return wxMUTEX_DEAD_LOCK
; 
 280 #else // have recursive mutexes on this platform 
 281         // we will succeed in locking it when we have it already locked 
 282         return wxMUTEX_NO_ERROR
; 
 283 #endif // recursive/non-recursive mutexes 
 286     wxMutexError err 
= m_internal
->TryLock(); 
 295 wxMutexError 
wxMutex::Unlock() 
 303         wxLogDebug(wxT("Unlocking not locked mutex.")); 
 305         return wxMUTEX_UNLOCKED
; 
 308     return m_internal
->Unlock(); 
 311 // =========================================================================== 
 312 // wxCondition implementation 
 313 // =========================================================================== 
 315 // --------------------------------------------------------------------------- 
 316 // wxConditionInternal 
 317 // --------------------------------------------------------------------------- 
 319 class wxConditionInternal
 
 322     wxConditionInternal(wxMutex
& mutex
); 
 323     ~wxConditionInternal(); 
 327     bool Wait( const timespec 
*ts 
); 
 334     // get the POSIX mutex associated with us 
 335     pthread_mutex_t 
*GetMutex() const { return &m_mutex
.m_internal
->m_mutex
; } 
 338     pthread_cond_t m_cond
; 
 341 wxConditionInternal::wxConditionInternal(wxMutex
& mutex
) 
 344     if ( pthread_cond_init( &m_cond
, NULL 
) != 0 ) 
 346         wxLogDebug(_T("pthread_cond_init() failed")); 
 350 wxConditionInternal::~wxConditionInternal() 
 352     if ( pthread_cond_destroy( &m_cond 
) != 0 ) 
 354         wxLogDebug(_T("pthread_cond_destroy() failed")); 
 358 void wxConditionInternal::Wait() 
 360     if ( pthread_cond_wait( &m_cond
, GetMutex() ) != 0 ) 
 362         wxLogDebug(_T("pthread_cond_wait() failed")); 
 366 bool wxConditionInternal::Wait( const timespec 
*ts 
) 
 368     int result 
= pthread_cond_timedwait( &m_cond
, GetMutex(), ts 
); 
 369     if ( result 
== ETIMEDOUT 
) 
 374         wxLogDebug(_T("pthread_cond_timedwait() failed")); 
 380 void wxConditionInternal::Signal() 
 382     int result 
= pthread_cond_signal( &m_cond 
); 
 385         wxFAIL_MSG( _T("pthread_cond_signal() failed") ); 
 389 void wxConditionInternal::Broadcast() 
 391     int result 
= pthread_cond_broadcast( &m_cond 
); 
 394         wxFAIL_MSG( _T("pthread_cond_broadcast() failed") ); 
 399 // --------------------------------------------------------------------------- 
 401 // --------------------------------------------------------------------------- 
 403 wxCondition::wxCondition(wxMutex
& mutex
) 
 405     m_internal 
= new wxConditionInternal( mutex 
); 
 408 wxCondition::~wxCondition() 
 413 void wxCondition::Wait() 
 418 bool wxCondition::Wait( unsigned long timeout_millis 
) 
 420     wxLongLong curtime 
= wxGetLocalTimeMillis(); 
 421     curtime 
+= timeout_millis
; 
 422     wxLongLong temp 
= curtime 
/ 1000; 
 423     int sec 
= temp
.GetLo(); 
 425     temp 
= curtime 
- temp
; 
 426     int millis 
= temp
.GetLo(); 
 431     tspec
.tv_nsec 
= millis 
* 1000L * 1000L; 
 433     return m_internal
->Wait(&tspec
); 
 436 void wxCondition::Signal() 
 438     m_internal
->Signal(); 
 441 void wxCondition::Broadcast() 
 443     m_internal
->Broadcast(); 
 446 // =========================================================================== 
 447 // wxSemaphore implementation 
 448 // =========================================================================== 
 450 // --------------------------------------------------------------------------- 
 451 // wxSemaphoreInternal 
 452 // --------------------------------------------------------------------------- 
 454 class wxSemaphoreInternal
 
 457     wxSemaphoreInternal( int initialcount
, int maxcount 
); 
 462     bool Wait( unsigned long timeout_millis 
); 
 474 wxSemaphoreInternal::wxSemaphoreInternal( int initialcount
, int maxcount 
) 
 478     if ( (initialcount 
< 0) || ((maxcount 
> 0) && (initialcount 
> maxcount
)) ) 
 480         wxFAIL_MSG( _T("wxSemaphore: invalid initial count") ); 
 484     count 
= initialcount
; 
 487 void wxSemaphoreInternal::Wait() 
 489     wxMutexLocker 
locker(m_mutex
); 
 499 bool wxSemaphoreInternal::TryWait() 
 501     wxMutexLocker 
locker(m_mutex
); 
 511 bool wxSemaphoreInternal::Wait( unsigned long timeout_millis 
) 
 513     wxMutexLocker 
locker(m_mutex
); 
 515     wxLongLong startTime 
= wxGetLocalTimeMillis(); 
 519         wxLongLong elapsed 
= wxGetLocalTimeMillis() - startTime
; 
 520         long remainingTime 
= (long)timeout_millis 
- (long)elapsed
.GetLo(); 
 521         if ( remainingTime 
<= 0 ) 
 524         bool result 
= m_cond
.Wait( remainingTime 
); 
 534 void wxSemaphoreInternal::Post() 
 536     wxMutexLocker 
locker(m_mutex
); 
 538     if ( maxcount 
> 0 && count 
== maxcount 
) 
 540         wxFAIL_MSG( _T("wxSemaphore::Post() overflow") ); 
 548 // -------------------------------------------------------------------------- 
 550 // -------------------------------------------------------------------------- 
 552 wxSemaphore::wxSemaphore( int initialcount
, int maxcount 
) 
 554     m_internal 
= new wxSemaphoreInternal( initialcount
, maxcount 
); 
 557 wxSemaphore::~wxSemaphore() 
 562 void wxSemaphore::Wait() 
 567 bool wxSemaphore::TryWait() 
 569     return m_internal
->TryWait(); 
 572 bool wxSemaphore::Wait( unsigned long timeout_millis 
) 
 574     return m_internal
->Wait( timeout_millis 
); 
 577 void wxSemaphore::Post() 
 582 // This class is used by wxThreadInternal to support Delete() on 
 584 class wxRefCountedCondition
 
 587     // start with a initial reference count of 1 
 588     wxRefCountedCondition() 
 593         m_mutex 
= new wxMutex(); 
 594         m_cond 
= new wxCondition( *m_mutex 
); 
 597     // increment the reference count 
 600         wxMutexLocker 
locker( *m_mutex 
); 
 605     // decrement the reference count if reference count is zero then delete the 
 609         bool shouldDelete 
= FALSE
; 
 613         if ( --m_refCount 
== 0 ) 
 627     // sets the object to signaled this signal will be a persistent signal all 
 628     // further Wait()s on the object will return without blocking 
 631         wxMutexLocker 
locker( *m_mutex 
); 
 638     // wait till the object is signaled if the object was already signaled then 
 639     // return immediately 
 642         wxMutexLocker 
locker( *m_mutex 
); 
 658     // Cannot delete this object directly, call DeleteRef() instead 
 659     ~wxRefCountedCondition() 
 665     // suppress gcc warning about the class having private dtor and not having 
 666     // friend (so what??) 
 667     friend class wxDummyFriend
; 
 670 // =========================================================================== 
 671 // wxThread implementation 
 672 // =========================================================================== 
 674 // the thread callback functions must have the C linkage 
 678 #if HAVE_THREAD_CLEANUP_FUNCTIONS 
 679     // thread exit function 
 680     void wxPthreadCleanup(void *ptr
); 
 681 #endif // HAVE_THREAD_CLEANUP_FUNCTIONS 
 683 void *wxPthreadStart(void *ptr
); 
 687 // ---------------------------------------------------------------------------- 
 689 // ---------------------------------------------------------------------------- 
 691 class wxThreadInternal
 
 697     // thread entry function 
 698     static void *PthreadStart(wxThread 
*thread
); 
 703         // ask the thread to terminate 
 705         // wake up threads waiting for our termination 
 707         // wake up threads waiting for our start 
 708     void SignalRun() { m_semRun
.Post(); } 
 709         // go to sleep until Resume() is called 
 716     int GetPriority() const { return m_prio
; } 
 717     void SetPriority(int prio
) { m_prio 
= prio
; } 
 719     wxThreadState 
GetState() const { return m_state
; } 
 720     void SetState(wxThreadState state
) { m_state 
= state
; } 
 722     pthread_t 
GetId() const { return m_threadId
; } 
 723     pthread_t 
*GetIdPtr() { return &m_threadId
; } 
 725     void SetCancelFlag() { m_cancelled 
= TRUE
; } 
 726     bool WasCancelled() const { return m_cancelled
; } 
 728     void SetExitCode(wxThread::ExitCode exitcode
) { m_exitcode 
= exitcode
; } 
 729     wxThread::ExitCode 
GetExitCode() const { return m_exitcode
; } 
 732     void SetReallyPaused(bool paused
) { m_isPaused 
= paused
; } 
 733     bool IsReallyPaused() const { return m_isPaused
; } 
 735         // tell the thread that it is a detached one 
 738         m_shouldBeJoined 
= m_shouldBroadcast 
= FALSE
; 
 741         // but even detached threads need to notifyus about their termination 
 742         // sometimes - tell the thread that it should do it 
 743     void Notify() { m_shouldBroadcast 
= TRUE
; } 
 745 #if HAVE_THREAD_CLEANUP_FUNCTIONS 
 746     // this is used by wxPthreadCleanup() only 
 747     static void Cleanup(wxThread 
*thread
); 
 748 #endif // HAVE_THREAD_CLEANUP_FUNCTIONS 
 751     pthread_t     m_threadId
;   // id of the thread 
 752     wxThreadState m_state
;      // see wxThreadState enum 
 753     int           m_prio
;       // in wxWindows units: from 0 to 100 
 755     // this flag is set when the thread should terminate 
 758     // this flag is set when the thread is blocking on m_semSuspend 
 761     // the thread exit code - only used for joinable (!detached) threads and 
 762     // is only valid after the thread termination 
 763     wxThread::ExitCode m_exitcode
; 
 765     // many threads may call Wait(), but only one of them should call 
 766     // pthread_join(), so we have to keep track of this 
 767     wxCriticalSection m_csJoinFlag
; 
 768     bool m_shouldBeJoined
; 
 769     bool m_shouldBroadcast
; 
 772     // this semaphore is posted by Run() and the threads Entry() is not 
 773     // called before it is done 
 774     wxSemaphore m_semRun
; 
 776     // this one is signaled when the thread should resume after having been 
 778     wxSemaphore m_semSuspend
; 
 780     // finally this one is signalled when the thread exits 
 781     // we are using a reference counted condition to support 
 782     // Delete() for a detached thread 
 783     wxRefCountedCondition 
*m_condEnd
; 
 786 // ---------------------------------------------------------------------------- 
 787 // thread startup and exit functions 
 788 // ---------------------------------------------------------------------------- 
 790 void *wxPthreadStart(void *ptr
) 
 792     return wxThreadInternal::PthreadStart((wxThread 
*)ptr
); 
 795 void *wxThreadInternal::PthreadStart(wxThread 
*thread
) 
 797     wxThreadInternal 
*pthread 
= thread
->m_internal
; 
 799     wxLogTrace(TRACE_THREADS
, _T("Thread %ld started."), pthread
->GetId()); 
 801     // associate the thread pointer with the newly created thread so that 
 802     // wxThread::This() will work 
 803     int rc 
= pthread_setspecific(gs_keySelf
, thread
); 
 806         wxLogSysError(rc
, _("Cannot start thread: error writing TLS")); 
 811     // have to declare this before pthread_cleanup_push() which defines a 
 815 #if HAVE_THREAD_CLEANUP_FUNCTIONS 
 816     // install the cleanup handler which will be called if the thread is 
 818     pthread_cleanup_push(wxPthreadCleanup
, thread
); 
 819 #endif // HAVE_THREAD_CLEANUP_FUNCTIONS 
 821     // wait for the semaphore to be posted from Run() 
 822     pthread
->m_semRun
.Wait(); 
 824     // test whether we should run the run at all - may be it was deleted 
 825     // before it started to Run()? 
 827         wxCriticalSectionLocker 
lock(thread
->m_critsect
); 
 829         dontRunAtAll 
= pthread
->GetState() == STATE_NEW 
&& 
 830                        pthread
->WasCancelled(); 
 835         // call the main entry 
 836         pthread
->m_exitcode 
= thread
->Entry(); 
 838         wxLogTrace(TRACE_THREADS
, _T("Thread %ld left its Entry()."), 
 842             wxCriticalSectionLocker 
lock(thread
->m_critsect
); 
 844             wxLogTrace(TRACE_THREADS
, _T("Thread %ld changes state to EXITED."), 
 847             // change the state of the thread to "exited" so that 
 848             // wxPthreadCleanup handler won't do anything from now (if it's 
 849             // called before we do pthread_cleanup_pop below) 
 850             pthread
->SetState(STATE_EXITED
); 
 854     // NB: at least under Linux, pthread_cleanup_push/pop are macros and pop 
 855     //     contains the matching '}' for the '{' in push, so they must be used 
 856     //     in the same block! 
 857 #if HAVE_THREAD_CLEANUP_FUNCTIONS 
 858     // remove the cleanup handler without executing it 
 859     pthread_cleanup_pop(FALSE
); 
 860 #endif // HAVE_THREAD_CLEANUP_FUNCTIONS 
 866         return EXITCODE_CANCELLED
; 
 870         // terminate the thread 
 871         thread
->Exit(pthread
->m_exitcode
); 
 873         wxFAIL_MSG(wxT("wxThread::Exit() can't return.")); 
 879 #if HAVE_THREAD_CLEANUP_FUNCTIONS 
 881 // this handler is called when the thread is cancelled 
 882 extern "C" void wxPthreadCleanup(void *ptr
) 
 884     wxThreadInternal::Cleanup((wxThread 
*)ptr
); 
 887 void wxThreadInternal::Cleanup(wxThread 
*thread
) 
 890         wxCriticalSectionLocker 
lock(thread
->m_critsect
); 
 891         if ( thread
->m_internal
->GetState() == STATE_EXITED 
) 
 893             // thread is already considered as finished. 
 898     // exit the thread gracefully 
 899     thread
->Exit(EXITCODE_CANCELLED
); 
 902 #endif // HAVE_THREAD_CLEANUP_FUNCTIONS 
 904 // ---------------------------------------------------------------------------- 
 906 // ---------------------------------------------------------------------------- 
 908 wxThreadInternal::wxThreadInternal() 
 912     m_prio 
= WXTHREAD_DEFAULT_PRIORITY
; 
 916     // set to TRUE only when the thread starts waiting on m_semSuspend 
 919     // defaults for joinable threads 
 920     m_shouldBeJoined 
= TRUE
; 
 921     m_shouldBroadcast 
= TRUE
; 
 922     m_isDetached 
= FALSE
; 
 924     m_condEnd 
= new wxRefCountedCondition(); 
 927 wxThreadInternal::~wxThreadInternal() 
 929     m_condEnd
->DeleteRef(); 
 932 wxThreadError 
wxThreadInternal::Run() 
 934     wxCHECK_MSG( GetState() == STATE_NEW
, wxTHREAD_RUNNING
, 
 935                  wxT("thread may only be started once after Create()") ); 
 939     SetState(STATE_RUNNING
); 
 941     return wxTHREAD_NO_ERROR
; 
 944 void wxThreadInternal::Wait() 
 946     // if the thread we're waiting for is waiting for the GUI mutex, we will 
 947     // deadlock so make sure we release it temporarily 
 948     if ( wxThread::IsMain() ) 
 951     bool isDetached 
= m_isDetached
; 
 952     wxThreadIdType id 
= (wxThreadIdType
) GetId(); 
 954     wxLogTrace(TRACE_THREADS
, 
 955                _T("Starting to wait for thread %ld to exit."), id
); 
 957     // wait until the thread terminates (we're blocking in _another_ thread, 
 960     // a reference counting condition is used to handle the 
 961     // case where a detached thread deletes itself 
 962     // before m_condEnd->Wait() returns 
 963     // in this case the deletion of the condition object is deferred until 
 964     // all Wait()ing threads have finished calling DeleteRef() 
 967     m_condEnd
->DeleteRef(); 
 969     wxLogTrace(TRACE_THREADS
, _T("Finished waiting for thread %ld."), id
); 
 971     // we can't use any member variables any more if the thread is detached 
 972     // because it could be already deleted 
 975         // to avoid memory leaks we should call pthread_join(), but it must 
 977         wxCriticalSectionLocker 
lock(m_csJoinFlag
); 
 979         if ( m_shouldBeJoined 
) 
 981             // FIXME shouldn't we set cancellation type to DISABLED here? If 
 982             //       we're cancelled inside pthread_join(), things will almost 
 983             //       certainly break - but if we disable the cancellation, we 
 985             if ( pthread_join((pthread_t
)id
, &m_exitcode
) != 0 ) 
 987                 wxLogError(_("Failed to join a thread, potential memory leak " 
 988                              "detected - please restart the program")); 
 991             m_shouldBeJoined 
= FALSE
; 
 995     // reacquire GUI mutex 
 996     if ( wxThread::IsMain() ) 
1000 void wxThreadInternal::SignalExit() 
1002     wxLogTrace(TRACE_THREADS
, _T("Thread %ld about to exit."), GetId()); 
1004     SetState(STATE_EXITED
); 
1006     // wake up all the threads waiting for our termination - if there are any 
1007     if ( m_shouldBroadcast 
) 
1009         wxLogTrace(TRACE_THREADS
, _T("Thread %ld signals end condition."), 
1012         m_condEnd
->SetSignaled(); 
1016 void wxThreadInternal::Pause() 
1018     // the state is set from the thread which pauses us first, this function 
1019     // is called later so the state should have been already set 
1020     wxCHECK_RET( m_state 
== STATE_PAUSED
, 
1021                  wxT("thread must first be paused with wxThread::Pause().") ); 
1023     wxLogTrace(TRACE_THREADS
, _T("Thread %ld goes to sleep."), GetId()); 
1025     // wait until the semaphore is Post()ed from Resume() 
1026     m_semSuspend
.Wait(); 
1029 void wxThreadInternal::Resume() 
1031     wxCHECK_RET( m_state 
== STATE_PAUSED
, 
1032                  wxT("can't resume thread which is not suspended.") ); 
1034     // the thread might be not actually paused yet - if there were no call to 
1035     // TestDestroy() since the last call to Pause() for example 
1036     if ( IsReallyPaused() ) 
1038         wxLogTrace(TRACE_THREADS
, _T("Waking up thread %ld"), GetId()); 
1041         m_semSuspend
.Post(); 
1044         SetReallyPaused(FALSE
); 
1048         wxLogTrace(TRACE_THREADS
, _T("Thread %ld is not yet really paused"), 
1052     SetState(STATE_RUNNING
); 
1055 // ----------------------------------------------------------------------------- 
1056 // wxThread static functions 
1057 // ----------------------------------------------------------------------------- 
1059 wxThread 
*wxThread::This() 
1061     return (wxThread 
*)pthread_getspecific(gs_keySelf
); 
1064 bool wxThread::IsMain() 
1066     return (bool)pthread_equal(pthread_self(), gs_tidMain
); 
1069 void wxThread::Yield() 
1071 #ifdef HAVE_SCHED_YIELD 
1076 void wxThread::Sleep(unsigned long milliseconds
) 
1078     wxUsleep(milliseconds
); 
1081 int wxThread::GetCPUCount() 
1083 #if defined(__LINUX__) && wxUSE_FFILE 
1084     // read from proc (can't use wxTextFile here because it's a special file: 
1085     // it has 0 size but still can be read from) 
1088     wxFFile 
file(_T("/proc/cpuinfo")); 
1089     if ( file
.IsOpened() ) 
1091         // slurp the whole file 
1093         if ( file
.ReadAll(&s
) ) 
1095             // (ab)use Replace() to find the number of "processor" strings 
1096             size_t count 
= s
.Replace(_T("processor"), _T("")); 
1102             wxLogDebug(_T("failed to parse /proc/cpuinfo")); 
1106             wxLogDebug(_T("failed to read /proc/cpuinfo")); 
1109 #elif defined(_SC_NPROCESSORS_ONLN) 
1110     // this works for Solaris 
1111     int rc 
= sysconf(_SC_NPROCESSORS_ONLN
); 
1116 #endif // different ways to get number of CPUs 
1123   // VMS is a 64 bit system and threads have 64 bit pointers. 
1124   // ??? also needed for other systems???? 
1125 unsigned long long wxThread::GetCurrentId() 
1127     return (unsigned long long)pthread_self(); 
1129 unsigned long wxThread::GetCurrentId() 
1131     return (unsigned long)pthread_self(); 
1135 bool wxThread::SetConcurrency(size_t level
) 
1137 #ifdef HAVE_THR_SETCONCURRENCY 
1138     int rc 
= thr_setconcurrency(level
); 
1141         wxLogSysError(rc
, _T("thr_setconcurrency() failed")); 
1145 #else // !HAVE_THR_SETCONCURRENCY 
1146     // ok only for the default value 
1148 #endif // HAVE_THR_SETCONCURRENCY/!HAVE_THR_SETCONCURRENCY 
1151 // ----------------------------------------------------------------------------- 
1153 // ----------------------------------------------------------------------------- 
1155 wxThread::wxThread(wxThreadKind kind
) 
1157     // add this thread to the global list of all threads 
1158     gs_allThreads
.Add(this); 
1160     m_internal 
= new wxThreadInternal(); 
1162     m_isDetached 
= kind 
== wxTHREAD_DETACHED
; 
1165 wxThreadError 
wxThread::Create(unsigned int WXUNUSED(stackSize
)) 
1167     if ( m_internal
->GetState() != STATE_NEW 
) 
1169         // don't recreate thread 
1170         return wxTHREAD_RUNNING
; 
1173     // set up the thread attribute: right now, we only set thread priority 
1174     pthread_attr_t attr
; 
1175     pthread_attr_init(&attr
); 
1177 #ifdef HAVE_THREAD_PRIORITY_FUNCTIONS 
1179     if ( pthread_attr_getschedpolicy(&attr
, &policy
) != 0 ) 
1181         wxLogError(_("Cannot retrieve thread scheduling policy.")); 
1185    /* the pthread.h contains too many spaces. This is a work-around */ 
1186 # undef sched_get_priority_max 
1187 #undef sched_get_priority_min 
1188 #define sched_get_priority_max(_pol_) \ 
1189      (_pol_ == SCHED_OTHER ? PRI_FG_MAX_NP : PRI_FIFO_MAX) 
1190 #define sched_get_priority_min(_pol_) \ 
1191      (_pol_ == SCHED_OTHER ? PRI_FG_MIN_NP : PRI_FIFO_MIN) 
1194     int max_prio 
= sched_get_priority_max(policy
), 
1195         min_prio 
= sched_get_priority_min(policy
), 
1196         prio 
= m_internal
->GetPriority(); 
1198     if ( min_prio 
== -1 || max_prio 
== -1 ) 
1200         wxLogError(_("Cannot get priority range for scheduling policy %d."), 
1203     else if ( max_prio 
== min_prio 
) 
1205         if ( prio 
!= WXTHREAD_DEFAULT_PRIORITY 
) 
1207             // notify the programmer that this doesn't work here 
1208             wxLogWarning(_("Thread priority setting is ignored.")); 
1210         //else: we have default priority, so don't complain 
1212         // anyhow, don't do anything because priority is just ignored 
1216         struct sched_param sp
; 
1217         if ( pthread_attr_getschedparam(&attr
, &sp
) != 0 ) 
1219             wxFAIL_MSG(_T("pthread_attr_getschedparam() failed")); 
1222         sp
.sched_priority 
= min_prio 
+ (prio
*(max_prio 
- min_prio
))/100; 
1224         if ( pthread_attr_setschedparam(&attr
, &sp
) != 0 ) 
1226             wxFAIL_MSG(_T("pthread_attr_setschedparam(priority) failed")); 
1229 #endif // HAVE_THREAD_PRIORITY_FUNCTIONS 
1231 #ifdef HAVE_PTHREAD_ATTR_SETSCOPE 
1232     // this will make the threads created by this process really concurrent 
1233     if ( pthread_attr_setscope(&attr
, PTHREAD_SCOPE_SYSTEM
) != 0 ) 
1235         wxFAIL_MSG(_T("pthread_attr_setscope(PTHREAD_SCOPE_SYSTEM) failed")); 
1237 #endif // HAVE_PTHREAD_ATTR_SETSCOPE 
1239     // VZ: assume that this one is always available (it's rather fundamental), 
1240     //     if this function is ever missing we should try to use 
1241     //     pthread_detach() instead (after thread creation) 
1244         if ( pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
) != 0 ) 
1246             wxFAIL_MSG(_T("pthread_attr_setdetachstate(DETACHED) failed")); 
1249         // never try to join detached threads 
1250         m_internal
->Detach(); 
1252     //else: threads are created joinable by default, it's ok 
1254     // create the new OS thread object 
1255     int rc 
= pthread_create
 
1257                 m_internal
->GetIdPtr(), 
1263     if ( pthread_attr_destroy(&attr
) != 0 ) 
1265         wxFAIL_MSG(_T("pthread_attr_destroy() failed")); 
1270         m_internal
->SetState(STATE_EXITED
); 
1272         return wxTHREAD_NO_RESOURCE
; 
1275     return wxTHREAD_NO_ERROR
; 
1278 wxThreadError 
wxThread::Run() 
1280     wxCriticalSectionLocker 
lock(m_critsect
); 
1282     wxCHECK_MSG( m_internal
->GetId(), wxTHREAD_MISC_ERROR
, 
1283                  wxT("must call wxThread::Create() first") ); 
1285     return m_internal
->Run(); 
1288 // ----------------------------------------------------------------------------- 
1290 // ----------------------------------------------------------------------------- 
1292 void wxThread::SetPriority(unsigned int prio
) 
1294     wxCHECK_RET( ((int)WXTHREAD_MIN_PRIORITY 
<= (int)prio
) && 
1295                  ((int)prio 
<= (int)WXTHREAD_MAX_PRIORITY
), 
1296                  wxT("invalid thread priority") ); 
1298     wxCriticalSectionLocker 
lock(m_critsect
); 
1300     switch ( m_internal
->GetState() ) 
1303             // thread not yet started, priority will be set when it is 
1304             m_internal
->SetPriority(prio
); 
1309 #ifdef HAVE_THREAD_PRIORITY_FUNCTIONS 
1311                 struct sched_param sparam
; 
1312                 sparam
.sched_priority 
= prio
; 
1314                 if ( pthread_setschedparam(m_internal
->GetId(), 
1315                                            SCHED_OTHER
, &sparam
) != 0 ) 
1317                     wxLogError(_("Failed to set thread priority %d."), prio
); 
1320 #endif // HAVE_THREAD_PRIORITY_FUNCTIONS 
1325             wxFAIL_MSG(wxT("impossible to set thread priority in this state")); 
1329 unsigned int wxThread::GetPriority() const 
1331     wxCriticalSectionLocker 
lock((wxCriticalSection 
&)m_critsect
); 
1333     return m_internal
->GetPriority(); 
1336 wxThreadIdType 
wxThread::GetId() const 
1338     return (wxThreadIdType
) m_internal
->GetId(); 
1341 // ----------------------------------------------------------------------------- 
1343 // ----------------------------------------------------------------------------- 
1345 wxThreadError 
wxThread::Pause() 
1347     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR
, 
1348                  _T("a thread can't pause itself") ); 
1350     wxCriticalSectionLocker 
lock(m_critsect
); 
1352     if ( m_internal
->GetState() != STATE_RUNNING 
) 
1354         wxLogDebug(wxT("Can't pause thread which is not running.")); 
1356         return wxTHREAD_NOT_RUNNING
; 
1359     wxLogTrace(TRACE_THREADS
, _T("Asking thread %ld to pause."), 
1362     // just set a flag, the thread will be really paused only during the next 
1363     // call to TestDestroy() 
1364     m_internal
->SetState(STATE_PAUSED
); 
1366     return wxTHREAD_NO_ERROR
; 
1369 wxThreadError 
wxThread::Resume() 
1371     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR
, 
1372                  _T("a thread can't resume itself") ); 
1374     wxCriticalSectionLocker 
lock(m_critsect
); 
1376     wxThreadState state 
= m_internal
->GetState(); 
1381             wxLogTrace(TRACE_THREADS
, _T("Thread %ld suspended, resuming."), 
1384             m_internal
->Resume(); 
1386             return wxTHREAD_NO_ERROR
; 
1389             wxLogTrace(TRACE_THREADS
, _T("Thread %ld exited, won't resume."), 
1391             return wxTHREAD_NO_ERROR
; 
1394             wxLogDebug(_T("Attempt to resume a thread which is not paused.")); 
1396             return wxTHREAD_MISC_ERROR
; 
1400 // ----------------------------------------------------------------------------- 
1402 // ----------------------------------------------------------------------------- 
1404 wxThread::ExitCode 
wxThread::Wait() 
1406     wxCHECK_MSG( This() != this, (ExitCode
)-1, 
1407                  _T("a thread can't wait for itself") ); 
1409     wxCHECK_MSG( !m_isDetached
, (ExitCode
)-1, 
1410                  _T("can't wait for detached thread") ); 
1414     return m_internal
->GetExitCode(); 
1417 wxThreadError 
wxThread::Delete(ExitCode 
*rc
) 
1419     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR
, 
1420                  _T("a thread can't delete itself") ); 
1423     wxThreadState state 
= m_internal
->GetState(); 
1425     // ask the thread to stop 
1426     m_internal
->SetCancelFlag(); 
1430         // detached threads won't broadcast about their termination by default 
1431         // because usually nobody waits for them - but here we do, so ask the 
1432         // thread to notify us 
1433         m_internal
->Notify(); 
1441             // we need to wake up the thread so that PthreadStart() will 
1442             // terminate - right now it's blocking on m_semRun 
1443             m_internal
->SignalRun(); 
1452             // resume the thread first (don't call our Resume() because this 
1453             // would dead lock when it tries to enter m_critsect) 
1454             m_internal
->Resume(); 
1459             // wait until the thread stops 
1464                 wxASSERT_MSG( !m_isDetached
, 
1465                               _T("no return code for detached threads") ); 
1467                 // if it's a joinable thread, it's not deleted yet 
1468                 *rc 
= m_internal
->GetExitCode(); 
1472     return wxTHREAD_NO_ERROR
; 
1475 wxThreadError 
wxThread::Kill() 
1477     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR
, 
1478                  _T("a thread can't kill itself") ); 
1480     switch ( m_internal
->GetState() ) 
1484             return wxTHREAD_NOT_RUNNING
; 
1487             // resume the thread first 
1493 #ifdef HAVE_PTHREAD_CANCEL 
1494             if ( pthread_cancel(m_internal
->GetId()) != 0 ) 
1497                 wxLogError(_("Failed to terminate a thread.")); 
1499                 return wxTHREAD_MISC_ERROR
; 
1504                 // if we use cleanup function, this will be done from 
1505                 // wxPthreadCleanup() 
1506 #if !HAVE_THREAD_CLEANUP_FUNCTIONS 
1507                 ScheduleThreadForDeletion(); 
1509                 // don't call OnExit() here, it can only be called in the 
1510                 // threads context and we're in the context of another thread 
1513 #endif // HAVE_THREAD_CLEANUP_FUNCTIONS 
1517                 m_internal
->SetExitCode(EXITCODE_CANCELLED
); 
1520             return wxTHREAD_NO_ERROR
; 
1524 void wxThread::Exit(ExitCode status
) 
1526     wxASSERT_MSG( This() == this, 
1527                   _T("wxThread::Exit() can only be called in the " 
1528                      "context of the same thread") ); 
1530     // from the moment we call OnExit(), the main program may terminate at any 
1531     // moment, so mark this thread as being already in process of being 
1532     // deleted or wxThreadModule::OnExit() will try to delete it again 
1533     ScheduleThreadForDeletion(); 
1535     // don't enter m_critsect before calling OnExit() because the user code 
1536     // might deadlock if, for example, it signals a condition in OnExit() (a 
1537     // common case) while the main thread calls any of functions entering 
1538     // m_critsect on us (almost all of them do) 
1541     // now do enter it because SignalExit() will change our state 
1544     // next wake up the threads waiting for us (OTOH, this function won't return 
1545     // until someone waited for us!) 
1546     m_internal
->SignalExit(); 
1548     // leave the critical section before entering the dtor which tries to 
1552     // delete C++ thread object if this is a detached thread - user is 
1553     // responsible for doing this for joinable ones 
1556         // FIXME I'm feeling bad about it - what if another thread function is 
1557         //       called (in another thread context) now? It will try to access 
1558         //       half destroyed object which will probably result in something 
1559         //       very bad - but we can't protect this by a crit section unless 
1560         //       we make it a global object, but this would mean that we can 
1561         //       only call one thread function at a time :-( 
1565     // terminate the thread (pthread_exit() never returns) 
1566     pthread_exit(status
); 
1568     wxFAIL_MSG(_T("pthread_exit() failed")); 
1571 // also test whether we were paused 
1572 bool wxThread::TestDestroy() 
1574     wxASSERT_MSG( This() == this, 
1575                   _T("wxThread::TestDestroy() can only be called in the " 
1576                      "context of the same thread") ); 
1580     if ( m_internal
->GetState() == STATE_PAUSED 
) 
1582         m_internal
->SetReallyPaused(TRUE
); 
1584         // leave the crit section or the other threads will stop too if they 
1585         // try to call any of (seemingly harmless) IsXXX() functions while we 
1589         m_internal
->Pause(); 
1593         // thread wasn't requested to pause, nothing to do 
1597     return m_internal
->WasCancelled(); 
1600 wxThread::~wxThread() 
1605     // check that the thread either exited or couldn't be created 
1606     if ( m_internal
->GetState() != STATE_EXITED 
&& 
1607          m_internal
->GetState() != STATE_NEW 
) 
1609         wxLogDebug(_T("The thread %ld is being destroyed although it is still " 
1610                       "running! The application may crash."), GetId()); 
1614 #endif // __WXDEBUG__ 
1618     // remove this thread from the global array 
1619     gs_allThreads
.Remove(this); 
1621     // detached thread will decrement this counter in DeleteThread(), but it 
1622     // is not called for the joinable threads, so do it here 
1623     if ( !m_isDetached 
) 
1625         wxMutexLocker 
lock( *gs_mutexDeleteThread 
); 
1627         gs_nThreadsBeingDeleted
--; 
1629         wxLogTrace(TRACE_THREADS
, _T("%u scheduled for deletion threads left."), 
1630                    gs_nThreadsBeingDeleted 
- 1); 
1634 // ----------------------------------------------------------------------------- 
1636 // ----------------------------------------------------------------------------- 
1638 bool wxThread::IsRunning() const 
1640     wxCriticalSectionLocker 
lock((wxCriticalSection 
&)m_critsect
); 
1642     return m_internal
->GetState() == STATE_RUNNING
; 
1645 bool wxThread::IsAlive() const 
1647     wxCriticalSectionLocker 
lock((wxCriticalSection
&)m_critsect
); 
1649     switch ( m_internal
->GetState() ) 
1660 bool wxThread::IsPaused() const 
1662     wxCriticalSectionLocker 
lock((wxCriticalSection
&)m_critsect
); 
1664     return (m_internal
->GetState() == STATE_PAUSED
); 
1667 //-------------------------------------------------------------------- 
1669 //-------------------------------------------------------------------- 
1671 class wxThreadModule 
: public wxModule
 
1674     virtual bool OnInit(); 
1675     virtual void OnExit(); 
1678     DECLARE_DYNAMIC_CLASS(wxThreadModule
) 
1681 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule
, wxModule
) 
1683 bool wxThreadModule::OnInit() 
1685     int rc 
= pthread_key_create(&gs_keySelf
, NULL 
/* dtor function */); 
1688         wxLogSysError(rc
, _("Thread module initialization failed: " 
1689                             "failed to create thread key")); 
1694     gs_tidMain 
= pthread_self(); 
1697     gs_mutexGui 
= new wxMutex(); 
1699     gs_mutexGui
->Lock(); 
1702     gs_mutexDeleteThread 
= new wxMutex(); 
1703     gs_condAllDeleted 
= new wxCondition( *gs_mutexDeleteThread 
); 
1708 void wxThreadModule::OnExit() 
1710     wxASSERT_MSG( wxThread::IsMain(), wxT("only main thread can be here") ); 
1712     // are there any threads left which are being deleted right now? 
1713     size_t nThreadsBeingDeleted
; 
1716         wxMutexLocker 
lock( *gs_mutexDeleteThread 
); 
1717         nThreadsBeingDeleted 
= gs_nThreadsBeingDeleted
; 
1719         if ( nThreadsBeingDeleted 
> 0 ) 
1721             wxLogTrace(TRACE_THREADS
, _T("Waiting for %u threads to disappear"), 
1722                            nThreadsBeingDeleted
); 
1724             // have to wait until all of them disappear 
1725             gs_condAllDeleted
->Wait(); 
1729     // terminate any threads left 
1730     size_t count 
= gs_allThreads
.GetCount(); 
1733         wxLogDebug(wxT("%u threads were not terminated by the application."), 
1737     for ( size_t n 
= 0u; n 
< count
; n
++ ) 
1739         // Delete calls the destructor which removes the current entry. We 
1740         // should only delete the first one each time. 
1741         gs_allThreads
[0]->Delete(); 
1745     // destroy GUI mutex 
1746     gs_mutexGui
->Unlock(); 
1751     // and free TLD slot 
1752     (void)pthread_key_delete(gs_keySelf
); 
1754     delete gs_condAllDeleted
; 
1755     delete gs_mutexDeleteThread
; 
1758 // ---------------------------------------------------------------------------- 
1760 // ---------------------------------------------------------------------------- 
1762 static void ScheduleThreadForDeletion() 
1764     wxMutexLocker 
lock( *gs_mutexDeleteThread 
); 
1766     gs_nThreadsBeingDeleted
++; 
1768     wxLogTrace(TRACE_THREADS
, _T("%u thread%s waiting to be deleted"), 
1769                gs_nThreadsBeingDeleted
, 
1770                gs_nThreadsBeingDeleted 
== 1 ? "" : "s"); 
1773 static void DeleteThread(wxThread 
*This
) 
1775     // gs_mutexDeleteThread should be unlocked before signalling the condition 
1776     // or wxThreadModule::OnExit() would deadlock 
1777     wxMutexLocker 
locker( *gs_mutexDeleteThread 
); 
1779     wxLogTrace(TRACE_THREADS
, _T("Thread %ld auto deletes."), This
->GetId()); 
1783     wxCHECK_RET( gs_nThreadsBeingDeleted 
> 0, 
1784                      _T("no threads scheduled for deletion, yet we delete " 
1787     wxLogTrace(TRACE_THREADS
, _T("%u scheduled for deletion threads left."), 
1788                gs_nThreadsBeingDeleted 
- 1); 
1790     if ( !--gs_nThreadsBeingDeleted 
) 
1792         // no more threads left, signal it 
1793         gs_condAllDeleted
->Signal(); 
1797 void wxMutexGuiEnter() 
1800     gs_mutexGui
->Lock(); 
1804 void wxMutexGuiLeave() 
1807     gs_mutexGui
->Unlock();