98 lines
2.9 KiB
C++
98 lines
2.9 KiB
C++
|
|
#include "stdafx.h"
|
|||
|
|
#include "SafeThread.h"
|
|||
|
|
#include <stdexcept>
|
|||
|
|
#include <map>
|
|||
|
|
|
|||
|
|
// RoutineInfo <20><>¼<EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ.
|
|||
|
|
typedef struct RoutineInfo
|
|||
|
|
{
|
|||
|
|
DWORD tid; // <20>߳<EFBFBD>ID
|
|||
|
|
|
|||
|
|
LPTHREAD_START_ROUTINE Func; // <20>̺߳<DFB3><CCBA><EFBFBD>
|
|||
|
|
LPVOID Param; // <20>̲߳<DFB3><CCB2><EFBFBD>
|
|||
|
|
|
|||
|
|
OnException Excep; // <20>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
LPVOID User; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
std::string File; // <20><><EFBFBD><EFBFBD><EFBFBD>̵߳<DFB3><CCB5>ļ<EFBFBD>
|
|||
|
|
int Line; // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
std::string Name; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
bool Trace; // <><D7B7><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
}RoutineInfo;
|
|||
|
|
|
|||
|
|
DWORD HandleCppException(RoutineInfo& ri) {
|
|||
|
|
try {
|
|||
|
|
return ri.Func(ri.Param); // <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>
|
|||
|
|
}
|
|||
|
|
catch (const std::exception& e) {
|
|||
|
|
if (ri.Excep) {
|
|||
|
|
Mprintf("[%d] <20><><EFBFBD><EFBFBD> C++ <20>쳣: %s. [%s:%d]\n", ri.tid, e.what(), ri.File.c_str(), ri.Line);
|
|||
|
|
return ri.Excep(ri.User, ri.Param);
|
|||
|
|
}
|
|||
|
|
Mprintf("[%d] <20><><EFBFBD><EFBFBD> C++ <20>쳣: %s. û<><C3BB><EFBFBD>ṩ<EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[%s:%d]!\n", ri.tid, e.what(), ri.File.c_str(), ri.Line);
|
|||
|
|
}
|
|||
|
|
catch (...) {
|
|||
|
|
if (ri.Excep) {
|
|||
|
|
Mprintf("[%d] <20><><EFBFBD><EFBFBD>δ֪ C++ <20>쳣. [%s:%d]\n", ri.tid, ri.File.c_str(), ri.Line);
|
|||
|
|
return ri.Excep(ri.User, ri.Param);
|
|||
|
|
}
|
|||
|
|
Mprintf("[%d] <20><><EFBFBD><EFBFBD>δ֪ C++ <20>쳣. û<><C3BB><EFBFBD>ṩ<EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[%s:%d]!\n", ri.tid, ri.File.c_str(), ri.Line);
|
|||
|
|
}
|
|||
|
|
return 0xDEAD0002;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DWORD HandleSEHException(RoutineInfo & ri) {
|
|||
|
|
__try {
|
|||
|
|
// ִ<><D6B4>ʵ<EFBFBD><CAB5><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>
|
|||
|
|
return HandleCppException(ri);
|
|||
|
|
}
|
|||
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
|
if (ri.Excep) {
|
|||
|
|
Mprintf("[%d] <20><><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD>̲߳<DFB3><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. [%s:%d] Code=%08X\n", ri.tid, ri.File.c_str(), ri.Line, GetExceptionCode());
|
|||
|
|
return ri.Excep(ri.User, ri.Param);
|
|||
|
|
}
|
|||
|
|
Mprintf("[%d] <20><><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>쳣. û<><C3BB><EFBFBD>ṩ<EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[%s:%d]! Code=%08X\n", ri.tid, ri.File.c_str(), ri.Line, GetExceptionCode());
|
|||
|
|
return 0xDEAD0001; // <20><><EFBFBD>ش<EFBFBD><D8B4><EFBFBD>״̬
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ͨ<><CDA8><EFBFBD>쳣<EFBFBD><ECB3A3>װ<EFBFBD><D7B0><EFBFBD><EFBFBD>
|
|||
|
|
DWORD WINAPI ThreadWrapper(LPVOID lpParam) {
|
|||
|
|
RoutineInfo *ri = (RoutineInfo *)lpParam;
|
|||
|
|
ri->tid = GetCurrentThreadId();
|
|||
|
|
RoutineInfo pRealThreadFunc = *ri;
|
|||
|
|
delete ri;
|
|||
|
|
|
|||
|
|
if (pRealThreadFunc.Trace)
|
|||
|
|
{
|
|||
|
|
CAutoLog Log(pRealThreadFunc.Name.c_str());
|
|||
|
|
// <20>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD>
|
|||
|
|
return HandleSEHException(pRealThreadFunc);
|
|||
|
|
}
|
|||
|
|
// <20>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD>
|
|||
|
|
return HandleSEHException(pRealThreadFunc);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3><CCA3><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>̵߳<DFB3><CCB5>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD><CDBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
HANDLE CreateSafeThread(const char*file, int line, const char* fname, OnException excep, LPVOID user, SIZE_T dwStackSize,
|
|||
|
|
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) {
|
|||
|
|
|
|||
|
|
if (excep) assert(user); // <20>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<CDAC>ṩ
|
|||
|
|
if (excep && !user) {
|
|||
|
|
Mprintf("[ERROR] <20>ṩ<EFBFBD><E1B9A9><EFBFBD>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> user Ϊ NULL, <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>[%s:%d]!\n", file, line);
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
auto ri = new RoutineInfo{ 0, lpStartAddress, lpParameter, excep, user, file ? file : "", line, fname, dwStackSize == 0 };
|
|||
|
|
|
|||
|
|
HANDLE hThread = ::CreateThread(NULL, dwStackSize, ThreadWrapper, ri, dwCreationFlags, lpThreadId);
|
|||
|
|
if (!hThread) {
|
|||
|
|
Mprintf("[ERROR] <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>GetLastError=%lu [%s:%d]\n", GetLastError(), file, line);
|
|||
|
|
delete ri;
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return hThread;
|
|||
|
|
}
|