- CriticalSection 의 Enter, Leave 를 지역변수로 선언하여 데드락을 피하는 클래스
1.
CRITICAL_SECTION의 기능형 클래스
#pragma once
class CCriticalSection
{
public:
CCriticalSection(VOID)
{
InitializeCriticalSection(&mSync);
}
~CCriticalSection(VOID)
{
DeleteCriticalSection(&mSync);
}
inline VOID Enter(VOID)
{
EnterCriticalSection(&mSync);
}
inline VOID Leave(VOID)
{
LeaveCriticalSection(&mSync);
}
private:
CRITICAL_SECTION mSync;
};
2. Enter, Leave를 지역변수화.
#pragma once
template <class T>
class CMultiThreadSync
{
friend class CThreadSync;
public:
class CThreadSync
{
public:
CThreadSync(VOID)
{
T::mSync.Enter();
}
~CThreadSync(VOID)
{
T::mSync.Leave();
}
};
private:
static CCriticalSection mSync;
};
template <class T>
CCriticalSection CMultiThreadSync<T>::mSync;
#pragma once
template <class T, int ALLOC_BLOCK_SIZE = 50>
class CMemoryPool : public CMultiThreadSync<T>
{
public:
static VOID* operator new(std::size_t allocLength)
{
CThreadSync Sync;
assert(sizeof(T) == allocLength);
assert(sizeof(T) >= sizeof(UCHAR*));
if (!mFreePointer)
allocBlock();
UCHAR *ReturnPointer = mFreePointer;
mFreePointer = *reinterpret_cast<UCHAR**>(ReturnPointer);
return ReturnPointer;
}
static VOID operator delete(VOID* deletePointer)
{
CThreadSync Sync;
*reinterpret_cast<UCHAR**>(deletePointer) = mFreePointer;
mFreePointer = static_cast<UCHAR*>(deletePointer);
}
private:
static VOID allocBlock()
{
mFreePointer = new UCHAR[sizeof(T) * ALLOC_BLOCK_SIZE];
UCHAR **Current = reinterpret_cast<UCHAR **>(mFreePointer);
UCHAR *Next = mFreePointer;
for (INT i=0;i<ALLOC_BLOCK_SIZE-1;++i)
{
Next += sizeof(T);
*Current = Next;
Current = reinterpret_cast<UCHAR**>(Next);
}
*Current = 0;
}
private:
static UCHAR *mFreePointer;
protected:
~CMemoryPool()
{
}
};
template <class T, int ALLOC_BLOCK_SIZE>
UCHAR* CMemoryPool<T, ALLOC_BLOCK_SIZE>::mFreePointer;