Rv定时器实现

上传人:博****1 文档编号:464315062 上传时间:2023-02-23 格式:DOCX 页数:16 大小:18.66KB
返回 下载 相关 举报
Rv定时器实现_第1页
第1页 / 共16页
Rv定时器实现_第2页
第2页 / 共16页
Rv定时器实现_第3页
第3页 / 共16页
Rv定时器实现_第4页
第4页 / 共16页
Rv定时器实现_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《Rv定时器实现》由会员分享,可在线阅读,更多相关《Rv定时器实现(16页珍藏版)》请在金锄头文库上搜索。

1、一、模块初始化1、中间层管理对象构造RvSipMidConstruct(sizeof(midCfg), &midCfg, &g_hMidMgr);中间层管理对象资源分配MidMgrAllocateResources(pMidMgr,&internalCfg);构造用户定时器列表pMidMgr-userTimerPool = RLIST_PoolListConstruct(pl/lidCfg-maxUserTimers/l,sizeof(MidTimer),pMidMgr-pLogMgr/User Timer);pMidMgr-hUserTimers = RLIST_ListConstruct(

2、pMidMgr-userTimerPool);/select引擎对象构造RvSelectConstruct(2048,pMidCfg-maxUserTimers/pMidCfg-sig_dev,pMidMgr-pLogMgr, &pMidMgr-pSelect);获取当前线程对象,因为第一次使用,所以最后返回值为0th = RvThreadCurrent();if (th = NULL)为线程对象分配资源RvMemoryAlloc(NULL,sizeof(RvThread),logMgr,(void *)&th);构造线程对象RvThreadConstructFromUserThread(lo

3、gMgr,th);constructedThread = th;从线程对象中获取select引擎,因为第一次使用所以为空。RvThreadGetVar(rvSeIectTIsVarIndex, logMgrJvoid *)&selectEngine);分配select引擎资源RvMemoryAlloc(NULL,sizeof(RvSelectEngine)JogMgr,(void *)&selectEngine);selectEngine-logMgr = logMgr;selectEngine-constructedThread = constructedThread;设置select引擎默

4、认的抢占回调,后面传输层模块会覆盖这些回调RvSelectPreemptionHandlersConstruct(selectEngine);phandlers = &seli-preemptionHandlers;phandlers-defaultHandler.cb = DefaultPreemptionCB;phandlers-defaultHandler.ctx = 0;/select引擎锁构造RvLockConstruct(selectEngine-logMgr, &selectEngine-lock);event-id+;event-triggerlength = delay; 定

5、时器超时时长event-triggertime = Rvlnt64Add(starttime, delay);实际超时的时刻event-canceled = RV_FALSE;event-userdata = userdata;/ pMidTimerevent-callback = callback;/MidTimerFunc当新的定时器事件对象放入优先级队列中RvPQueuePut(&tqueue-pqueue, event);将事件条目对象及事件ID返回给上层MID定时器对象,即/ pMidTimer-sipTimer. hTimer. Event/ pMidTimer-sipTimer.

6、 hTimer. idtimer-event = event;timer-id = event-id;获取定时器队列中最小超时时间的条目RvTimerQueueNextEvent(tqueue,&nextevent);更新select引擎对象的超时等待时间RvSelectSetTimeOut(RvSelectEngine *)tqueue-selEng, starttime,nextevent, tqueue-logMgr);记载select引擎需要唤醒的时间selectEngine-wakeupTime = RvUint64Add(currentTime, nsecTimeout);记载se

7、lect引擎的超时时间selectEngine-nsecTimeout = nsecTimeout;给select引擎的抢占对象发送一个空消息,唤醒select,让其设置新的超时时间。rvFdPreempt(selectEngine/ RvSelectEmptyPreemptMsg);如果是空消息,则标记需要唤醒if (message = RvSelectEmptyPreemptMsg)needToWrite = RV_TRUE;唤醒select引擎if (needToWrite)RvSocketSendBuffer(&selectEngine-preemptionSocket,&messag

8、e, sizeof(RvUint8), &selectEngine-localAddress,logMgr, NULL);三、select引擎收到唤醒消息RvSelectWaitAndBlockselectEngine-waiting = RV_TRUE;如果之前有定时器需要设置超时时间,则从定时器及正常的select超时变量中取最小时间做为超时时间if (RvUint64lsNotEqual(selectEngine-nsecTimeout, RvUint64Const(0, 0)nsecSelectTimeout = Rvll int64Min(nsecTimeout, selectEng

9、ine-nsecTimeout);转换时间格式timeout.tv_sec = Rvlnt64ToRvlnt32(Rvlnt64Div(nsecSelectTimeout,RV_TIME64_NSECPERSEC);timeout.tv_usec = (long)(Rvlnt64ToRvlnt32(Rvlnt64Mod(nsecSelectTimeout,RV_TIME64_NSECPERSEC) / RV_TIME_NSECPERUSEC);tm = &timeout;复位所有文件描述符集RvSelectGetSelectFds(selectEngine, &numFds, &tmpRdSe

10、t, &tmpWrSet);selectEngine-selectThread = RvThreadCurrent();标记当前有定时器selectEngine-suspectTimeout =RvU int64lsNotEqual(selectEngine-nsecTimeoutz RvUint64Const(0, 0);selectEngine-nsecTimeout = RvUint64Const(0z 0);select(numFds, &tmpRdSet, &tmpWrSet, NULL, tm);selectEngine-waiting = RV_FALSE;如果有定时器超时标记i

11、f(selectEngine-suspectTimeout)selectEngine-wakeupTime = RvUint64Const(0, 0);处理定时器事件RvTimerQueueService(&selectEngine-tqueue, 0, &numevents,selectEngine-timeOutCb, selectEngine-timeOutCbContext);获取当前时间curtime = RvTimestampGet(tqueue-logMgr);do 循环处理所有超时的定时器队列事件获取当前最小的超时定时器事件event = (RvTimerEvent *)RvP

12、QueuePeek(&tqueue-pqueue);如果没有可处理的定时器事件,则跳出循环if(event = NULL) | | (Rvlnt64lsGreaterThan(event-triggertime, curtime)I I (tqueue-qState = RV_TIMERQUEUE_DISABLED &alternativeCb != NULL)break;执行定时器超时处理回调,这里该回调函数为/ MultiThreadedTimerEventHandler,在下面单独描述alternativeCb(alternativeCbContext);如果满足条件则继续处理下一个定时

13、器超时事件while(result = RV_OK) & (tqueue-qState != RV_TIMERQUEUE_DELETED) &(maxevents = 0) | | (*eventcount selEng, curtime, nextevent,tqueue-logMgr);MultiThreadedTimerEventHandler将定时器队列的状态设置为关闭。/ tqueue-qState = RV_TIMERQUEUE_DISABLEDRvTimerQueueControl(&pTransportMgr-pSelect-tqueue, RV_TIMERQUEUE_DISA

14、BLED);处理队列分配TransportProcessingQueueAllocateEvent(pTransportMgr, NULL, TIMER_EXPIRED_EVENTZRV_FALSE, &ev);从处理队列中分配一个事件资源PQUEUE_AllocateEvent(pTransportMgr-hProcessingQueue,(HQEVENT *)ev);(*ev)-type = TIMER_EXPIRED_EVENT; 记载事件类形处理尾部事件TransportProcessingQueueTailEvent(RvSipTransportMgrHandle)pTransportMgr,ev);PQUEUE_TailEvent(pTransportMgr-hProcessingQueue,(HQEVENT)ev);将分配到的事件资源插入到事件队列尾部RLIST_lnsertTail(processing_queue-hEventQueuePool,processing_queue-hEventQueue,&listltem);pEv = (HQEVENT*)listltem;*pEv = ev;使调用RvSelectWaitAndBlock的线程继续执行,该函数给select引擎发送一个抢占事件。RvSelect

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号