📄 sehmgr.cpp
字号:
//
// FILE: SEHMgr.cpp
//
// Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring
//
/////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#include <CGuardedThreadHandler.h>
#include <CMclWaitableCollection.h>
#include "SynchExceptionMgr.h"
#include "AsynchExceptionMgr.h"
// USE_SYNCH_EXCEPTION_MGR is used to control whether or not this
// application uses the synchronous form of the exception manager
// (CSynchronousExceptionManager) or the asynchronous form
// (CAsynchronousExceptionManager). Because both are derived from
// the CExceptionManager base class, the remainder of this application
// doesn't differentiate between them.
//
#define USE_SYNCH_EXCEPTION_MGR 1 // 1 => Use CSynchronousExceptionManager
// 0 => Use CAsynchronousExceptionManager
#if USE_SYNCH_EXCEPTION_MGR
CSynchronousExceptionManager gExceptMgr;
#else
CAsynchronousExceptionManager gExceptMgr;
#endif
// CWorkerThreadHandler
//
// Defines a worker thread that registers itself with an exception manager
// object when the thread starts, and notifies the exception manager object
// whenever an exception that it can't handle occurs in this thread.
//
class CWorkerThreadHandler : public CGuardedThreadHandler, public CExceptionHandler
{
public:
// Class constructor.
CWorkerThreadHandler( BOOL fBlowUp, CExceptionManager *pEM );
// CGuardedThreadHandler overrides.
//
virtual unsigned GuardedThreadHandlerProc( void );
virtual unsigned TerminationHandler( DWORD dwExceptionCode );
// CExceptionHandler override. This will be called if an exception
// occurs anywhere else in the program so that we can clean up before
// the program exits.
//
virtual void OnException
(
CExceptionHandler::NOTIFICATION_CONTEXT Context,
DWORD dwExceptionCode
);
private:
CExceptionManager *m_pEM;
BOOL m_fBlowUp;
};
// CWorkerThreadHandler implementation.
//
CWorkerThreadHandler::CWorkerThreadHandler( BOOL fBlowUp, CExceptionManager *pEM )
: m_pEM(pEM),
m_fBlowUp(fBlowUp)
{
}
unsigned CWorkerThreadHandler::GuardedThreadHandlerProc( void )
{
// Register with the exception manager.
//
m_pEM->RegisterHandler(this);
printf(
"[tid 0x%08lx] Worker thread has started (m_fBlowUp == %d).\n",
GetCurrentThreadId(),
m_fBlowUp
);
for( int i = 0; i < 3; i++ )
{
printf(
"[tid 0x%08lx] Worker about to sleep...\n",
GetCurrentThreadId()
);
Sleep(4000);
if( (i == 1) && m_fBlowUp )
{
printf(
"[tid 0x%08lx] Worker about to blow up (handler = 0x%x).\n",
GetCurrentThreadId(),
(CExceptionHandler *)this
);
*((PBYTE)0) = '!';
}
printf(
"[tid 0x%08lx] Worker done sleeping.\n",
GetCurrentThreadId()
);
}
printf(
"[tid 0x%08lx] Worker thread exiting thread proc normally.\n",
GetCurrentThreadId()
);
// Unregister with the exception manager just before allowing
// this thread to exit.
//
m_pEM->UnregisterHandler(this);
return(0);
}
unsigned CWorkerThreadHandler::TerminationHandler( DWORD dwExceptionCode )
{
printf(
"[tid 0x%08lx] Worker termination handler (0x%x) running, exception = 0x%x\n",
GetCurrentThreadId(),
(CExceptionHandler *)this,
dwExceptionCode
);
// Notify other threads that we're about to exit the process.
//
m_pEM->UnregisterHandler(this);
m_pEM->NotifyException(dwExceptionCode);
ExitProcess(0xffffffff);
return(0);
}
void CWorkerThreadHandler::OnException
(
CExceptionHandler::NOTIFICATION_CONTEXT Context,
DWORD dwExceptionCode
)
{
printf(
"[tid 0x%08lx] Worker handler 0x%x OnException(%s exception = 0x%x)\n",
GetCurrentThreadId(),
(CExceptionHandler *)this,
(Context == CExceptionHandler::THREAD_EXCEPTION ? "thread" : "unhandled"),
dwExceptionCode
);
}
// Program implementation.
//
void main( void )
{
CWorkerThreadHandler WorkerHandler1(FALSE, &gExceptMgr); // This thread won't fault.
CMclThread WorkerThread1(&WorkerHandler1);
CWorkerThreadHandler WorkerHandler2(TRUE, &gExceptMgr); // This thread will fault out.
CMclThread WorkerThread2(&WorkerHandler2);
CWorkerThreadHandler WorkerHandler3(FALSE, &gExceptMgr); // This thread won't fault.
CMclThread WorkerThread3(&WorkerHandler3);
#if USE_SYNCH_EXCEPTION_MGR
printf(
"[tid 0x%08lx] Synchronous exception manager is being used.\n",
GetCurrentThreadId()
);
#else
printf(
"[tid 0x%08lx] Asynchronous exception manager is being used.\n",
GetCurrentThreadId()
);
#endif
printf(
"[tid 0x%08lx] Waiting for worker threads to exit...\n",
GetCurrentThreadId()
);
// Now that the three worker threads are running, wait for
// them to exit.
//
CMclWaitableCollection WaitSet;
WaitSet.AddObject(WorkerThread1);
WaitSet.AddObject(WorkerThread2);
WaitSet.AddObject(WorkerThread3);
WaitSet.Wait(TRUE, INFINITE);
printf(
"[tid 0x%08lx] Done waiting for workers to exit.\n",
GetCurrentThreadId()
);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -