73 lines
1.4 KiB
C
73 lines
1.4 KiB
C
|
class CTryableCriticalSection
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
CTryableCriticalSection();
|
||
|
~CTryableCriticalSection();
|
||
|
|
||
|
public:
|
||
|
|
||
|
void Lock();
|
||
|
void Unlock();
|
||
|
BOOL TryLock();
|
||
|
|
||
|
private:
|
||
|
|
||
|
BOOL TryLockPrivate(BOOL fTakeAlways);
|
||
|
|
||
|
private:
|
||
|
|
||
|
CRITICAL_SECTION m_csInner;
|
||
|
CRITICAL_SECTION m_csOuter;
|
||
|
LONG m_cRefs;
|
||
|
};
|
||
|
|
||
|
inline CTryableCriticalSection::CTryableCriticalSection()
|
||
|
{
|
||
|
InitializeCriticalSection(&m_csInner);
|
||
|
InitializeCriticalSection(&m_csOuter);
|
||
|
m_cRefs = 0;
|
||
|
}
|
||
|
|
||
|
inline CTryableCriticalSection::~CTryableCriticalSection()
|
||
|
{
|
||
|
DeleteCriticalSection(&m_csOuter);
|
||
|
DeleteCriticalSection(&m_csInner);
|
||
|
}
|
||
|
|
||
|
inline void CTryableCriticalSection::Lock()
|
||
|
{
|
||
|
TryLockPrivate(TRUE);
|
||
|
}
|
||
|
|
||
|
inline void CTryableCriticalSection::Unlock()
|
||
|
{
|
||
|
LeaveCriticalSection(&m_csInner);
|
||
|
|
||
|
InterlockedDecrement(&m_cRefs);
|
||
|
}
|
||
|
|
||
|
inline BOOL CTryableCriticalSection::TryLock()
|
||
|
{
|
||
|
return TryLockPrivate(FALSE);
|
||
|
}
|
||
|
|
||
|
inline BOOL CTryableCriticalSection::TryLockPrivate(BOOL fTakeAlways)
|
||
|
{
|
||
|
BOOL fLocked = FALSE;
|
||
|
|
||
|
EnterCriticalSection(&m_csOuter);
|
||
|
|
||
|
if (fTakeAlways || !m_cRefs)
|
||
|
{
|
||
|
fLocked = TRUE;
|
||
|
InterlockedIncrement(&m_cRefs);
|
||
|
|
||
|
EnterCriticalSection(&m_csInner);
|
||
|
}
|
||
|
|
||
|
LeaveCriticalSection(&m_csOuter);
|
||
|
|
||
|
return fLocked;
|
||
|
}
|