X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3ad41c280f8d84a34b20e29719fea73481386840..3cfde7c049bddf6fd3b4c2e35a6b8ecdcdc1d74f:/src/msw/thread.cpp diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 072df5b373..2a692e374d 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -190,11 +190,14 @@ private: HANDLE m_mutex; + unsigned long m_owningThread; + wxMutexType m_type; + DECLARE_NO_COPY_CLASS(wxMutexInternal) }; // all mutexes are recursive under Win32 so we don't use mutexType -wxMutexInternal::wxMutexInternal(wxMutexType WXUNUSED(mutexType)) +wxMutexInternal::wxMutexInternal(wxMutexType mutexType) { // create a nameless (hence intra process and always private) mutex m_mutex = ::CreateMutex @@ -204,10 +207,14 @@ wxMutexInternal::wxMutexInternal(wxMutexType WXUNUSED(mutexType)) NULL // no name ); + m_type = mutexType; + m_owningThread = 0; + if ( !m_mutex ) { wxLogLastError(_T("CreateMutex()")); } + } wxMutexInternal::~wxMutexInternal() @@ -231,19 +238,25 @@ wxMutexError wxMutexInternal::TryLock() wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds) { - DWORD rc = ::WaitForSingleObject(m_mutex, milliseconds); - if ( rc == WAIT_ABANDONED ) + if (m_type == wxMUTEX_DEFAULT) { - // the previous caller died without releasing the mutex, but now we can - // really lock it - wxLogDebug(_T("WaitForSingleObject() returned WAIT_ABANDONED")); - - // use 0 timeout, normally we should always get it - rc = ::WaitForSingleObject(m_mutex, 0); + // Don't allow recursive + if (m_owningThread != 0) + { + if (m_owningThread == wxThread::GetCurrentId()) + return wxMUTEX_DEAD_LOCK; + } } + DWORD rc = ::WaitForSingleObject(m_mutex, milliseconds); switch ( rc ) { + case WAIT_ABANDONED: + // the previous caller died without releasing the mutex, so even + // though we did get it, log a message about this + wxLogDebug(_T("WaitForSingleObject() returned WAIT_ABANDONED")); + // fall through + case WAIT_OBJECT_0: // ok break; @@ -251,7 +264,6 @@ wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds) case WAIT_TIMEOUT: return wxMUTEX_TIMEOUT; - case WAIT_ABANDONED: // checked for above default: wxFAIL_MSG(wxT("impossible return value in wxMutex::Lock")); // fall through @@ -261,11 +273,20 @@ wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds) return wxMUTEX_MISC_ERROR; } + if (m_type == wxMUTEX_DEFAULT) + { + // required for checking recursiveness + m_owningThread = wxThread::GetCurrentId(); + } + return wxMUTEX_NO_ERROR; } wxMutexError wxMutexInternal::Unlock() { + // required for checking recursiveness + m_owningThread = 0; + if ( !::ReleaseMutex(m_mutex) ) { wxLogLastError(_T("ReleaseMutex()"));