#ifndef CWORKERTHREAD_H
#define  CWORKERTHREAD_H

#include "stdafx.h"

class cWorkerThread
{
public:
	virtual bool	Init( const int nCPUId )
	{
		m_hEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL );
		if(m_hEvent == NULL)
			return false;

		InitializeCriticalSection( &m_csData );

		m_hThread = CreateThread(
			0,											//LPSECURITY_ATTRIBUTES lpThreadAttributes,
			0,											//SIZE_T dwStackSize,
			ThreadStart_Static,			//LPTHREAD_START_ROUTINE lpStartAddress,
			this,										//LPVOID lpParameter,
			0,											//DWORD dwCreationFlags,
			0);											//LPDWORD lpThreadId);

		SetThreadPriority(m_hThread,THREAD_PRIORITY_HIGHEST);

		return true;
	}

	virtual DWORD	Done()
	{
		if( IsRunning() )
		{
			SignalThreadClose();
			::WaitForSingleObject( m_hThread, INFINITE );
		}

		DWORD dwExitCode = 0;
		GetExitCodeThread(m_hThread, &dwExitCode);

		::CloseHandle( m_hThread );
		::CloseHandle( m_hEvent );
		DeleteCriticalSection( &m_csData );

		return dwExitCode;

	}

	bool	IsRunning()
	{
		return (::WaitForSingleObject(m_hEvent, 0) != WAIT_OBJECT_0 );
	}

	void EnterCS()
	{
		::EnterCriticalSection( &m_csData );
	}

	void LeaveCS()
	{
		::LeaveCriticalSection( &m_csData );
	}

	void SignalThreadClose()
	{
		::EnterCriticalSection( &m_csData );
		::SetEvent( m_hEvent );
		::LeaveCriticalSection( &m_csData );
	}

	virtual UINT ThreadStart()
	{
		return -1;
	}

	static DWORD WINAPI ThreadStart_Static(LPVOID lParam)
	{
		cWorkerThread *pThis = static_cast<cWorkerThread*>(lParam);
		if(pThis != NULL)
			return pThis->ThreadStart();
		else return -1;
	}

protected:
	HANDLE	m_hThread;
	HANDLE	m_hEvent;
	CRITICAL_SECTION	m_csData;
	//Data

};

#endif//CWORKERTHREAD_H