|
//-- Thread.hpp --
/*--------------------------------------------------------------------------
Class Library
Copyrights Emad Barsoum 2002. All rights reserved.
________________________________________________________________
PROJECT : General
MODULE : CThread, TThread
FILENAME : Thread.hpp
REFERENCES: MSDN and ANSI/ISO C++ Professional Programmer's Handbook.
BUILD : 1
History of Modifications:
Date(dd/mm/yyyy)Person Description
---- ------ -----------
19/04/2002 Emad Barsoum Initial design and coding
23/04/2002 Emad Barsoum Update some member function
17/09/2002 Emad Barsoum Remove Constructor Parameter not needed
17/09/2002 Emad Barsoum Add the TThread class which is a template thread class
17/09/2002 Emad Barsoum Add m_nInitPriority
CLASS NAME: CThread, TThread
CLASS TYPE: NORMAL
DESCRIPTION:
Those are two standard threads class, that encapsulate all the thread
operation.
*/
#if !defined INC_THREAD_HPP
#define INC_THREAD_HPP
#include <Windows.h>
#include <process.h>
#include <assert.h>
namespace Thread
{
class CThread
{
public:
//-- The constructor --
CThread(int nPriority = THREAD_PRIORITY_NORMAL);
//-- Wait until the thread terminate, after this function you are sure that the thread is terminated.
bool WaitUntilTerminate(DWORD dwMiliSec = INFINITE);
//-- Start the thread or recreate it, if it has been terminated before --
bool Start();
//-- Start the thread and return when it actualy start --
bool StartAndWait();
//-- Pause the thread --
bool Pause();
//-- Check if the thread is running or not.
bool IsRunning();
//-- check if the thread has been terminated or not.
bool IsTerminated();
//-- Check for the thread is suspend or not.
bool IsSuspend();
//-- Set thread priority
void SetPriority(int nLevel);
//-- Get thread priority
int GetPriority();
//-- Speed up thread execution - increase priority level
void SpeedUp();
//-- Slow down Thread execution - decrease priority level
void SlowDown();
//-- Terminate immediate the thread Unsafe.
void Terminate();
protected:
//-- put the initialization code here.
virtual void OnInitInstance(){}
//-- put the main code of the thread here.
virtual void OnRunning() = 0; //-- Must be overloaded --
//-- put the cleanup code here.
virtual DWORD OnExitInstance(){return 0;}
//-- Exit the thread safety.
void Exit();
//-- Thread function --
static unsigned __stdcall _ThreadProc(LPVOID lpParameter);
//-- Destructor --
virtual ~CThread()
{
::CloseHandle(m_hEvent);
}
protected:
HANDLE m_hThread, m_hEvent; //-- Thread and Event handle --
int m_nInitPriority;
unsigned int m_dwThreadID; //-- Contain the thread ID --
//-- Variable to know the state of the thread terminated or suspend or Running --
bool m_bTerminate, m_bSuspend, m_bIsRunning;
};
/////////////////////////////////////////////////////////////////////////////
//-- End of CThread Class Definition --
//-- Begin of TThread declaration --
template<typename T>
class TThread
{
public:
//-- The constructor --
TThread(T& thObject, void (T::*pfnOnRunning)(), int nPriority = THREAD_PRIORITY_NORMAL);
//-- Wait until the thread terminate, after this function you are sure that the thread is terminated.
bool WaitUntilTerminate(DWORD dwMiliSec = INFINITE);
//-- Start the thread or recreate it, if it has been terminated before --
bool Start();
//-- Start the thread and return when it actualy start --
bool StartAndWait();
//-- Pause the thread --
bool Pause();
//-- Check if the thread is running or not.
bool IsRunning();
//-- check if the thread has been terminated or not.
bool IsTerminated();
//-- Check for the thread is suspend or not.
bool IsSuspend();
//-- Set thread priority
void SetPriority(int nLevel);
//-- Get thread priority
int GetPriority();
//-- Speed up thread execution - increase priority level
void SpeedUp();
//-- Slow down Thread execution - decrease priority level
void SlowDown();
//-- Terminate immediate the thread Unsafe.
void Terminate();
//-- Destructor
virtual ~TThread()
{
::CloseHandle(m_hEvent);
}
protected:
//-- Thread function --
static unsigned __stdcall _ThreadProc(LPVOID lpParameter);
//-- Exit the thread safety.
void Exit();
//-- Call the running member function --
inline void OnRunning();
protected:
T& m_thObject; //-- The thread object --
void (T::*m_pfnOnRunning)();
HANDLE m_hThread, m_hEvent; //-- Thread and Event handle --
int m_nInitPriority;
unsigned int m_dwThreadID; //-- Contain the thread ID --
//-- Variable to know the state of the thread terminated or suspend or Running --
bool m_bTerminate, m_bSuspend, m_bIsRunning;
};
/////////////////////////////////////////////////////////////////////////////
//-- End of TThread Class Declaration --
//-- Begin TThread Implementation --
template<typename T> TThread<T>::TThread(T& thObject,void (T::*pfnOnRunning)(), int nPriority):m_thObject(thObject),m_pfnOnRunning(pfnOnRunning)
{
m_hThread = NULL;
m_dwThreadID = 0;
m_bTerminate = true;
m_bSuspend = true;
m_bIsRunning = false;
m_nInitPriority = nPriority;
m_hEvent = ::CreateEvent(NULL,FALSE,FALSE,NULL);
}
template<typename T> bool TThread<T>::Start()
{
if(m_bTerminate)
{
m_hThread = (HANDLE)_beginthreadex(NULL,0,_ThreadProc,(LPVOID)this,0/* CREATE_SUSPENDED*/,&m_dwThreadID);
m_bTerminate = false;
m_bSuspend = false;
if(m_hThread != 0)
return true;
return false;
}
else if(m_bSuspend)
{
DWORD nRet = ::ResumeThread(m_hThread);
if(nRet == 0xFFFFFFFF)
return false;
m_bSuspend = false;
return true;
}
return true;
}
template<typename T> bool TThread<T>::StartAndWait()
{
bool bRet = Start();
if(bRet)
::WaitForSingleObject(m_hEvent,INFINITE);
return bRet;
}
template<typename T> bool TThread<T>::Pause()
{
if(m_bTerminate)
return false;
if(m_bSuspend)
return true;
DWORD nRet = ::SuspendThread(m_hThread);
if(nRet == 0xFFFFFFFF)
return false;
m_bSuspend = true;
return true;
}
template<typename T> bool TThread<T>::IsRunning()
{
return m_bIsRunning;
}
template<typename T> bool TThread<T>::IsTerminated()
{
return m_bTerminate;
}
template<typename T> bool TThread<T>::IsSuspend()
{
return m_bSuspend;
}
template<typename T> void TThread<T>::Terminate()
{
DWORD dwExitCode;
::GetExitCodeThread(m_hThread,&dwExitCode);
if (STILL_ACTIVE == dwExitCode)
{
::TerminateThread(m_hThread,dwExitCode);
::CloseHandle(m_hThread);
m_hThread = NULL;
}
m_bIsRunning = false;
m_bTerminate = true;
}
template<typename T> void TThread<T>::Exit()
{
DWORD dwExitCode;
::GetExitCodeThread(m_hThread,&dwExitCode);
if (STILL_ACTIVE == dwExitCode)
{
_endthreadex(dwExitCode);
::ExitThread(dwExitCode);
::CloseHandle(m_hThread);
m_hThread = NULL;
}
m_bIsRunning = false;
m_bTerminate = true;
}
template<typename T> bool TThread<T>::WaitUntilTerminate(DWORD dwMiliSec)
{
if(WaitForSingleObject(m_hThread,dwMiliSec) == WAIT_TIMEOUT)
return false;
m_bIsRunning = false;
m_bTerminate = true;
return true;
}
template<typename T> void TThread<T>::SetPriority(int nLevel)
{
::SetThreadPriority(m_hThread,nLevel);
}
template<typename T> int TThread<T>::GetPriority()
{
return ::GetThreadPriority(m_hThread);
}
template<typename T> void TThread<T>::SpeedUp()
{
int nOldLevel;
int nNewLevel;
nOldLevel = GetPriority();
if (THREAD_PRIORITY_TIME_CRITICAL == nOldLevel)
return;
else if (THREAD_PRIORITY_HIGHEST == nOldLevel)
nNewLevel = THREAD_PRIORITY_TIME_CRITICAL;
else if (THREAD_PRIORITY_ABOVE_NORMAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_HIGHEST;
else if (THREAD_PRIORITY_NORMAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_ABOVE_NORMAL;
else if (THREAD_PRIORITY_BELOW_NORMAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_NORMAL;
else if (THREAD_PRIORITY_LOWEST == nOldLevel)
nNewLevel = THREAD_PRIORITY_BELOW_NORMAL;
else if (THREAD_PRIORITY_IDLE == nOldLevel)
nNewLevel = THREAD_PRIORITY_LOWEST;
SetPriority(nNewLevel);
}
template<typename T> void TThread<T>::SlowDown()
{
int nOldLevel;
int nNewLevel;
nOldLevel = GetPriority();
if (THREAD_PRIORITY_TIME_CRITICAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_HIGHEST;
else if (THREAD_PRIORITY_HIGHEST == nOldLevel)
nNewLevel = THREAD_PRIORITY_ABOVE_NORMAL;
else if (THREAD_PRIORITY_ABOVE_NORMAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_NORMAL;
else if (THREAD_PRIORITY_NORMAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_BELOW_NORMAL;
else if (THREAD_PRIORITY_BELOW_NORMAL == nOldLevel)
nNewLevel = THREAD_PRIORITY_LOWEST;
else if (THREAD_PRIORITY_LOWEST == nOldLevel)
nNewLevel = THREAD_PRIORITY_IDLE;
else if (THREAD_PRIORITY_IDLE == nOldLevel)
return;
SetPriority(nNewLevel);
}
template<typename T> void TThread<T>::OnRunning()
{
(m_thObject.*m_pfnOnRunning)();
}
template<typename T> unsigned __stdcall TThread<T>::_ThreadProc(LPVOID lpParameter)
{
TThread<T>* pThread = reinterpret_cast<TThread<T>*>(lpParameter);
pThread->SetPriority(pThread->m_nInitPriority);
pThread->m_bIsRunning = true;
::SetEvent(pThread->m_hEvent);
pThread->OnRunning();
return 0;
}
};
#endif //-- INC_THREAD_HPP
//-- End of Thread.hpp --
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.