+#endif
+
+#if wxUSE_MAC_CRITICAL_REGION_MUTEX
+
+class wxMutexInternal
+{
+public:
+ wxMutexInternal( wxMutexType mutexType );
+ virtual ~wxMutexInternal();
+
+ bool IsOk() const { return m_isOk; }
+
+ wxMutexError Lock() { return Lock(kDurationForever); }
+ wxMutexError Lock(unsigned long ms);
+ wxMutexError TryLock();
+ wxMutexError Unlock();
+
+private:
+ MPCriticalRegionID m_critRegion;
+ bool m_isOk ;
+};
+
+wxMutexInternal::wxMutexInternal( wxMutexType mutexType )
+{
+ m_isOk = false;
+ m_critRegion = kInvalidID;
+
+ verify_noerr( MPCreateCriticalRegion( &m_critRegion ) );
+ m_isOk = ( m_critRegion != kInvalidID );
+ if ( !IsOk() )
+ {
+ wxFAIL_MSG( wxT("Error when creating mutex") );
+ }
+}
+
+wxMutexInternal::~wxMutexInternal()
+{
+ if ( m_critRegion != kInvalidID )
+ MPDeleteCriticalRegion( m_critRegion );
+
+ MPYield();
+}
+
+wxMutexError wxMutexInternal::Lock(unsigned long ms)
+{
+ wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") );
+
+ OSStatus err = MPEnterCriticalRegion( m_critRegion, ms );
+ switch ( err )
+ {
+ case noErr:
+ break;
+
+ case kMPTimeoutErr:
+ wxASSERT_MSG( ms != kDurationForever, wxT("unexpected timeout") );
+ return wxMUTEX_TIMEOUT;
+
+ default:
+ 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 = MPEnterCriticalRegion( m_critRegion, 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 = MPExitCriticalRegion( m_critRegion );
+ MPYield() ;
+
+ if (err != noErr)
+ {
+ wxLogSysError( wxT("Could not unlock mutex") );
+
+ return wxMUTEX_MISC_ERROR;
+ }
+
+ return wxMUTEX_NO_ERROR;
+}
+
+#endif
+
+// --------------------------------------------------------------------------
+// wxSemaphore
+// --------------------------------------------------------------------------
+
+class wxSemaphoreInternal
+{
+public:
+ wxSemaphoreInternal( int initialcount, int maxcount );
+ virtual ~wxSemaphoreInternal();
+
+ bool IsOk() const
+ { return m_isOk; }
+
+ wxSemaError Post();
+ wxSemaError WaitTimeout( unsigned long milliseconds );
+
+ wxSemaError Wait()
+ { return WaitTimeout( kDurationForever); }
+
+ wxSemaError TryWait()
+ {
+ wxSemaError err = WaitTimeout( kDurationImmediate );
+ if (err == wxSEMA_TIMEOUT)
+ err = wxSEMA_BUSY;
+
+ return err;
+ }
+
+private:
+ MPSemaphoreID m_semaphore;
+ bool m_isOk;
+};
+
+wxSemaphoreInternal::wxSemaphoreInternal( int initialcount, int maxcount)
+{
+ m_isOk = false;
+ m_semaphore = kInvalidID;
+ if ( maxcount == 0 )
+ // make it practically infinite
+ maxcount = INT_MAX;
+
+ verify_noerr( MPCreateSemaphore( maxcount, initialcount, &m_semaphore ) );
+ m_isOk = ( m_semaphore != kInvalidID );
+
+ if ( !IsOk() )
+ {
+ wxFAIL_MSG( wxT("Error when creating semaphore") );
+ }
+}
+
+wxSemaphoreInternal::~wxSemaphoreInternal()
+{
+ if (m_semaphore != kInvalidID)
+ MPDeleteSemaphore( m_semaphore );
+
+ MPYield();
+}
+
+wxSemaError wxSemaphoreInternal::WaitTimeout( unsigned long milliseconds )
+{
+ OSStatus err = MPWaitOnSemaphore( m_semaphore, milliseconds );
+ if (err != noErr)
+ {
+ if (err == kMPTimeoutErr)
+ return wxSEMA_TIMEOUT;
+
+ return wxSEMA_MISC_ERROR;
+ }
+
+ return wxSEMA_NO_ERROR;
+}
+
+wxSemaError wxSemaphoreInternal::Post()
+{
+ OSStatus err = MPSignalSemaphore( m_semaphore );
+ MPYield();
+ if (err != noErr)
+ return wxSEMA_MISC_ERROR;
+
+ return wxSEMA_NO_ERROR;
+}
+