140 lines
3.7 KiB
C++
140 lines
3.7 KiB
C++
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT MICROSOFT CORPORATION, 1998
|
|
*
|
|
* TITLE: SIMCRIT.H
|
|
*
|
|
* VERSION: 1.0
|
|
*
|
|
* AUTHOR: ShaunIv
|
|
*
|
|
* DATE: 9/6/1999
|
|
*
|
|
* DESCRIPTION: Simple critical section implementation. Note the hideous hack
|
|
* to get around the fact that many of our components don't use the CRT (so global
|
|
* and static classes don't have their constructors called. Ever.
|
|
* The solution is to link to MSVCRT.LIB and set _DllMainCRTStartup as the entry
|
|
* point in your DLL, instead of DllMain. The way this is coded is not thread safe.
|
|
* Two threads could call InitializeCriticalSection at the same time. If you setup
|
|
* your build as discussed above, this won't be a problem. Note that this hack only
|
|
* affects the use of this class when you have a GLOBAL or STATIC instance of a
|
|
* critical section.
|
|
*
|
|
*******************************************************************************/
|
|
#ifndef __SIMCRIT_H_INCLUDED
|
|
#define __SIMCRIT_H_INCLUDED
|
|
|
|
#include <windows.h>
|
|
|
|
class CSimpleCriticalSection
|
|
{
|
|
private:
|
|
CRITICAL_SECTION m_CriticalSection;
|
|
bool m_bInitCalled;
|
|
|
|
private:
|
|
//
|
|
// No implementation
|
|
//
|
|
CSimpleCriticalSection( const CSimpleCriticalSection & );
|
|
CSimpleCriticalSection &operator=( const CSimpleCriticalSection & );
|
|
|
|
public:
|
|
CSimpleCriticalSection(void)
|
|
: m_bInitCalled(false)
|
|
{
|
|
Initialize();
|
|
}
|
|
~CSimpleCriticalSection(void)
|
|
{
|
|
if (m_bInitCalled)
|
|
{
|
|
DeleteCriticalSection(&m_CriticalSection);
|
|
}
|
|
}
|
|
void Initialize(void)
|
|
{
|
|
if (!m_bInitCalled)
|
|
{
|
|
_try
|
|
{
|
|
InitializeCriticalSection(&m_CriticalSection);
|
|
m_bInitCalled = true;
|
|
}
|
|
_except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
#if defined(DBG)
|
|
OutputDebugString(TEXT("CSimpleCriticalSection::Initialize(), InitializeCriticalSection failed\n"));
|
|
DebugBreak();
|
|
#endif
|
|
m_bInitCalled = false;
|
|
}
|
|
}
|
|
}
|
|
void Enter(void)
|
|
{
|
|
if (!m_bInitCalled)
|
|
{
|
|
Initialize();
|
|
}
|
|
if (m_bInitCalled)
|
|
{
|
|
EnterCriticalSection(&m_CriticalSection);
|
|
}
|
|
}
|
|
void Leave(void)
|
|
{
|
|
if (m_bInitCalled)
|
|
{
|
|
LeaveCriticalSection(&m_CriticalSection);
|
|
}
|
|
}
|
|
CRITICAL_SECTION &cs(void)
|
|
{
|
|
return m_CriticalSection;
|
|
}
|
|
};
|
|
|
|
class CAutoCriticalSection
|
|
{
|
|
private:
|
|
PVOID m_pvCriticalSection;
|
|
bool m_bUsingPlainCriticalSection;
|
|
|
|
private:
|
|
// No implementation
|
|
CAutoCriticalSection(void);
|
|
CAutoCriticalSection( const CAutoCriticalSection & );
|
|
CAutoCriticalSection &operator=( const CAutoCriticalSection & );
|
|
|
|
public:
|
|
CAutoCriticalSection( CSimpleCriticalSection &criticalSection )
|
|
: m_pvCriticalSection(&criticalSection),
|
|
m_bUsingPlainCriticalSection(false)
|
|
{
|
|
reinterpret_cast<CSimpleCriticalSection*>(m_pvCriticalSection)->Enter();
|
|
}
|
|
CAutoCriticalSection( CRITICAL_SECTION &criticalSection )
|
|
: m_pvCriticalSection(&criticalSection),
|
|
m_bUsingPlainCriticalSection(true)
|
|
{
|
|
EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(m_pvCriticalSection));
|
|
}
|
|
~CAutoCriticalSection(void)
|
|
{
|
|
if (m_bUsingPlainCriticalSection)
|
|
{
|
|
LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(m_pvCriticalSection));
|
|
}
|
|
else
|
|
{
|
|
reinterpret_cast<CSimpleCriticalSection*>(m_pvCriticalSection)->Leave();
|
|
}
|
|
m_pvCriticalSection = NULL;
|
|
}
|
|
};
|
|
|
|
|
|
#endif //__SIMCRIT_H_INCLUDED
|
|
|