+wxMutexInternal::wxMutexInternal()
+{
+ // support recursive locks like Win32, i.e. a thread can lock a mutex which
+ // it had itself already locked
+ //
+ // but initialization of recursive mutexes is non portable <sigh>, so try
+ // several methods
+#ifdef HAVE_PTHREAD_MUTEXATTR_T
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ 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
+ pthread_mutex_init(&m_mutex, NULL);
+
+ // used by TryLock() below
+ #define NO_RECURSIVE_MUTEXES
+#endif // HAVE_PTHREAD_MUTEXATTR_T/...
+}
+
+wxMutexInternal::~wxMutexInternal()
+{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+wxMutexError wxMutexInternal::Lock()
+{
+ int err = pthread_mutex_lock(&m_mutex);
+ switch ( err )
+ {
+ case EDEADLK:
+ wxLogDebug(wxT("Locking this mutex would lead to deadlock!"));
+ return wxMUTEX_DEAD_LOCK;
+
+ default:
+ wxFAIL_MSG( _T("unexpected pthread_mutex_lock() return") );
+ // fall through
+
+ case EINVAL:
+ wxLogDebug(_T("Failed to lock the mutex."));
+ return wxMUTEX_MISC_ERROR;
+
+ case 0:
+ return wxMUTEX_NO_ERROR;
+ }
+}
+
+wxMutexError wxMutexInternal::TryLock()
+{
+ int err = pthread_mutex_trylock(&m_mutex);
+ switch ( err )
+ {
+ case EBUSY:
+ return wxMUTEX_BUSY;
+
+ default:
+ wxFAIL_MSG( _T("unexpected pthread_mutex_trylock() return") );
+ // fall through
+
+ case EINVAL:
+ wxLogDebug(_T("Failed to try to lock the mutex."));
+ return wxMUTEX_MISC_ERROR;
+
+ case 0:
+ return wxMUTEX_NO_ERROR;
+ }
+}
+
+wxMutexError wxMutexInternal::Unlock()
+{
+ int err = pthread_mutex_unlock(&m_mutex);
+ switch ( err )
+ {
+ case EPERM:
+ // we don't own the mutex
+ return wxMUTEX_UNLOCKED;
+
+ default:
+ wxFAIL_MSG( _T("unexpected pthread_mutex_unlock() return") );
+ // fall through
+
+ case EINVAL:
+ wxLogDebug(_T("Failed to unlock the mutex."));
+ return wxMUTEX_MISC_ERROR;
+
+ case 0:
+ return wxMUTEX_NO_ERROR;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxMutex
+// ----------------------------------------------------------------------------
+
+// TODO: this is completely generic, move it to common code?
+