|
#if !defined(_EXITABLETHREAD_H_)
#define _EXITABLETHREAD_H_
#include "Thread.h"
namespace Lib
{
// --------------------------------------------
// ExitableThread class
// --------------------------------------------
template<class T, class P>
class ExitableThread : public Thread<T, P>
{
public:
typedef void (T::*ThreadFunc)( P );
ExitableThread();
virtual ~ExitableThread();
// ExitThread methods - Called within the context of an
// external thread to instruct the embedded (running)
// thread to exit.
//
// ExitThread() - Signals the event and immediately
// returns.
//
// ExitThreadAndWait() - Signals the event and waits
// until the thread actually exits or the timeout
// expires. Returns true if the thread exited, or
// false if the timeout expired
void ExitThread();
bool ExitThreadAndWait( DWORD timeoutMS = 5000 );
// IsExitEventSet - Called by the embedded (running)
// thread to test if the exit event is set. Returns
// true if the event has been set, and the thread
// should exit, and false otherwise
bool IsExitEventSet();
protected:
// Handle to the Exit Event
HANDLE m_hExitThreadEvent;
};
// ------------------------------------------------------
template<class T, class P>
ExitableThread<T, P>::ExitableThread()
: m_hExitThreadEvent( NULL )
{
// Create the Exit Event - Should the args to CreateEvent be
// customizable? What should be done if CreateEvent() fails?
// NOTE: Since we will have only one consumer of the exit event,
// it is safe to make the event an auto-reset event
m_hExitThreadEvent = ::CreateEvent( NULL, false, false, NULL );
}
// ------------------------------------------------------
template<class T, class P>
ExitableThread<T, P>::~ExitableThread()
{
if ( m_hExitThreadEvent )
{
::CloseHandle( m_hExitThreadEvent );
m_hExitThreadEvent = NULL;
}
}
// ------------------------------------------------------
template<class T, class P>
void ExitableThread<T, P>::ExitThread()
{
::SetEvent( m_hExitThreadEvent );
}
// ------------------------------------------------------
template<class T, class P>
bool ExitableThread<T, P>::ExitThreadAndWait( DWORD timeoutMS )
{
// Set the event telling the thread to exit
::SetEvent( m_hExitThreadEvent );
// Wait for the thread to actually exit
DWORD result = ::WaitForSingleObject( m_hThread, timeoutMS );
// Cleanup handle
::CloseHandle( m_hThread );
m_hThread = NULL;
return ( result == WAIT_OBJECT_0 );
}
// ------------------------------------------------------
template<class T, class P>
bool ExitableThread<T, P>::IsExitEventSet()
{
DWORD res = ::WaitForSingleObject( m_hExitThreadEvent, 0 );
return ( res == WAIT_OBJECT_0 );
}
}
#endif
|
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.