#pragma once

class ThreadSection
{
public:
	ThreadSection(){
		HRESULT hr = Init();
		(hr);
	}

	~ThreadSection(){
		DeleteCriticalSection(&_CriticalSection);
	}

	bool Lock()
	{
		bool result = false;
		__try
		{
			EnterCriticalSection(&_CriticalSection);
			result = true;
		}
		__except (STATUS_NO_MEMORY == GetExceptionCode())
		{
		}
		return result;
	}

	bool Unlock()
	{
		bool result = false;
		__try
		{
			LeaveCriticalSection(&_CriticalSection);
			result = true;
		}
		__except (STATUS_NO_MEMORY == GetExceptionCode())
		{
		}
		return result;
	}

private:
	HRESULT Init() throw()
	{
		HRESULT hRes = E_FAIL;
		__try
		{
			InitializeCriticalSection(&_CriticalSection);
			hRes = S_OK;
		}
		__except (STATUS_NO_MEMORY == GetExceptionCode())
		{
			hRes = E_OUTOFMEMORY;
		}
		return hRes;
	}

	ThreadSection(const ThreadSection & tSection);
	ThreadSection &operator=(const ThreadSection & tSection);
	CRITICAL_SECTION _CriticalSection;
};


class AutoThreadSection
{
public:
	AutoThreadSection(IN ThreadSection* pSection){
		_pSection = pSection;
		_pSection->Lock();
	}

	~AutoThreadSection(){
		_pSection->Unlock();
	}
private:
	AutoThreadSection(const AutoThreadSection & tSection);
	AutoThreadSection &operator=(const AutoThreadSection & tSection);
	ThreadSection * _pSection;
};
