用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

246 lines
4.6 KiB

#include <windows.h>
#include <cassert>
#include "thread.h"
#include <interface\STaskLoop-i.h>
#include <process.h>
namespace SOUI
{
class ThreadPrivate
{
public:
ThreadPrivate():_hthread(NULL), _threadID(0)
{
}
HANDLE _hthread;
unsigned int _threadID;
};
const long Thread::INVALID_THREAD_ID = -1;
Thread::Thread() :
_stopping(false),
_runnable(NULL),
_name(),
_private(*(new ThreadPrivate())),
_start(false)
{
}
Thread::~Thread()
{
waitForStop();
delete &_private;
}
long Thread::getCurrentThreadID()
{
DWORD id = ::GetCurrentThreadId();
return (long) id;
}
bool Thread::start(IRunnable *runnable, const std::string &name, ThreadPriority priority)
{
assert(runnable);
{
SAutoLock autolock (_lock);
if (_start)
{
return false;
}
_stopping = false;
_runnable = runnable->clone();
_name = name;
_start = true;
_priorityLevel = priority;
_private._hthread = (HANDLE)_beginthreadex(NULL, 0, Thread::threadProcWin32thunk, this, 0, &_private._threadID);
if (_private._hthread == NULL)
{
clear();
return false;
}
setPriority(priority);
}
_startSem.wait(100);
return true;
}
void Thread::stop()
{
SAutoLock autolock (_lock);
if (!_start)
{
return;
}
_stopping = true;
}
void Thread::waitForStop()
{
// we must release lock before the wait function, to avoid deadlock
{
SAutoLock autolock (_lock);
if (!_start)
{
if ( _private._hthread )
{
::CloseHandle( _private._hthread); // resource must be released
_private._hthread = NULL;
_private._threadID = 0;
}
return;
}
}
DWORD ret = ::WaitForSingleObject(_private._hthread, INFINITE);
{
SAutoLock autolock (_lock);
if ( WAIT_OBJECT_0 == ret )
{
::CloseHandle( _private._hthread);
}
_private._hthread = NULL;
_private._threadID = 0;
}
if (WAIT_OBJECT_0 != 0)
{
}
}
bool Thread::isStopping()
{
SAutoLock autolock (_lock);
return _stopping;
}
bool Thread::isStopped()
{
SAutoLock autolock (_lock);
return _stopping || (!_start);
}
std::string Thread::getName()
{
SAutoLock autolock (_lock);
return _name;
}
// we have undocumented Win32 APIs to set thread name.
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
static void SetThreadName(DWORD dwThreadID, const char *threadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable: 6320 6322)
__try
{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR *)&info);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
}
#pragma warning(pop)
}
void Thread::setThreadName(const std::string &name)
{
SetThreadName(::GetCurrentThreadId(), name.c_str());
}
void Thread::setPriority(ThreadPriority priorityLevel)
{
int priority = 0;
switch (priorityLevel)
{
case High:
priority = THREAD_PRIORITY_TIME_CRITICAL;
break;
case Low:
priority = THREAD_PRIORITY_IDLE;
break;
default:
priority = THREAD_PRIORITY_NORMAL;
break;
}
BOOL ret = SetThreadPriority(_private._hthread, priority);
if (!ret)
{
}
}
void Thread::clear()
{
SAutoLock autolock (_lock);
_stopping = false;
delete _runnable;
_runnable = NULL;
_name = "";
_start = false;
_threadID = INVALID_THREAD_ID;
}
// `stdcall' to 'cdecl' thunk
unsigned WINAPI Thread::threadProcWin32thunk(LPVOID lpParameter )
{
Thread::threadProc(lpParameter);
return 0;
}
void *Thread::threadProc(void *args)
{
Thread *thread = static_cast<Thread *> (args);
{
SAutoLock autoLock(thread->_lock);
thread->_threadID = getCurrentThreadID();
thread->setThreadName(thread->_name);
thread->setPriority(thread->_priorityLevel);
}
thread->_startSem.notify();
thread->_runnable->run();
{
SAutoLock autoLock(thread->_lock);
thread->clear();
}
return NULL;
}
}