Made wxMSW wxMutex non-recursive by checking reentrance
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55469 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -860,7 +860,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
enum wxMutexType
|
enum wxMutexType
|
||||||
{
|
{
|
||||||
/** Normal mutex: try to always use this one. Recursive under Windows. */
|
/** Normal non-recursive mutex: try to always use this one. */
|
||||||
wxMUTEX_DEFAULT,
|
wxMUTEX_DEFAULT,
|
||||||
|
|
||||||
/** Recursive mutex: don't use these ones with wxCondition. */
|
/** Recursive mutex: don't use these ones with wxCondition. */
|
||||||
@@ -909,9 +909,9 @@ enum wxMutexError
|
|||||||
had already locked before (instead of dead locking the entire process in this
|
had already locked before (instead of dead locking the entire process in this
|
||||||
situation by starting to wait on a mutex which will never be released while the
|
situation by starting to wait on a mutex which will never be released while the
|
||||||
thread is waiting) but using them is not recommended under Unix and they are
|
thread is waiting) but using them is not recommended under Unix and they are
|
||||||
@b not recursive there by default. The reason for this is that recursive
|
@b not recursive by default. The reason for this is that recursive
|
||||||
mutexes are not supported by all Unix flavours and, worse, they cannot be used
|
mutexes are not supported by all Unix flavours and, worse, they cannot be used
|
||||||
with wxCondition. On the other hand, Win32 mutexes are always recursive.
|
with wxCondition.
|
||||||
|
|
||||||
For example, when several threads use the data stored in the linked list,
|
For example, when several threads use the data stored in the linked list,
|
||||||
modifications to the list should only be allowed to one thread at a time
|
modifications to the list should only be allowed to one thread at a time
|
||||||
|
@@ -190,11 +190,15 @@ private:
|
|||||||
|
|
||||||
HANDLE m_mutex;
|
HANDLE m_mutex;
|
||||||
|
|
||||||
|
unsigned long m_owningThread;
|
||||||
|
bool m_isLocked;
|
||||||
|
wxMutexType m_type;
|
||||||
|
|
||||||
DECLARE_NO_COPY_CLASS(wxMutexInternal)
|
DECLARE_NO_COPY_CLASS(wxMutexInternal)
|
||||||
};
|
};
|
||||||
|
|
||||||
// all mutexes are recursive under Win32 so we don't use mutexType
|
// 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
|
// create a nameless (hence intra process and always private) mutex
|
||||||
m_mutex = ::CreateMutex
|
m_mutex = ::CreateMutex
|
||||||
@@ -204,10 +208,15 @@ wxMutexInternal::wxMutexInternal(wxMutexType WXUNUSED(mutexType))
|
|||||||
NULL // no name
|
NULL // no name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
m_type = mutexType;
|
||||||
|
m_owningThread = 0;
|
||||||
|
m_isLocked = false;
|
||||||
|
|
||||||
if ( !m_mutex )
|
if ( !m_mutex )
|
||||||
{
|
{
|
||||||
wxLogLastError(_T("CreateMutex()"));
|
wxLogLastError(_T("CreateMutex()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMutexInternal::~wxMutexInternal()
|
wxMutexInternal::~wxMutexInternal()
|
||||||
@@ -231,6 +240,16 @@ wxMutexError wxMutexInternal::TryLock()
|
|||||||
|
|
||||||
wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds)
|
wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds)
|
||||||
{
|
{
|
||||||
|
if (m_type == wxMUTEX_DEFAULT)
|
||||||
|
{
|
||||||
|
// Don't allow recursive
|
||||||
|
if (m_isLocked)
|
||||||
|
{
|
||||||
|
if (m_owningThread == wxThread::GetCurrentId())
|
||||||
|
return wxMUTEX_DEAD_LOCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DWORD rc = ::WaitForSingleObject(m_mutex, milliseconds);
|
DWORD rc = ::WaitForSingleObject(m_mutex, milliseconds);
|
||||||
if ( rc == WAIT_ABANDONED )
|
if ( rc == WAIT_ABANDONED )
|
||||||
{
|
{
|
||||||
@@ -261,6 +280,13 @@ wxMutexError wxMutexInternal::LockTimeout(DWORD milliseconds)
|
|||||||
return wxMUTEX_MISC_ERROR;
|
return wxMUTEX_MISC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_type == wxMUTEX_DEFAULT)
|
||||||
|
{
|
||||||
|
// required for checking recursiveness
|
||||||
|
m_isLocked = true;
|
||||||
|
m_owningThread = wxThread::GetCurrentId();
|
||||||
|
}
|
||||||
|
|
||||||
return wxMUTEX_NO_ERROR;
|
return wxMUTEX_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +299,9 @@ wxMutexError wxMutexInternal::Unlock()
|
|||||||
return wxMUTEX_MISC_ERROR;
|
return wxMUTEX_MISC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// required for checking recursiveness
|
||||||
|
m_isLocked = false;
|
||||||
|
|
||||||
return wxMUTEX_NO_ERROR;
|
return wxMUTEX_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user