-#if wxUSE_MAC_PTHREADS_MUTEX
-
-#include <pthread.h>
-
-
-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
-