windows-nt/Source/XPSP1/NT/sdktools/debuggers/excepmon/include/genthread.h
2020-09-26 16:20:57 +08:00

176 lines
3.8 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// Module : Common
// Description : Generic Thread Base class
// Uses Win32 SEH
//
// File : genthread.h
// Author : kulor
// Date : 05/18/2000
//
// History :
//
///////////////////////////////////////////////////////////////////////////
#pragma once
///////////////////////////////////////////////////////////////////////////
//
// class CGenThread
//
// Usage : 1) Derive from this class and implement the Run method.
// 2) Use the IsStopRequested appropriately.
//
//
typedef class CGenThread {
public:
CGenThread (bool fStart = false) {
m_hGenThread = NULL;
m_dwThreadId = 0;
m_hGenStopEvent = ::CreateEvent (
NULL,
true,
false,
NULL
);
if ( fStart ) {
Start ();
}
}
virtual ~CGenThread () {
CleanupThread ();
}
DWORD GetThreadId ( void ) { return m_dwThreadId ; }
DWORD Start ( DWORD dwCreateFlags = 0 ) {
DWORD dwRet = FALSE;
if ( !fOkToRun () || IsValidThread () )
return FALSE;
// de-signal the event
::ResetEvent ( m_hGenStopEvent );
m_hGenThread = ::CreateThread (
NULL,
0,
GenThreadProc,
reinterpret_cast <void*>(this),
0,
&m_dwThreadId
);
dwRet = ( m_hGenThread ? 0 : GetLastError() );
return dwRet;
}
DWORD Stop ( void ) {
if ( IsValidThread () == FALSE )
return FALSE;
// signal the thread
::SetEvent ( m_hGenStopEvent );
// now wait for it to stop
DWORD dwRet = ::WaitForSingleObject ( m_hGenThread , INFINITE );
CleanupThread ();
return dwRet;
}
DWORD Pause ( void ) {
if ( IsValidThread() == FALSE )
return FALSE;
::SuspendThread ( m_hGenThread );
return GetLastError ();
}
DWORD Resume ( void ) {
if ( IsValidThread() == FALSE )
return FALSE;
::ResumeThread ( m_hGenThread );
return GetLastError ();
}
bool IsStopRequested ( void ) {
bool fVal = false;
fVal = ( ::WaitForSingleObject ( m_hGenStopEvent, 0 ) == WAIT_OBJECT_0 );
return (fVal);
}
virtual DWORD Run ( void ) = 0 ;
bool IsValidThread ( void ) {
return ( m_hGenThread != NULL );
}
protected:
void CleanupThread ( void ) {
m_dwThreadId = 0;
if ( m_hGenStopEvent ) {
::CloseHandle ( m_hGenStopEvent );
m_hGenStopEvent = NULL;
}
if ( m_hGenThread ) {
::CloseHandle ( m_hGenThread );
m_hGenThread = NULL;
}
}
virtual bool fOkToRun( void ) {
return ( m_hGenStopEvent != NULL );
}
static DWORD WINAPI GenThreadProc(
LPVOID lpParameter
)
{
CGenThread *pGenThread = reinterpret_cast<CGenThread*> (lpParameter);
DWORD dwRet = 0;
if ( pGenThread ) {
__try {
dwRet = pGenThread->Run ();
}
__except ( EXCEPTION_EXECUTE_HANDLER, 1 ) {
// wireup crash info
}
{
pGenThread->CleanupThread ();
}
}
return dwRet;
}
protected:
HANDLE m_hGenStopEvent;
HANDLE m_hGenThread;
DWORD m_dwThreadId;
} CGenThread, GENTHREAD, *PGENTHREAD;