X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6fe7378863be6febaaab0e8aa855b51781351ac5..b4efa0696e9b6fdc6b19441981c5e0341d177a48:/src/mac/carbon/thread.cpp diff --git a/src/mac/carbon/thread.cpp b/src/mac/carbon/thread.cpp index a8243467ed..75db6e539e 100644 --- a/src/mac/carbon/thread.cpp +++ b/src/mac/carbon/thread.cpp @@ -34,6 +34,11 @@ #include "wx/module.h" #include "wx/thread.h" +#ifdef __WXMAC__ +#include +#include "wx/mac/uma.h" +#endif + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -63,13 +68,15 @@ static bool gs_waitingForThread = FALSE ; class wxMacStCritical { public : - wxMacStCritical() + wxMacStCritical() { - ThreadBeginCritical() ; + if ( UMASystemIsInitialized() ) + ThreadBeginCritical() ; } ~wxMacStCritical() { - ThreadEndCritical() ; + if ( UMASystemIsInitialized() ) + ThreadEndCritical() ; } }; @@ -85,7 +92,7 @@ public: m_owner = kNoThreadID ; } - ~wxMutexInternal() + ~wxMutexInternal() { } @@ -114,19 +121,21 @@ wxMutex::~wxMutex() wxMutexError wxMutex::Lock() { wxMacStCritical critical ; - - OSErr err ; - ThreadID current = kNoThreadID; - err = ::MacGetCurrentThread(¤t); - // if we are not the owner, add this thread to the list of waiting threads, stop this thread - // and invoke the scheduler to continue executing the owner's thread - while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current) - { - m_internal->m_waiters.Add(current); - err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner); - err = ::ThreadBeginCritical(); + if ( UMASystemIsInitialized() ) + { + OSErr err ; + ThreadID current = kNoThreadID; + err = ::MacGetCurrentThread(¤t); + // if we are not the owner, add this thread to the list of waiting threads, stop this thread + // and invoke the scheduler to continue executing the owner's thread + while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current) + { + m_internal->m_waiters.Add(current); + err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner); + err = ::ThreadBeginCritical(); + } + m_internal->m_owner = current; } - m_internal->m_owner = current; m_locked++; return wxMUTEX_NO_ERROR; @@ -135,15 +144,16 @@ wxMutexError wxMutex::Lock() wxMutexError wxMutex::TryLock() { wxMacStCritical critical ; - - OSErr err ; - ThreadID current = kNoThreadID; - ::MacGetCurrentThread(¤t); - // if we are not the owner, give an error back - if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current ) - return wxMUTEX_BUSY; - - m_internal->m_owner = current; + if ( UMASystemIsInitialized() ) + { + ThreadID current = kNoThreadID; + ::MacGetCurrentThread(¤t); + // if we are not the owner, give an error back + if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current ) + return wxMUTEX_BUSY; + + m_internal->m_owner = current; + } m_locked++; return wxMUTEX_NO_ERROR; @@ -151,32 +161,39 @@ wxMutexError wxMutex::TryLock() wxMutexError wxMutex::Unlock() { - OSErr err; - err = ::ThreadBeginCritical(); - - if (m_locked > 0) - m_locked--; + if ( UMASystemIsInitialized() ) + { + OSErr err; + err = ::ThreadBeginCritical(); - // this mutex is not owned by anybody anmore - m_internal->m_owner = kNoThreadID; + if (m_locked > 0) + m_locked--; - // now pass on to the first waiting thread - ThreadID firstWaiting = kNoThreadID; - bool found = false; - while (!m_internal->m_waiters.IsEmpty() && !found) + // this mutex is not owned by anybody anmore + m_internal->m_owner = kNoThreadID; + + // now pass on to the first waiting thread + ThreadID firstWaiting = kNoThreadID; + bool found = false; + while (!m_internal->m_waiters.IsEmpty() && !found) + { + firstWaiting = m_internal->m_waiters[0]; + err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID); + // in case this was not successful (dead thread), we just loop on and reset the id + found = (err != threadNotFoundErr); + if ( !found ) + firstWaiting = kNoThreadID ; + m_internal->m_waiters.RemoveAt(0) ; + } + // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the + // critical section and invoke the scheduler + err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting); + } + else { - firstWaiting = m_internal->m_waiters[0]; - err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID); - // in case this was not successful (dead thread), we just loop on and reset the id - found = (err != threadNotFoundErr); - if ( !found ) - firstWaiting = kNoThreadID ; - m_internal->m_waiters.RemoveAt(0) ; + if (m_locked > 0) + m_locked--; } - // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the - // critical section and invoke the scheduler - err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting); - return wxMUTEX_NO_ERROR; } @@ -187,7 +204,7 @@ wxMutexError wxMutex::Unlock() class wxConditionInternal { public: - wxConditionInternal() + wxConditionInternal(wxMutex& mutex) : m_mutex(mutex) { m_excessSignals = 0 ; } @@ -229,11 +246,12 @@ public: wxArrayLong m_waiters ; wxInt32 m_excessSignals ; + wxMutex& m_mutex; }; -wxCondition::wxCondition() +wxCondition::wxCondition(wxMutex& mutex) { - m_internal = new wxConditionInternal; + m_internal = new wxConditionInternal(mutex); } wxCondition::~wxCondition() @@ -246,10 +264,9 @@ void wxCondition::Wait() (void)m_internal->Wait(0xFFFFFFFFL); } -bool wxCondition::Wait(unsigned long sec, - unsigned long nsec) +bool wxCondition::Wait(unsigned long timeout_millis) { - return m_internal->Wait(sec*1000 + nsec/1000000); + return m_internal->Wait(timeout_millis); } void wxCondition::Signal() @@ -267,7 +284,7 @@ void wxCondition::Broadcast() // this works because all these threads are already waiting and so each // SetEvent() inside Signal() is really a PulseEvent() because the event // state is immediately returned to non-signaled - for ( int i = 0; i < m_internal->m_waiters.Count(); i++ ) + for ( size_t i = 0; i < m_internal->m_waiters.Count(); i++ ) { Signal(); } @@ -319,7 +336,7 @@ public: // thread priority void SetPriority(unsigned int priority); unsigned int GetPriority() const { return m_priority; } - + void SetResult( void *res ) { m_result = res ; } void *GetResult() { return m_result ; } @@ -405,7 +422,7 @@ bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize) bool wxThreadInternal::Suspend() { OSErr err ; - + ::ThreadBeginCritical(); if ( m_state != STATE_RUNNING ) @@ -430,18 +447,18 @@ bool wxThreadInternal::Resume() wxASSERT( err == noErr ) ; wxASSERT( current != m_tid ) ; - + ::ThreadBeginCritical(); if ( m_state != STATE_PAUSED && m_state != STATE_NEW ) { ::ThreadEndCritical() ; wxLogSysError(_("Can not resume thread %x"), m_tid); return FALSE; - + } err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID); wxASSERT( err == noErr ) ; - + m_state = STATE_RUNNING; ::ThreadEndCritical() ; ::YieldToAnyThread() ; @@ -453,13 +470,13 @@ bool wxThreadInternal::Resume() wxThread *wxThread::This() { wxMacStCritical critical ; - + ThreadID current ; OSErr err ; - + err = MacGetCurrentThread( ¤t ) ; - - for ( int i = 0 ; i < s_threads.Count() ; ++i ) + + for ( size_t i = 0 ; i < s_threads.Count() ; ++i ) { if ( ( (wxThread*) s_threads[i] )->GetId() == current ) return (wxThread*) s_threads[i] ; @@ -473,7 +490,7 @@ bool wxThread::IsMain() { ThreadID current ; OSErr err ; - + err = MacGetCurrentThread( ¤t ) ; return current == gs_idMainThread; } @@ -490,7 +507,7 @@ void wxThread::Yield() void wxThread::Sleep(unsigned long milliseconds) { clock_t start = clock() ; - do + do { YieldToAnyThread() ; } while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ; @@ -502,6 +519,13 @@ int wxThread::GetCPUCount() return 1; } +unsigned long wxThread::GetCurrentId() +{ + ThreadID current ; + MacGetCurrentThread( ¤t ) ; + return (unsigned long)current; +} + bool wxThread::SetConcurrency(size_t level) { wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") ); @@ -517,7 +541,7 @@ bool wxThread::SetConcurrency(size_t level) // processor system it doesn't make much sense anyhow return level == 1; } - + return TRUE ; } @@ -728,7 +752,7 @@ void wxThread::Exit(ExitCode status) m_internal->SetResult( status ) ; -/* +/* #if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) _endthreadex((unsigned)status); #else // !VC++ @@ -844,7 +868,7 @@ bool WXDLLEXPORT wxGuiOwnedByMainThread() return false ; } -// wake up the main thread +// wake up the main thread void WXDLLEXPORT wxWakeUpMainThread() { wxMacWakeUp() ;