/*
* CBaseTimer.cpp
*
* Created on: 2009-11-29
* Author: lgh
*/
#include "CBaseTimer.h"
namespace Kingdom_Base {
//---------------------------------------------CTimerEvent-------------------------------------------------------------------
CTimerEvent::CTimerEvent()
{
}
CTimerEvent::~CTimerEvent()
{
}
int CTimerEvent::OnTimer(unsigned long p_TimerID,unsigned long wParam,unsigned long lParam)
{
return 0;
}
//---------------------------------------------CTimerEvent End-------------------------------------------------------------------
//---------------------------------------------CMyTimerData-------------------------------------------------------------------
CMyTimerData::CMyTimerData()
{
m_pTimerEvent = NULL;
m_pBaseThread = NULL;
//初始化互斥访问量
pthread_mutex_init(&m_node_mutex,NULL);
//第一个时间节点,用于保存时间节点的总的数量
m_pTotalHead = NULL;
m_pTotalHead = new HeadNode();
}
CMyTimerData::~CMyTimerData()
{
//卸构函数中需要释放分配的链表空间
ClearQueue();
delete m_pTotalHead;
m_pTotalHead = NULL;
//销毁互斥锁
pthread_mutex_destroy(&m_node_mutex);
}
//添加一个定时器事件节点
/*
*
//成功返回 0
//如果该TimerID已经存在,那么返回 1
//如果时间间隔为0,那么返回 2
* */
int CMyTimerData::AddTimer(unsigned long p_TimerID,unsigned long p_TimerElapse, unsigned long p_wParam, unsigned long p_lParam,bool p_OnceTimer)
{
//检查时间间隔
if(p_TimerElapse <= 0)
return 2;
//查询是否已经存在了该TimerID的节点
EventNode tmp_EventNode;
tmp_EventNode.m_TimerID = p_TimerID;
int ret = QueryTimerInfo(&tmp_EventNode);
if(ret == 0)
{
return 1;
}
unsigned long tmp_RemainTimeElapse = p_TimerElapse;
EventNode *tmp_pNewEventNode = NULL;
//HeadNode *tmp_pNewHeadNode = NULL;
EventNode *tmp_pEventNode_1 = NULL;
EventNode *tmp_pEventNode_2 = NULL;
HeadNode *tmp_pHeadNode_1 = NULL;
HeadNode *tmp_pHeadNode_2 = NULL;
//新申请一个定时器事件节点
tmp_pNewEventNode = new EventNode();
tmp_pNewEventNode->m_TimerID = p_TimerID;
tmp_pNewEventNode->m_TimeElapse = p_TimerElapse;
tmp_pNewEventNode->m_wParam = p_wParam;
tmp_pNewEventNode->m_lParam = p_lParam;
tmp_pNewEventNode->m_OnceTimer = p_OnceTimer;
tmp_pNewEventNode->m_pNextEventNode = NULL;
//查找时间节点中是否有合适的节点,如果某个时间节点中的时延时长和本定时器时长相等,那么,将上面的事件节点加入到该时间节点所属
//的定时器事件节点列表中
//否则,新生成一个时间节点,放入到时间节点链表中,然后,将本定时器事件节点放入到该时间节点的定时器事件节点链表中
bool tmp_IsFinished = false; //指示是否完成
bool tmp_IsContinue = true; //指示是否接续查找时间节点
pthread_mutex_lock(&m_node_mutex);
//TRACE("Add Timer Lock\r\n");
tmp_pHeadNode_1 = m_pTotalHead;
tmp_pHeadNode_2 = tmp_pHeadNode_1->m_pNextHeadNode ;
while(tmp_pHeadNode_2 != NULL && !tmp_IsFinished && tmp_IsContinue )
{
//如果当前新的节点剩余时间小于tmp_pHeadNode_2->m_TimeElapse,那么需要新生成一个节点插入到tmp_pHeadNode_2的前面
if(tmp_RemainTimeElapse < tmp_pHeadNode_2->m_TimeElapse )
{
tmp_IsContinue = false;
break;
}
//如果当前新的节点剩余时间和tmp_pHeadNode_2->m_TimeElapse的时间相等,那么,将该节点插入到tmp_pHeadNode_2所指向的队列中
else if(tmp_RemainTimeElapse == tmp_pHeadNode_2->m_TimeElapse)
{
//将该事件节点插入到本时间节点的定时器事件节点链表中
tmp_pEventNode_1 = tmp_pHeadNode_2->m_pEventNode ;
if(tmp_pEventNode_1 == NULL)
{
//如果该头节点的指向的时间节点为空,那么直接插入,这种情况应该不会存在
tmp_pHeadNode_2->m_pEventNode = tmp_pNewEventNode;
}
else
{
tmp_pEventNode_2 = tmp_pEventNode_1 ->m_pNextEventNode ;
while(tmp_pEventNode_2 != NULL)
{
tmp_pEventNode_2 = tmp_pEventNode_2->m_pNextEventNode ;
tmp_pEventNode_1 = tmp_pEventNode_1->m_pNextEventNode ;
}
tmp_pEventNode_1->m_pNextEventNode = tmp_pNewEventNode;
}
tmp_IsFinished = true;
tmp_IsContinue = false;
break;
}
else
{
tmp_RemainTimeElapse = tmp_RemainTimeElapse - tmp_pHeadNode_2->m_TimeElapse;
tmp_pHeadNode_2 = tmp_pHeadNode_2->m_pNextHeadNode ;
tmp_pHeadNode_1 = tmp_pHeadNode_1->m_pNextHeadNode ;
}
}
//如果成功添加该定时器事件节点,那么,成功返回
if(tmp_IsFinished)
{
pthread_mutex_unlock(&m_node_mutex);
//TRACE("Add Timer UnLock\r\n");
return 0;
}
//如果到现在还没有完成,那么新生成一个时间节点
HeadNode *tmp_pHeadNode_3 = NULL;
tmp_pHeadNode_3 = new HeadNode();
tmp_pHeadNode_3->m_TimeElapse = tmp_RemainTimeElapse ;
tmp_pHeadNode_3->m_pNextHeadNode = NULL;
tmp_pHeadNode_3->m_pEventNode = tmp_pNewEventNode;
//将该时间节点放在合适的位置上面
tmp_pHeadNode_1->m_pNextHeadNode = tmp_pHeadNode_3;
tmp_pHeadNode_3->m_pNextHeadNode = tmp_pHeadNode_2;
//然后将后面时间节点的时间时延都减去新加入的时间节点的时延
if(tmp_pHeadNode_2!= NULL)
{
tmp_pHeadNode_2->m_TimeElapse = tmp_pHeadNode_2->m_TimeElapse - tmp_pHeadNode_3->m_TimeElapse ;
}
pthread_mutex_unlock(&m_node_mutex);
//TRACE("Add Timer UnLock\r\n");
return 0;
}
//删除一个定时器事件节点
//成功返回 0
//该TimerID的定时器事件不存在,那么返回 1
int CMyTimerData::RemoveTimer(unsigned long p_TimerID)
{
bool isSuccess = false;
EventNode *tmp_pEventNode_1 = NULL;
EventNode *tmp_pEventNode_2 = NULL;
HeadNode *tmp_pHeadNode_1 = NULL;
HeadNode *tmp_pHeadNode_2 = NULL;
HeadNode *tmp_pHeadNode_3 = NULL;
pthread_mutex_lock(&m_node_mutex);
//TRACE("Remove Timer Lock\r\n");
tmp_pHeadNode_1 = m_pTotalHead;
tmp_pHeadNode_2 = tmp_pHeadNode_1->m_pNextHeadNode ;
while(tmp_pHeadNode_2 != NULL && !isSuccess)
{
tmp_pEventNode_1 = tmp_pHeadNode_2->m_pEventNode ;
if(tmp_pEventNode_1 == NULL)
{
//这是一个空的时间节点,删除该时间节点
tmp_pHeadNode_3 = tmp_pHeadNode_2->m_pNextHeadNode ;
if(tmp_pHeadNode_3 != NULL)
{
tmp_pHeadNode_3->m_TimeElapse = tmp_pHeadNode_3->m_TimeElapse + tmp_pHeadNode_2->m_TimeElapse;
}
tmp_pHeadNode_1->m_pNextHeadNode = tmp_pHeadNode_2->m_pNextHeadNode ;
delete tmp_pHeadNode_2;
tmp_pHeadNode_2 = tmp_pHeadNode_1->m_pNextHeadNode;
continue;
}
else
{
//该时间节点下面存在定时器事件节点
if(tmp_pEventNode_1->m_TimerID == p_TimerID)
{
//第一个定时器事件节点就是要删除的定时器
tmp_pHeadNode_2->m_pEventNode = tmp_pEventNode_1->m_pNextEventNode ;
delete tmp_pEventNode_1;
tmp_pEventNode_1 = NULL;
//判断删除完后的该时间节点下面的定时器列表是否为空,如果下面已经没有定时器事件节点,那么,删除该时间节点
if(tmp_pHeadNode_2->m_pEventNode == NULL)
{
tmp_pHeadNode_3 = tmp_pHeadNode_2->m_pNextHeadNode ;
if(tmp_pHeadNode_3 != NULL)
{
tmp_pHeadNode_3->m_TimeElapse = tmp_pHeadNode_3->m_TimeElapse + tmp_pHeadNode_2->m_TimeElapse;
}
tmp_pHeadNode_1->m_pNextHeadNode = tmp_pHeadNode_2->m_pNextHeadNode ;
delete tmp_pHeadNode_2;
tmp_pHeadNode_2 = tmp_pHeadNode_1->m_pNextHeadNode;
}
isSuccess = true;
break;
}
else
{
//如果第一个定时器不是要删除的定时器
tmp_pEventNode_2 = tmp_pEventNode_1 ->m_pNextEventNode ;
while(tmp_pEventNode_2!= NULL)
{
if(tmp_pEventNode_2 ->m_TimerID == p_TimerID)
{
tmp_pEventNode_1->m_pNextEventNode = tmp_pEventNode_2->m_pNextEventNode ;
delete tmp_pEventNode_2;
tmp_pEventNode_2 = NULL;
isSuccess = true;
}
else
{
tmp_pEventNode_2 = tmp_pEventNode_2->m_