X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3f49efdba9f219752121353c9430aabb6d679cf0..c084a1ac064cff672b777e1e6a3624fd838387e7:/src/msw/thread.cpp diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 942a0379da..2a692e374d 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -75,8 +75,9 @@ // this is where _beginthreadex() is declared #include - // the return type of the thread function entry point - typedef wxUIntPtr THREAD_RETVAL; + // the return type of the thread function entry point: notice that this + // type can't hold a pointer under Win64 + typedef unsigned THREAD_RETVAL; // the calling convention of the thread function entry point #define THREAD_CALLCONV __stdcall @@ -144,7 +145,7 @@ static bool gs_waitingForThread = false; // wxCriticalSection // ---------------------------------------------------------------------------- -wxCriticalSection::wxCriticalSection() +wxCriticalSection::wxCriticalSection( wxCriticalSectionType WXUNUSED(critSecType) ) { wxCOMPILE_TIME_ASSERT( sizeof(CRITICAL_SECTION) <= sizeof(wxCritSectBuffer), wxCriticalSectionBufferTooSmall ); @@ -189,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 @@ -203,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() @@ -230,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; @@ -250,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 @@ -260,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()")); @@ -528,7 +550,7 @@ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread) return THREAD_ERROR_EXIT; } - rc = (THREAD_RETVAL)thread->Entry(); + rc = wxPtrToUInt(thread->Entry()); } wxCATCH_ALL( wxTheApp->OnUnhandledException(); ) @@ -916,11 +938,6 @@ void wxThread::Yield() ::Sleep(0); } -void wxThread::Sleep(unsigned long milliseconds) -{ - ::Sleep(milliseconds); -} - int wxThread::GetCPUCount() { SYSTEM_INFO si; @@ -1097,7 +1114,7 @@ wxThreadError wxThread::Resume() wxThread::ExitCode wxThread::Wait() { - ExitCode rc = (ExitCode)THREAD_ERROR_EXIT; + ExitCode rc = wxUIntToPtr(THREAD_ERROR_EXIT); // although under Windows we can wait for any thread, it's an error to // wait for a detached one in wxWin API