X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b2680ced12cbbed16990007c5fa3ea7730700122..472137baebae6c011ad7d70285de454b9ce7796d:/src/osx/carbon/thread.cpp?ds=inline diff --git a/src/osx/carbon/thread.cpp b/src/osx/carbon/thread.cpp index d8bcd279da..f780d4bc03 100644 --- a/src/osx/carbon/thread.cpp +++ b/src/osx/carbon/thread.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/mac/carbon/thread.cpp +// Name: src/osx/carbon/thread.cpp // Purpose: wxThread Implementation // Author: Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin // Modified by: Aj Lavin, Stefan Csomor @@ -106,7 +106,7 @@ MPCriticalRegionID gs_guiCritical = kInvalidID; // wxCriticalSection // ---------------------------------------------------------------------------- -wxCriticalSection::wxCriticalSection() +wxCriticalSection::wxCriticalSection( wxCriticalSectionType WXUNUSED(critSecType) ) { MPCreateCriticalRegion( (MPCriticalRegionID*) &m_critRegion ); } @@ -134,270 +134,6 @@ void wxCriticalSection::Leave() #define wxUSE_MAC_CRITICAL_REGION_MUTEX 1 #define wxUSE_MAC_PTHREADS_MUTEX 0 -#if wxUSE_MAC_PTHREADS_MUTEX - -#include - - -class wxMutexInternal -{ -public: - wxMutexInternal( wxMutexType mutexType ); - ~wxMutexInternal(); - - wxMutexError Lock(); - wxMutexError TryLock(); - wxMutexError Unlock(); - - bool IsOk() const - { return m_isOk; } - -private: - pthread_mutex_t m_mutex; - bool m_isOk; - - // wxConditionInternal uses our m_mutex - friend class wxConditionInternal; -}; - -#ifdef HAVE_PTHREAD_MUTEXATTR_T -// on some systems pthread_mutexattr_settype() is not in the headers (but it is -// in the library, otherwise we wouldn't compile this code at all) -extern "C" int pthread_mutexattr_settype( pthread_mutexattr_t *, int ); -#endif - -wxMutexInternal::wxMutexInternal( wxMutexType mutexType ) -{ - int err; - switch ( mutexType ) - { - case wxMUTEX_RECURSIVE: - // support recursive locks like Win32, i.e. a thread can lock a - // mutex which it had itself already locked - // - // unfortunately initialization of recursive mutexes is non - // portable, so try several methods -#ifdef HAVE_PTHREAD_MUTEXATTR_T - { - pthread_mutexattr_t attr; - pthread_mutexattr_init( &attr ); - pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); - - err = pthread_mutex_init( &m_mutex, &attr ); - } -#elif defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER) - // we can use this only as initializer so we have to assign it - // first to a temp var - assigning directly to m_mutex wouldn't - // even compile - { - pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; - m_mutex = mutex; - } -#else // no recursive mutexes - err = EINVAL; -#endif // HAVE_PTHREAD_MUTEXATTR_T/... - break; - - default: - wxFAIL_MSG( wxT("unknown mutex type") ); - // fall through - - case wxMUTEX_DEFAULT: - err = pthread_mutex_init( &m_mutex, NULL ); - break; - } - - m_isOk = err == 0; - if ( !m_isOk ) - { - wxLogApiError( wxT("pthread_mutex_init()"), err ); - } -} - -wxMutexInternal::~wxMutexInternal() -{ - if ( m_isOk ) - { - int err = pthread_mutex_destroy( &m_mutex ); - if ( err != 0 ) - { - wxLogApiError( wxT("pthread_mutex_destroy()"), err ); - } - } -} - -wxMutexError wxMutexInternal::Lock() -{ - int err = pthread_mutex_lock( &m_mutex ); - switch ( err ) - { - case EDEADLK: - // only error checking mutexes return this value and so it's an - // unexpected situation -- hence use assert, not wxLogDebug - wxFAIL_MSG( wxT("mutex deadlock prevented") ); - return wxMUTEX_DEAD_LOCK; - - case EINVAL: - wxLogDebug( wxT("pthread_mutex_lock(): mutex not initialized.") ); - break; - - case 0: - return wxMUTEX_NO_ERROR; - - default: - wxLogApiError( wxT("pthread_mutex_lock()"), err ); - } - - return wxMUTEX_MISC_ERROR; -} - -wxMutexError wxMutexInternal::TryLock() -{ - int err = pthread_mutex_trylock( &m_mutex ); - switch ( err ) - { - case EBUSY: - // not an error: mutex is already locked, but we're prepared for this case - return wxMUTEX_BUSY; - - case EINVAL: - wxLogDebug( wxT("pthread_mutex_trylock(): mutex not initialized.") ); - break; - - case 0: - return wxMUTEX_NO_ERROR; - - default: - wxLogApiError( wxT("pthread_mutex_trylock()"), err ); - } - - return wxMUTEX_MISC_ERROR; -} - -wxMutexError wxMutexInternal::Unlock() -{ - int err = pthread_mutex_unlock( &m_mutex ); - switch ( err ) - { - case EPERM: - // we don't own the mutex - return wxMUTEX_UNLOCKED; - - case EINVAL: - wxLogDebug( wxT("pthread_mutex_unlock(): mutex not initialized.") ); - break; - - case 0: - return wxMUTEX_NO_ERROR; - - default: - wxLogApiError( wxT("pthread_mutex_unlock()"), err ); - } - - return wxMUTEX_MISC_ERROR; -} - -#endif - -#if wxUSE_MAC_SEMAPHORE_MUTEX - -class wxMutexInternal -{ -public: - wxMutexInternal( wxMutexType mutexType ); - virtual ~wxMutexInternal(); - - bool IsOk() const - { return m_isOk; } - - wxMutexError Lock(); - wxMutexError TryLock(); - wxMutexError Unlock(); - -private: - MPSemaphoreID m_semaphore; - bool m_isOk; -}; - -wxMutexInternal::wxMutexInternal(wxMutexType mutexType ) -{ - m_isOk = false; - m_semaphore = kInvalidID; - OSStatus err = noErr; - - switch ( mutexType ) - { - case wxMUTEX_DEFAULT : - verify_noerr( MPCreateBinarySemaphore( &m_semaphore ) ); - m_isOk = ( m_semaphore != kInvalidID ); - break; - - case wxMUTEX_RECURSIVE : - wxFAIL_MSG( wxT("Recursive Mutex not supported yet") ); - break; - - default : - wxFAIL_MSG( wxT("Unknown mutex type") ); - break; - } -} - -wxMutexInternal::~wxMutexInternal() -{ - if ( m_semaphore != kInvalidID ) - MPDeleteSemaphore( m_semaphore ); - - MPYield(); -} - -wxMutexError wxMutexInternal::Lock() -{ - wxCHECK_MSG( m_isOk, wxMUTEX_MISC_ERROR, wxT("Invalid Mutex") ); - OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationForever ); - if (err != noErr) - { - wxLogSysError( wxT("Could not lock mutex") ); - - return wxMUTEX_MISC_ERROR; - } - - return wxMUTEX_NO_ERROR; -} - -wxMutexError wxMutexInternal::TryLock() -{ - wxCHECK_MSG( m_isOk, wxMUTEX_MISC_ERROR, wxT("Invalid Mutex") ); - OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationImmediate ); - if (err != noErr) - { - if (err == kMPTimeoutErr) - return wxMUTEX_BUSY; - - wxLogSysError( wxT("Could not try lock mutex") ); - - return wxMUTEX_MISC_ERROR; - } - - return wxMUTEX_NO_ERROR; -} - -wxMutexError wxMutexInternal::Unlock() -{ - wxCHECK_MSG( m_isOk, wxMUTEX_MISC_ERROR, wxT("Invalid Mutex") ); - OSStatus err = MPSignalSemaphore( m_semaphore ); - - MPYield(); - if (err != noErr) - { - wxLogSysError( wxT("Could not unlock mutex") ); - return wxMUTEX_MISC_ERROR; - } - - return wxMUTEX_NO_ERROR; -} - -#endif - #if wxUSE_MAC_CRITICAL_REGION_MUTEX class wxMutexInternal @@ -583,177 +319,6 @@ wxSemaError wxSemaphoreInternal::Post() // wxCondition implementation // ---------------------------------------------------------------------------- -#if 0 - -class wxConditionInternal -{ -public: - wxConditionInternal( wxMutex& mutex ) - : - m_mutex( mutex ), - m_semaphore( 0, 1 ), - m_gate( 1, 1 ) - { - m_waiters = 0; - m_signals = 0; - m_canceled = 0; - } - - virtual ~wxConditionInternal() {} - - bool IsOk() const - { return m_mutex.IsOk(); } - - wxCondError Wait() - { return WaitTimeout( kDurationForever ); } - - wxCondError WaitTimeout( unsigned long msectimeout ); - - wxCondError Signal() - { return DoSignal( false); } - - wxCondError Broadcast() - { return DoSignal( true ); } - -private: - wxCondError DoSignal( bool signalAll ); - - wxMutex& m_mutex; - wxSemaphoreInternal m_semaphore; // Signals the waiting threads. - wxSemaphoreInternal m_gate; - wxCriticalSection m_varSection; - size_t m_waiters; // Number of threads waiting for a signal. - size_t m_signals; // Number of signals to send. - size_t m_canceled; // Number of canceled waiters in m_waiters. -}; - -wxCondError wxConditionInternal::WaitTimeout( unsigned long msectimeout ) -{ - m_gate.Wait(); - - if ( ++ m_waiters == INT_MAX ) - { - m_varSection.Enter(); - - m_waiters -= m_canceled; - m_signals -= m_canceled; - m_canceled = 0; - - m_varSection.Leave(); - } - - m_gate.Post(); - m_mutex.Unlock(); - - wxSemaError err = m_semaphore.WaitTimeout( msectimeout); - wxASSERT( err == wxSEMA_NO_ERROR || err == wxSEMA_TIMEOUT); - - m_varSection.Enter(); - - if ( err != wxSEMA_NO_ERROR ) - { - if ( m_signals > m_canceled ) - { - // A signal is being sent after we timed out. - if ( m_waiters == m_signals ) - { - // There are no excess waiters to catch the signal, so - // we must throw it away. - wxSemaError err2 = m_semaphore.Wait(); - if ( err2 != wxSEMA_NO_ERROR ) - { - wxLogSysError( wx("Error while waiting on semaphore") ); - } - - wxASSERT( err2 == wxSEMA_NO_ERROR); - - --m_waiters; - if ( --m_signals == m_canceled ) - { - // This was the last signal. open the gate. - wxASSERT( m_waiters == m_canceled ); - m_gate.Post(); - } - } - else - { - // There are excess waiters to catch the signal, leave it be. - --m_waiters; - } - } - else - { - // No signals is being sent: - // the gate may be open or closed, so we can't touch m_waiters. - ++m_canceled; - ++m_signals; - } - } - else - { - // We caught a signal. - wxASSERT( m_signals > m_canceled ); - - --m_waiters; - - if ( --m_signals == m_canceled) - { - // This was the last signal. open the gate. - wxASSERT( m_waiters == m_canceled ); - - m_gate.Post(); - } - } - - m_varSection.Leave(); - m_mutex.Lock(); - - if (err != noErr) - return err == wxSEMA_TIMEOUT ? wxCOND_TIMEOUT : wxCOND_MISC_ERROR; - - return wxCOND_NO_ERROR; -} - - -wxCondError wxConditionInternal::DoSignal( bool signalAll) -{ - m_gate.Wait(); - m_varSection.Enter(); - - wxASSERT( m_signals == m_canceled ); - - if ( m_waiters == m_canceled) - { - m_varSection.Leave(); - m_gate.Post(); - return wxCOND_NO_ERROR; - } - - if ( m_canceled > 0) - { - m_waiters -= m_canceled; - m_signals = 0; - m_canceled = 0; - } - - m_signals = signalAll ? m_waiters : 1; - size_t n = m_signals; - - m_varSection.Leave(); - - // Let the waiters inherit the gate lock. - - do - { - wxSemaError err = m_semaphore.Post(); - wxASSERT( err == wxSEMA_NO_ERROR ); - } - while ( --n ); - - return wxCOND_NO_ERROR; -} - -#else class wxConditionInternal { public: @@ -884,7 +449,6 @@ wxCondError wxConditionInternal::Broadcast() return wxCOND_NO_ERROR; } -#endif // ---------------------------------------------------------------------------- // wxCriticalSection implementation