📄 ostimer.cpp
字号:
#include "OSTimer.h"#include <stdio.h>#include "MyAssert.h"#include "OSMessage.h"#include "OSThread.h"#include "LogInterface.h"#ifdef __linux__ #include <sys/time.h>#endif#define DEBUG 0using namespace std;OSTimerTask * OSTimerTask::m_inst=NULL;
//////////////////////////////////////////////////////////////////////////
CTimer::CTimer()
{
m_ID = 0;
m_pOwnerObj = NULL;
}
void CTimer::Initialize(CEvent *pOwnerObj)
{
m_ID = OSTimerTask::GetInstance()->GetTimer(pOwnerObj);
m_pOwnerObj = pOwnerObj;
}
CTimer::~CTimer()
{
OSTimerTask::GetInstance()->StopTimer(m_ID);
OSTimerTask::GetInstance()->RemoveTimer(m_ID);
}
Bool CTimer::Start(UInt32 nTimeoutVal)
{
return OSTimerTask::GetInstance()->StartTimer( m_ID, nTimeoutVal, m_ID, (OSTask*)m_pOwnerObj);
}
void CTimer::Stop()
{
OSTimerTask::GetInstance()->StopTimer(m_ID);
}
Bool CTimer::operator==(const Timer_T &other)
{
return m_ID == other;
}
Bool CTimer::operator==(const CTimer &y)
{
return m_ID == y.m_ID;
}
//////////////////////////////////////////////////////////////////////////
/** * * @return */TimerQueue::TimerQueue() :priority_queue< TimerData *, std::vector<TimerData *>,timer_greater>(){}/** * * @return */TimerQueue::~ TimerQueue( ){}/** * 打印信息 */void TimerQueue::PrintQueue( ){#if DEBUG>0 TimerData *p; for(int i=0;i<c.size();i++) { p=c.at(i); if(p) {#ifdef __Win32__ printf("Priority Queue Timer Info [ID= %I64d, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %lld]\n",#else printf("Priority Queue Timer Info [ID= %lld, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %lld]\n",#endif p->m_ID, p->m_Status, p->m_Value, p->m_MsgRecvObj, p->m_Task, p->m_T); } }#endif}OSTimerTask::OSTimerTask(){
m_strTaskType = "OSTimerTask";
m_isrun = FALSE; m_TimerID = 0;}OSTimerTask::~OSTimerTask(){ Terminate();}/* * 函数介绍: 遍历OSTimer连表,找出超时的OSTimer,并超时发送消息 * 输入参数:无 * 输出参数:无 * 返回值 : */Bool OSTimerTask::Run(){ Int64 m_ct; TimerData *m_tr; while(m_isrun) { //处理消息 MsgData gdata; if(PopMessage(&gdata)) { Bool bQuit=false; switch(gdata.m_MsgID) { case RFS_MSG_NORNALQUIT: bQuit=TRUE; break; } if(bQuit) { break; } } m_mutex.Lock(); m_ct=OS::Milliseconds(); m_tr=NULL; //取得最小超时时间的的Timer while(!m_tlist.empty()) { m_tr=m_tlist.top(); if(m_tr){ if(m_tr->m_Status != TimerData::RUN ){ m_tlist.pop(); ReclaimTimerData(m_tr); } else { //合法的需要计算超时的Timer //printf("CurrentTimer:AimTime =[%lld,%lld]\n",m_ct,m_tr->m_T); if( m_ct > m_tr->m_T ) { //printf("PostMessage. ID is [%lld]\n",m_tr->m_ID); PrintRunList(); m_tlist.PrintQueue(); if(m_tr->m_Task)
m_tr->m_Task->PostMessage(RFS_MSG_TIMEOUT,m_tr->m_MsgRecvObj,m_tr->m_Value); m_tlist.pop(); ReclaimTimerData(m_tr); } else break; } } else m_tlist.pop(); } //printf("Wait for timeout or Wait event\n"); if(m_tlist.empty()) m_cond.Wait(&m_mutex,1000); else { //printf("Wait for [%d] ms\n",(Int32)(m_tr->m_T-m_ct)); if(m_tr->m_T-m_ct >0) m_cond.Wait(&m_mutex,(Int32)(m_tr->m_T-m_ct)); } m_mutex.Unlock(); } m_isrun = FALSE; //printf("OSTimerTask->Run quit\n"); return TRUE;}/* * 函数介绍: 取得定时器 * 输入参数:v_obj - 接收超时信息的对象 * 输出参数:无 * 返回值 :0 -失败 * >0 定时器ID */TimerID_t OSTimerTask::GetTimer(CEvent *v_Obj){ OSMutexLocker Locker(&m_mutex); //取得Timer TimerData *Timer=NULL; Timer=AllocTimerData(); if(!Timer) return 0; //初始化值 Timer->m_Status= TimerData::IDLE; Timer->m_MsgRecvObj = v_Obj; //printf("m_UsedList size is [%d]\n",m_UsedList.size()); PrintRunList(); m_tlist.PrintQueue(); return Timer->m_ID;}/* * 函数介绍: 销毁定时器 * 输入参数:TimerID_t 定时器的ID‘ * 输出参数:无 * 返回值 :0 -失败 * >0 定时器ID */void OSTimerTask::RemoveTimer(TimerID_t v_id){ OSMutexLocker Locker(&m_mutex); TimerData *Timer=NULL; Timer=FindUsedTimer(v_id); if(Timer) { //从使用链中移除 m_UsedList.erase(v_id); //保证未使用连中有一定的数量 if(m_UnusedList.size()>100) { delete Timer; } else {//加入到未使用链 m_UnusedList.push_back(Timer); Timer->m_Status= TimerData::IDLE; } } else { Timer=FindRunTimer(v_id); if(Timer) { m_RunList.erase(Timer->m_ID); //等待Run将其移到m_UnusedList中,再移除 Timer->m_Status = TimerData::REMOVE; Timer->m_Task = NULL; } } PrintRunList(); m_tlist.PrintQueue();}Bool OSTimerTask::IsRun(TimerID_t v_id){ Assert(v_id); TimerData *Timer=FindRunTimer(v_id); if(Timer) { if(Timer->m_Status == TimerData::RUN) return TRUE; } return FALSE;}/* * 函数介绍: 起动定时器 * 输入参数:v_t 超时时间。 * v_value 发送消息的value,消息的ID为超时消息 * 输出参数:无 * 返回值 : */Bool OSTimerTask::StartTimer(TimerID_t v_id,Int32 v_t,Int32 v_value,OSTask *v_Recv){ Assert(v_id); //不允许超时的间隔为0.// Assert(v_t > 0); if(v_t <= 0)
v_t = 10;// return FALSE; TimerData *Timer=NULL; OSMutexLocker Locker(&m_mutex); //在使用链中查找 Timer=FindUsedTimer(v_id); if(Timer) { if(!Timer->m_Task && !v_Recv) return FALSE; //从使用链中移除 m_UsedList.erase(v_id); //设置 Timer->m_T=OS::Milliseconds()+v_t*1000; Timer->m_Value=v_value; Timer->m_Status= TimerData::RUN; //设置OSTask if(v_Recv) Timer->m_Task = v_Recv; //加入到运行链中 m_RunList[Timer->m_ID]=Timer; m_tlist.push(Timer); m_cond.Signal(); PrintRunList(); m_tlist.PrintQueue(); return TRUE; //printf("Start Timer. Terminate time is [%lld]\n",Timer->m_T); } else { //在运行链中查找, Timer=FindRunTimer(v_id); if(Timer) { if(Timer->m_Status == TimerData::STOP) { //Timer已停止,但还未出Run链 //生成新对象 TimerData *NewTimer=new TimerData; Assert(NewTimer); if(NewTimer) { //初始化,复制 memset(NewTimer,0,sizeof(TimerData)); *NewTimer=*Timer; //复制品已存在,设置自己,并移除 m_RunList.erase(v_id); Timer->m_Status= TimerData::REMOVE; //设置,并将复制品加入到运行链中 m_RunList[v_id]=NewTimer; NewTimer->m_T=OS::Milliseconds()+v_t*1000; NewTimer->m_Value=v_value; NewTimer->m_Status= TimerData::RUN; //设置OSTask if(v_Recv) Timer->m_Task = v_Recv; //加入到优先级队列中 m_tlist.push(NewTimer); m_cond.Signal(); PrintRunList(); m_tlist.PrintQueue(); return TRUE; //printf("Start Timer. Terminate time is [%lld]\n",NewTimer->m_T); } } else { //Timer 正在运行 ERR_LOGGER(LOG_RUN_LEVEL_HIGH,LOG_MODULE_OS,(UInt32)v_id,"Program BUG!, Timer is running, Pls call StopTimer and then StartTimer!"); //Assert(FALSE); return FALSE; } } else {//不在RunList, 也不在UseList ERR_LOGGER(LOG_RUN_LEVEL_HIGH,LOG_MODULE_OS,(UInt32)v_id,"Timer doesn't exist in both RunList and UsedList"); Assert(FALSE); return FALSE; } } return FALSE;}/* * 函数介绍: 停止定时器 * 输入参数:TimerID_t 定时器的ID‘ * 输出参数:无 * 返回值 : */void OSTimerTask::StopTimer(TimerID_t v_id){ OSMutexLocker Locker(&m_mutex); TimerData *Timer=NULL; //在运行链中查找 Timer=FindRunTimer(v_id); if(Timer) { Timer->m_Status= TimerData::STOP; } PrintRunList(); m_tlist.PrintQueue();}/* * 函数介绍: 起动运行 * 输入参数:无 * 输出参数:无 * 返回值 :无 */Bool OSTimerTask::Initialize(){ if(!m_isrun) { m_isrun=true; RunTask(); return TRUE; } return FALSE;}/* * 函数介绍: 终止运行 * 输入参数:无 * 输出参数:无 * 返回值 :无 */void OSTimerTask::Terminate(){ if(m_isrun) { //停止线程 PostMessage(RFS_MSG_NORNALQUIT); m_mutex.Lock(); m_cond.Signal(); m_mutex.Unlock();/* while(m_isrun) { OS::Sleep(100); m_mutex.Lock(); m_cond.Signal(); m_mutex.Unlock(); }*/ OSTask::StopTask(); #if DEBUG >0 PrintAllList(); #endif //释放UnusedList while(!m_UnusedList.empty()) { delete *m_UnusedList.begin(); m_UnusedList.pop_front(); } //释放UsedList while(!m_UsedList.empty()) { delete m_UsedList.begin()->second; m_UsedList.erase(m_UsedList.begin()); } //释放RunList// while(!m_RunList.empty()) {// delete m_RunList.begin()->second;// m_RunList.erase(m_RunList.begin());// } //释放priority中,需要释放的对象 TimerData *tmp; while(!m_tlist.empty()) { tmp=m_tlist.top(); if(tmp) { delete tmp; } m_tlist.pop(); } }}/* * 函数介绍: 取得唯一实例 * 输入参数:无 * 输出参数:无 * 返回值 :实例指针 */OSTimerTask * OSTimerTask::GetInstance(){ if(m_inst) return m_inst; m_inst=new OSTimerTask; if(!m_inst) return NULL; return m_inst;}/* * 函数介绍: 销毁唯一实例 * 输入参数:无 * 输出参数:无 * 返回值 :无 */void OSTimerTask::DelInstance(){ if(m_inst) { delete m_inst; m_inst=NULL; }}TimerData * OSTimerTask::FindUnusedTimer(TimerID_t v_id){ Assert(v_id); //Find it in Unused list list<TimerData *>::iterator Iter; for(Iter=m_UnusedList.begin();Iter!=m_UnusedList.end();Iter++){ if(*Iter) { if((*Iter)->m_ID == v_id) return *Iter; } } return NULL;} TimerData * OSTimerTask::FindUsedTimer(TimerID_t v_id){ //Find it in Unused list map<TimerID_t,TimerData *>::iterator Iter; Iter=m_UsedList.find(v_id); if(Iter != m_UsedList.end()) { return Iter->second; } return NULL;}TimerData * OSTimerTask::FindRunTimer(TimerID_t v_id){ //Find it in runing list map<TimerID_t,TimerData *>::iterator Iter; Iter=m_RunList.find(v_id); if(Iter != m_RunList.end()) { return Iter->second; } return NULL; }/* * 函数介绍: 从未使用连中取得一个Timer,并加入到使用链 * 输入参数:无 * 输出参数:无 * 返回值 :TimerData * */TimerData * OSTimerTask::AllocTimerData(){ //取得Timer TimerData *Timer=NULL; if(m_UnusedList.empty()) { //未使用连中无,则创建新的 Timer=new TimerData; if(!Timer) { Assert(Timer); return NULL; } //初始化值 memset(Timer,0,sizeof(TimerData)); //如果v_id为0时 m_TimerID++; Timer->m_ID = m_TimerID; } else { //从未使用连中取得// map<TimerID_t, TimerData *>::iterator Iter;// Iter=m_UnusedList.begin();// m_UnusedList.erase(Iter);// Timer=Iter->second;// Assert(Timer); Timer=*m_UnusedList.begin(); m_UnusedList.pop_front(); Assert(Timer); } //加入到使用连 Timer->m_Status= TimerData::IDLE; m_UsedList[Timer->m_ID]=Timer; return Timer;}/* * 函数介绍: 从运行链中回收Timer到使用链中 * 输入参数:v_td * 输出参数:无 * 返回值 :TimerData * */void OSTimerTask::ReclaimTimerData(TimerData *v_td){ Assert(v_td); if (v_td->m_Status == TimerData::REMOVE) { //已有Timer的复制品,该Timer需要释放 delete v_td; } else { //从运行链中取走 m_RunList.erase(v_td->m_ID); //加入到m_UsedList m_UsedList[v_td->m_ID]=v_td; v_td->m_Status= TimerData::IDLE; }}void OSTimerTask::PrintRunList(){#if DEBUG>0 map<TimerID_t,TimerData *>::iterator Iter; for(Iter=m_RunList.begin();Iter!=m_RunList.end();Iter++) { if(Iter->second) {#ifdef __Win32__ printf("RunList Timer Info [ID= %I64d, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %lld]\n",#else printf("RunList Timer Info [ID= %lld, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %lld]\n",#endif Iter->second->m_ID, Iter->second->m_Status, Iter->second->m_Value, Iter->second->m_MsgRecvObj, Iter->second->m_Task, Iter->second->m_T); } }#endif}void OSTimerTask::PrintUnusedList( ){ list<TimerData *>::iterator Iter; for(Iter=m_UnusedList.begin();Iter!=m_UnusedList.end();Iter++) { if(*Iter) {#ifdef __Win32__ printf("UnusedList Timer Info [ID= %I64d, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %I64d]\n",#else printf("UnusedList Timer Info [ID= %lld, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %lld]\n",#endif (*Iter)->m_ID, (*Iter)->m_Status, (*Iter)->m_Value, (*Iter)->m_MsgRecvObj, (*Iter)->m_Task, (*Iter)->m_T); } }}void OSTimerTask::PrintUsedList( ){ map<TimerID_t,TimerData *>::iterator Iter; for(Iter=m_UsedList.begin();Iter!=m_UsedList.end();Iter++) { if(Iter->second) {#ifdef __Win32__ printf("UsedList Timer Info [ID= %I64d, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %I64d]\n",#else printf("UsedList Timer Info [ID= %lld, Status= %d, Value= %d, Owner= %p, Receiver= %p, AimTime= %lld]\n",#endif Iter->second->m_ID, Iter->second->m_Status, Iter->second->m_Value, Iter->second->m_MsgRecvObj, Iter->second->m_Task, Iter->second->m_T); } }}void OSTimerTask::PrintAllList( ){ PrintUnusedList(); PrintUsedList(); PrintRunList(); m_tlist.PrintQueue();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -