windows-nt/Source/XPSP1/NT/printscan/inc/psutil/simcrit.h
2020-09-26 16:20:57 +08:00

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