用于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.
 
 
 
 
 
 

264 lines
4.8 KiB

#include "TaskLoop.h"
#include <unknown/obj-ref-impl.hpp>
#include <algorithm>
#include <cassert>
#include <deque>
#include <limits>
namespace SOUI
{
STaskLoop::RunnableDisposer STaskLoop::kRunnableDisposer;
STaskLoop::STaskLoop() :
m_taskListLock(),
m_runningLock(),
m_thread(),
m_itemsSem(),
m_items(),
m_hasRunningItem(false),
m_runningItem(NULL,0),
m_nextTaskID(0)
{
}
STaskLoop::~STaskLoop()
{
stop();
}
void STaskLoop::start(const char * pszName,Priority priority)
{
{
SAutoLock autoLock(m_taskListLock);
m_items.clear();
if(pszName) m_strName = pszName;
}
_start(this, &STaskLoop::runLoopProc, priority);
}
void STaskLoop::stop()
{
int taskNum = getTaskCount();
m_thread.stop();
m_itemsSem.notify();
m_thread.waitForStop();
}
bool STaskLoop::isRunning()
{
return !m_thread.isStopped();
}
long STaskLoop::postTask(const IRunnable *runnable, bool waitUntilDone, int priority)
{
if (m_thread.isStopped())
{
return -1;
}
IRunnable *pCloneRunnable = runnable->clone();
if (Thread::getCurrentThreadID() == m_thread.getThreadID() && waitUntilDone)
{
pCloneRunnable->run();
pCloneRunnable->destroy();
return -1;
}
SSemaphore semaphore;
TaskItem item(pCloneRunnable,priority);
if (waitUntilDone)
{
item.semaphore = &semaphore;
}
m_taskListLock.Enter();
item.taskID = m_nextTaskID;
m_nextTaskID = (m_nextTaskID + 1) & ((std::numeric_limits<long>::max)());
std::list<TaskItem>::reverse_iterator it= m_items.rbegin();
while(it != m_items.rend())
{
if(it->nPriority>=priority)
{
m_items.insert(it.base(),item);
break;
}
it ++;
}
if(it==m_items.rend())
m_items.push_front(item);
m_taskListLock.Leave();
m_itemsSem.notify();
if (waitUntilDone)
{
int ret = semaphore.wait();
if (ret == RETURN_ERROR)
{
}
}
return item.taskID;
}
void STaskLoop::runLoopProc()
{
while (true)
{
if (m_thread.isStopping())
{
break;
}
m_itemsSem.wait(INFINITE);
{
SAutoLock autoLock(m_taskListLock);
SAutoLock autoRunningLock(m_runningLock);
SAutoLock autoRuningInfoLock(m_runningInfoLock);
m_hasRunningItem = false;
m_runingItemInfo.clear();
m_runningItem = TaskItem(NULL,0);
if (!m_items.empty())
{
m_hasRunningItem = true;
m_runningItem = m_items.front();
m_runingItemInfo = m_runningItem.getRunnableInfo();
m_items.pop_front();
}
}
{
SAutoLock autoRunningLock(m_runningLock);
if (m_hasRunningItem)
{
TaskItem item = m_runningItem;
item.runnable->run();
if (item.semaphore)
{
//通知一个task执行完毕
item.semaphore->notify();
}
}
{
SAutoLock autoRuningInfoLock(m_runningInfoLock);
m_hasRunningItem = false;
m_runingItemInfo.clear();
m_runningItem = TaskItem(NULL,0);
}
}
}// end of while
SAutoLock autoLock(m_taskListLock);
size_t itemsSize = m_items.size();
while (itemsSize > 0)
{
TaskItem item = m_items.front();
m_items.pop_front();
itemsSize--;
if (item.semaphore)
{
item.semaphore->notify();
}
}
m_items.clear();
}
bool STaskLoop::getName(char * pszBuf, int nBufLen)
{
SAutoLock autoLock(m_taskListLock);
if (m_strName.length() >= (size_t)nBufLen)
return false;
strcpy_s(pszBuf, nBufLen, m_strName.c_str());
return true;
}
void STaskLoop::cancelTasksForObject(void *object)
{
if (object == NULL)
{
return;
}
{
SAutoLock autoLock(m_taskListLock);
std::list<TaskItem>::iterator iter = m_items.begin();
while (iter != m_items.end())
{
TaskItem &item = *iter;
if (item.runnable->getObject() == object)
{
iter = m_items.erase(iter);
}
else
{
++iter;
}
}
}
{
SAutoLock autoLock(m_runningLock);
SAutoLock autoLockRunningInfo(m_runningInfoLock);
if(m_hasRunningItem)
{//make sure the running item is not belong to the to be canceled object.
m_hasRunningItem = false;
m_runingItemInfo.clear();
m_runningItem = TaskItem(NULL,0);
}
}
}
bool STaskLoop::cancelTask(long taskId)
{
SAutoLock autoLock(m_taskListLock);
std::list<TaskItem>::iterator itemIt = m_items.begin();
while (itemIt != m_items.end())
{
if (itemIt->taskID == taskId)
{
itemIt = m_items.erase(itemIt);
return true;
}
else
{
++itemIt;
}
}
return false;
}
int STaskLoop::getTaskCount() const
{
SAutoLock autoLock(m_taskListLock);
return (int)m_items.size();
}
bool STaskLoop::getRunningTaskInfo(char *buf, int bufLen)
{
SAutoLock autoLock(m_runningInfoLock);
if(!m_hasRunningItem)
return false;
strcat_s(buf,bufLen-1,m_runingItemInfo.c_str());
return true;
}
SOUI_COM_C BOOL SOUI_COM_API TASKLOOP::SCreateInstance(IObjRef **ppTaskLoop)
{
*ppTaskLoop = new STaskLoop();
return TRUE;
}
}