|
CTimerEngine成员变量:
//状态变量
DWORD m_dwTimerSpace; //时间间隔,这个值后来应该是给了定时器线程
protected:
bool m_bService; //运行标志
DWORD m_dwTimePass; //经过时间
DWORD m_dwTimeLeave; //倒计时间
CTimerItemPtr m_TimerItemFree; //空闲数组
CTimerItemPtr m_TimerItemActive; //活动数组
这些是分析定时器线程函数需要了解的成员变量,其次是线程同步:
从代码中可以看出所有对:m_TimerItemActive; m_TimerItemFree;的操作都是在一个线程锁的保护之下的。
定时器线程:
通过CTimerThread绕一圈以后最终被循环执行的实际上是这个函数(m_dwTimerSpace控制最小时间):
- //定时器通知
- void CTimerEngine::OnTimerThreadSink()
- {
- //锁定资源
- CThreadLockHandle LockHandle(&m_ThreadLock);
-
- //倒计时间
- if (m_dwTimeLeave==NO_TIME_LEFT)
- {
- ASSERT(m_TimerItemActive.GetCount()==0);
- return;
- }
-
- //减少时间
- ASSERT(m_dwTimeLeave>=m_dwTimerSpace);
- m_dwTimeLeave-=m_dwTimerSpace;
- m_dwTimePass+=m_dwTimerSpace;
-
- //查询定时器
- if (m_dwTimeLeave==0)
- {
- bool bKillTimer=false;
- tagTimerItem * pTimerItem=NULL;
- DWORD dwTimeLeave=NO_TIME_LEFT;
- for (INT_PTR i=0;i<m_TimerItemActive.GetCount();)
- {
- //效验参数
- pTimerItem=m_TimerItemActive;
- ASSERT(pTimerItem!=NULL);
- ASSERT(pTimerItem->dwTimeLeave>=m_dwTimePass);
-
- //定时器处理
- bKillTimer=false;
- // 这一行做了--操作
- pTimerItem->dwTimeLeave -= m_dwTimePass;
- if (pTimerItem->dwTimeLeave==0L)
- {
- //发送通知
- m_AttemperEvent.PostTimerEvent(pTimerItem->wTimerID,pTimerItem->wBindParam);
-
- //设置次数
- if (pTimerItem->dwRepeatTimes!=TIMER_REPEAT_TIMER)
- {
- ASSERT(pTimerItem->dwRepeatTimes>0);
- if (pTimerItem->dwRepeatTimes==1L)
- {
- bKillTimer=true;
- m_TimerItemActive.RemoveAt(i);
- m_TimerItemFree.Add(pTimerItem);
- }
- else pTimerItem->dwRepeatTimes--;
- }
-
- //设置时间,从新开始倒计时
- if (bKillTimer==false) pTimerItem->dwTimeLeave=pTimerItem->dwElapse;
- }
-
- //增加索引
- if (bKillTimer==false)
- {
- i++;
- dwTimeLeave=__min(dwTimeLeave,pTimerItem->dwTimeLeave);
- ASSERT(dwTimeLeave%m_dwTimerSpace==0);
- }
- }
-
- //设置响应
- m_dwTimePass=0L;
- m_dwTimeLeave=dwTimeLeave;
- }
-
- return;
- }
CTimerEngine:
启动一个定时器线程,循环遍历定时器,如果发现满足出发条件的定时器就投递一个定时器消息到CQueueServiceEvent对象。
|
|