一、模块初始化
1、//中间层管理对象构造
RvSipMidConstruct(sizeof(midCfg), &midCfg, &g_hMidMgr);
//中间层管理对象资源分配
MidMgrAllocateResources(pMidMgr,&internalCfg);
//构造用户定时器列表
pMidMgr->userTimerPool = RLIST_PoolListConstruct(pMidCfg->maxUserTimers,
1,sizeof(MidTimer),pMidMgr->pLogMgr,"User Timer");
pMidMgr->hUserTimers = RLIST_ListConstruct(pMidMgr->userTimerPool);
//select引擎对象构造
RvSelectConstruct(2048,pMidCfg->maxUserTimers,pMidCfg->sig_dev,
pMidMgr->pLogMgr, &pMidMgr->pSelect);
//获取当前线程对象,因为第一次使用,所以最后返回值为0
th = RvThreadCurrent();
if (th == NULL)
//为线程对象分配资源
RvMemoryAlloc(NULL,sizeof(RvThread),logMgr,(void **)&th);
//构造线程对象
RvThreadConstructFromUserThread(logMgr,th);
constructedThread = th;
//从线程对象中获取select引擎,因为第一次使用所以为空。
RvThreadGetVar(rvSelectTlsVarIndex, logMgr,(void **)&selectEngine);
//分配select引擎资源
RvMemoryAlloc(NULL,sizeof(RvSelectEngine),logMgr,(void **)&selectEngine);
selectEngine->logMgr = logMgr;
selectEngine->constructedThread = constructedThread;
//设置select引擎默认的抢占回调,后面传输层模块会覆盖这些回调
RvSelectPreemptionHandlersConstruct(selectEngine);
phandlers = &seli->preemptionHandlers;
phandlers->defaultHandler.cb = DefaultPreemptionCB;
phandlers->defaultHandler.ctx = 0;
//select引擎锁构造
RvLockConstruct(selectEngine->logMgr, &selectEngine->lock);
//select引擎桶HASH构造
fdBucketHashConstruct(selectEngine, maxHashSize);
selectEngine->maxFd = rvSelectMaxDescriptors;
selectEngine->maxFdInSelect = 0;
RV_FD_ZERO(&selectEngine->rdSet);
RV_FD_ZERO(&selectEngine->wrSet);
//文件描述符抢占对象构造,当前使用SOCKET实现
rvFdPreemptionConstruct(selectEngine);
//转换地址格式
RvAddressConstructIpv4(&selectEngine->localAddress, *ipPtr,
RV_ADDRESS_IPV4_ANYPORT);
//构造抢占SOCKET
RvSocketConstruct(RV_ADDRESS_TYPE_IPV4, RvSocketProtocolUdp, logMgr,
&selectEngine->preemptionSocket);
//设置为非阻塞模式
RvSocketSetBlocking(&selectEngine->preemptionSocket, RV_FALSE, logMgr);
//地址绑定
RvSocketBind(&selectEngine->preemptionSocket,
&selectEngine->localAddress, NULL, logMgr);
RvSocketGetLocalAddress(&selectEngine->preemptionSocket, logMgr,
&selectEngine->localAddress);
//文件描述符构造
RvFdConstruct(&selectEngine->preemptionFd,
&selectEngine->preemptionSocket, logMgr);
fd->fd = *s;
fd->closedByTcpPeer = RV_FALSE;
fd->logMgr = logMgr;
fd->timestamp = RV_UINT64_ZERO;
//将抢占描述符加入的select引擎中,其中回调处理函数为
//rvFdPreemptionCallback,该回调实现下面单独描述。
RvSelectAdd(selectEngine, &selectEngine->preemptionFd, RV_SELECT_READ,
rvFdPreemptionCallback);
selectEngine->usageCnt = 1; //引用计数
//将select引擎设置到线程对象中
RvThreadSetVar(rvSelectTlsVarIndex,(void *)selectEngine,logMgr);
//select引擎的定时器队列构造
RvTimerQueueConstruct(RV_TIMER_QTYPE_FIXED, maxTimers, 0, 0, 0,
RV_SELECT_TIMERS_PER_PAGE, NULL, selectEngine, logMgr,
&selectEngine->tqueue);
RvLockConstruct(logMgr, &tqueue->lock); // 锁构造
RvSemaphoreConstruct(0,logMgr, &tqueue->wait); //信号量构造
//定时器列表池的回调
poolcallbacks.objconstruct = RvTimerEventConstruct;
poolcallbacks.objdestruct = RvTimerEventDestruct;
poolcallbacks.pagealloc = RvTimerMemAlloc;
poolcallbacks.pagefree = RvTimerMemFree;
poolcallbacks.objconstructdata = tqueue;
poolcallbacks.objdestructdata = NULL;
poolcallbacks.pageallocdata = memregion;
poolcallbacks.pagefreedata = memregion;
//定时器列表池构造
RvObjPoolConstruct(&timerevent, &timerevent.element, &poolcallbacks,
sizeof(RvTimerEvent), pagetimers, 0, pooltype, salvage,
maxtimers, mintimers, freelevel, &tqueue->pool)
//优先级队列回调
pqueuecallbacks.memalloc = RvTimerMemAlloc;
pqueuecallbacks.memfree = RvTimerMemFree;
pqueuecallbacks.itemcmp = RvTimerPQueueItemCmp;
pqueuecallbacks.newindex = RvTimerPQueueNewIndex;
pqueuecallbacks.memallocdata = memregion;
pqueuecallbacks.memfreedata = memregion;
//优先级队列构造
RvPQueueConstruct(pqueuetype, startevents, &pqueuecallbacks,
&tqueue->pqueue)
//参数复位
tqueue->callcount = 0;
tqueue->qState = RV_TIMERQUEUE_ENABLED;
tqueue->selEng = selEng;
selectEngine->maxTimers = maxTimers;
---------------------------------------------------------------------------------------------------------------------------
rvFdPreemptionCallback
//从抢占描述符对象中接收消息
while (bytesRead < sizeof(message))
RvSocketReceiveBuffer(&fd->fd, message+bytesRead, sizeof(message)-bytesRead,
NULL, &read, &dummyAddress);
if (rvSts != RV_OK || read == 0) break;
bytesRead += read;
//处理非空抢占消息
for (i = 0; i < (RvInt)bytesRead; i++)
if (message[i] != RvSelectEmptyPreemptMsg)
RvSelectPreemptionHandlersCall(selectEngine, message[i]);
RvSelectPreemptionHandler *h = &seli->preemptionHandlers.handlers[msg];
//如果之前没有设置则使用默认回调
if(h->cb == 0)
h = &seli->preemptionHandlers.defaultHandler;
//执行对应抢占消息的回调。
h->cb(seli, msg, h->ctx);
2、传输层模块构造
StackConstructTransportModule
//参数设置
transportCfg.pLogMgr = pStackMgr->pLogMgr;
transportCfg.regId = pStackMgr->pLogSourceArrey[RVSIP_TRANSPORT];
……
//传输层对象构造
SipTransportConstruct(&transportCfg, &pStackMgr->hTransport);
//传输层对象资源分配
RvMemoryAlloc(NULL, sizeof(TransportMgr), pTransportCfg->pLogMgr,
(void*)&pTransportMgr)
//互斥锁构造
RvMutexConstruct(pTransportMgr->pLogMgr, &pTransportMgr->udpBufferLock);
RvMutexConstruct(pTransportMgr->pLogMgr, &pTransportMgr->hObjEventListLock);
RvMutexConstruct(pTransportMgr->pLogMgr, &pTransportMgr->hRcvBufferAllocLock);
RvMutexConstruct(pTransportMgr->pLogMgr, &pTransportMgr->hOORListLock);
RvSocketSetUDPMaxLength(pTransportCfg->maxBufSize); //设置最大接收BUF
//传输层模块初始化
TransportMgrInitialize(pTransportMgr,pTransportCfg);
//参数初始化
pTransportMgr->pLogMgr = pTransportCfg->pLogMgr;
……
pTransportMgr->preemptionCellAvailable = 0;
pTransportMgr->preemptionDispatchEvents = 0;
pTransportMgr->preemptionReadBuffersReady = 0;
//上面已经构造select引擎了,这里只是增加引用计数,及增加定时器数量
RvSelectConstruct(numofSockets, pTransportMgr->maxTimers,
pTransportCfg->sig_dev, pTransportMgr->pLogMgr, &pTransportMgr->pSelect);
//oor列表构造
pTransportMgr->oorListPool =
RLIST_PoolListConstruct(SOCKET_OOR_RATIO*numofSockets+5, 1,
sizeof(TransportConnection *),pTransportMgr->pLogMgr, "OORPool");
pTransportMgr->oorList = RLIST_ListConstruct(pTransportMgr->oorListPool);
//传输层抢占回调设置,设置回调如下:
//selectEngine. preemptionHandlers.handlers[1].cb =
// TransportPreemptionSelectPreemptionDispatchEventsEvHandler;
// pTransportMgr. preemptionDispatchEvents = 1;
//
//selectEngine. preemptionHandlers.handlers[2].cb =
// TransportPreemptionSelectPreemptionReadBuffersReadyEvHandler;
// pTransportMgr. preemptionReadBuffersReady = 2;
//
//selectEngine. preemptionHandlers.handlers[3].cb =
// TransportPreemptionSelectPreemptionCellAvailableEvHandler;
// pTransportMgr. preemptionCellAvailable = 3;
TransportPreemptionConstruct(pTransportMgr);
//构造发送BUF
pTransportMgr->hraSendBuffer = RA_Construct (pTransportMgr->maxBufSize,
1, NULL, pTransportMgr->pLogMgr, "SendBuffer");
RA_Alloc(pTransportMgr->hraSendBuffer, &(pTransportMgr->sendBuffer));
//构造接收BUF
pTransportMgr->hraRecvBuffer = RA_Construct (pTransportMgr->maxBufSize,
1, NULL, pTransportMgr->pLogMgr, "RecvBuffer");
RA_Alloc(pTransportMgr->hraRecvBuffer, &(pTransportMgr->recvBuffer));
//获取本地地址
RvHostLocalGetAddress(pTransportMgr->pLogMgr,pTransportMgr->sig_dev,
&dummyNumOfAddr,(RvAddress*)dummyAddr);
//为TCP构造连接资源
ConstructConnectionResources(pTransportMgr,pTransportCfg);
// 构造本地地址列表(TCP、UDP)
ConstructLocalAddressLists(pTransportMgr,pTransportCfg);
//将本地地址加入到本地地址列表中
InitializeLocalAddressLists(pTransportMgr,pTransportCfg);
//开启本地地址服务,加入到select引擎对象中,其中UDP的回调函数
//为TransportUdpEventCallback
OpenLocalAddresses(pTransportMgr, pTransportCfg);
//如果用户配置了outbound服务器,则设置到传输层管理对象中
//pTransportMgr->outboundAddr
InitializeOutboundAddress(pTransportMgr,pTransportCfg);
//构造线程处理
MultiThreadedEnvironmentConstruct(pTransportMgr,pTransportCfg);
//参数初始化
pTransportMgr->hProcessingQueue = NULL;
pTransportMgr->processingThreads = NULL;
pTransportMgr->hMessageMemoryBuffPool = NULL;
pTransportMgr->numberOfProcessingThreads =
pTransportCfg->numberOfProcessingThreads; //0个线程
pTransportMgr->processingTaskStackSize =
sportCfg->processingTaskStackSize;
pTransportMgr->processingTaskPriority =
sportCfg->processingTaskPriority;
//锁构造
RvMutexConstruct(NULL, &pTransportMgr->processingQueueLock);
pTransportMgr->bMultiThreadEnvironmentConstructed = RV_TRUE;
//构造处理队列
PQUEUE_Construct(pTransportCfg->processingQueueSize,
pTransportMgr->pLogMgr, &pTransportMgr->processingQueueLock,
sizeof(TransportProcessingQueueEvent),
(pTransportMgr->numberOfProcessingThreads > 0)?RV_TRUE:RV_FALSE,
pTransportMgr->pSelect, "StackProcessingQueue",
&(pTransportMgr->hProcessingQueue));
//分配一个处理队列资源
RvMemoryAlloc(NULL, sizeof (PQUEUE), pLogMgr,
d*)&processing_queue)
//构造一个事件队列
processing_queue->hEventQueuePool =
T_PoolListConstruct(queueSize,1, sizeof(RA_Element),pLogMgr, name);
processing_queue->hEventQueue =
T_ListConstruct(processing_queue->hEventQueuePool);
processing_queue->evSize = evSize; //事件结构大小
//构造事件池
processing_queue->hEventsPool = RA_Construct(evSize,queueSize,
NULL,pLogMgr,name);
//初始值
processing_queue->newMsgSync = NULL;
processing_queue->hLock = hLock;
processing_queue->startShutdown = RV_FALSE;
processing_queue->noEnoughEvents = RV_FALSE;
processing_queue->pSelect = pSelect;
processing_queue->isMultiThreaded = isMultiThreaded;
processing_queue->pLogMgr = pLogMgr;
processing_queue->tryAgainCellAvailable = RV_FALSE;
//将构造好的处理队列设置到pTransportMgr->hProcessingQueue中
*hQueue = (RV_PROCESSING_QUEUE)processing_queue;
//把之前设置好的抢占消息ID设置到处理队列中
PQUEUE_SetPreemptionLocation(pTransportMgr->hProcessingQueue,
pTransportMgr->preemptionDispatchEvents,
pTransportMgr->preemptionReadBuffersReady,
pTransportMgr->preemptionCellAvailable);
processing_queue->preemptionDispatchEvents = preemptionDispatchEvents;
processing_queue->preemptionReadBuffersReady =
preemptionReadBuffersReady;
processing_queue->preemptionCellAvailable = preemptionCellAvailable;
//设置select引擎的定时器处理回调函数为MultiThreadedTimerEventHandler
RvSelectSetTimeoutInfo(pTransportMgr->pSelect,
MultiThreadedTimerEventHandler, (void *)pTransportMgr);
selectEngine->timeOutCb = timeOutCb;
selectEngine->timeOutCbContext = cbContext;
//构造消息池
pTransportMgr->hMessageMemoryBuffPool =
RA_Construct(pTransportCfg->maxBufSize, pTransportCfg->numOfReadBuffers,
NULL,pTransportCfg->pLogMgr, "Read buffers pool");
pTransportMgr->noEnoughBuffersInPool = RV_FALSE;
//消息管理模块关联传输层模块
SipMsgMgrSetTransportHandle(pStackMgr->hMsgMgr, pStackMgr->hTransport);
pMsgMgr->hTransportMgr = hTransportMgr;
二、设置一个新的定时器
RvSipMidTimerSet
//入参分别为:
// hMidMgr 中间层管理对象句柄
// miliTimeOut 定时器超时时间
//cb 定时器回调函数
//ctx 定时器回调函数参数
//出参为:
//phTimer 中间层定时器对象句柄
MidTimerSet((MidMgr*)hMidMgr, miliTimeOut, cb, ctx, (MidTimer**)phTimer);
//从中间层管理对象的hUserTimers列表中获取一个成员条目listItem
RLIST_InsertTail(pMidMgr->userTimerPool,pMidMgr->hUserTimers ,&listItem);
//使用用户设置的回调等参数,填充获取的列表条目。
pMidTimer = (MidTimer*)listItem;
pMidTimer->cb = cb;
pMidTimer->ctx = ctx;
pMidTimer->pMgr = pMidMgr;
//触发通用模块定时器构造,当前中间层定时器对象只是一个定时器的封装
//这里会向通用模块启动定时器,并传入回调函数为MidTimerFunc,该回调
//函数的参数为当前中间层定时器对象,这样当通用模块定时器触发后,调用
//中间层定时器固定的回调MidTimerFunc,该回调函数会执行用户设置的回调
//函数,并从中间层定时器列表中移除超时的定时器条目。
SipCommonCoreRvTimerStart(&pMidTimer->sipTimer, pMidMgr->pSelect,
miliTimeOut, MidTimerFunc, (void*)pMidTimer);
//转换时间格式
delay_nsec =
RvInt64Mul(RvInt64FromRvUint32(delay), RV_TIME64_NSECPERMSEC);
//启动通用模块定时器
RvTimerStart(&timer->hTimer, &pSelect->tqueue, RV_TIMER_TYPE_ONESHOT,
delay_nsec, timerCb, cbContext);
RvTimerStartEx(timer, queue, timertype, delay, (RvTimerFuncEx)(cb), ctx);
//获取当前时间
starttime = RvTimestampGet(tqueue->logMgr);
//从select引擎的定时器队列池中获取一个可用的事件对象
event = (RvTimerEvent *)RvObjPoolGetItem(&tqueue->pool);
event->timertype = timertype; // RV_TIMER_TYPE_ONESHOT
event->state = RV_TIMER_EVENTSTATE_QUEUED;
event->id++;
event->triggerlength = delay; //定时器超时时长
event->triggertime = RvInt64Add(starttime, delay);//实际超时的时刻
event->canceled = RV_FALSE;
event->userdata = userdata; // pMidTimer
event->callback = callback; //MidTimerFunc
//当新的定时器事件对象放入优先级队列中
RvPQueuePut(&tqueue->pqueue, event);
//将事件条目对象及事件ID返回给上层MID定时器对象,即
// pMidTimer->sipTimer. hTimer. Event
// pMidTimer->sipTimer. hTimer. id
timer->event = event;
timer->id = event->id;
//获取定时器队列中最小超时时间的条目
RvTimerQueueNextEvent(tqueue,&nextevent);
//更新select引擎对象的超时等待时间
RvSelectSetTimeOut((RvSelectEngine *)tqueue->selEng, starttime,
nextevent, tqueue->logMgr);
//记载select引擎需要唤醒的时间
selectEngine->wakeupTime = RvUint64Add(currentTime, nsecTimeout);
//记载select引擎的超时时间
selectEngine->nsecTimeout = nsecTimeout;
//给select引擎的抢占对象发送一个空消息,唤醒select,让其设置
//新的超时时间。
rvFdPreempt(selectEngine, RvSelectEmptyPreemptMsg);
//如果是空消息,则标记需要唤醒
if (message == RvSelectEmptyPreemptMsg)
needToWrite = RV_TRUE;
//唤醒select引擎
if (needToWrite)
RvSocketSendBuffer(&selectEngine->preemptionSocket,
&message, sizeof(RvUint8), &selectEngine->localAddress,
logMgr, NULL);
三、select引擎收到唤醒消息
RvSelectWaitAndBlock
selectEngine->waiting = RV_TRUE;
//如果之前有定时器需要设置超时时间,则从定时器及正常的select超时变量中
//取最小时间做为超时时间
if (RvUint64IsNotEqual(selectEngine->nsecTimeout, RvUint64Const(0, 0)))
nsecSelectTimeout = RvUint64Min(nsecTimeout, selectEngine->nsecTimeout);
//转换时间格式
timeout.tv_sec = RvInt64ToRvInt32(RvInt64Div(nsecSelectTimeout,
RV_TIME64_NSECPERSEC));
timeout.tv_usec = (long)(RvInt64ToRvInt32(RvInt64Mod(nsecSelectTimeout,
RV_TIME64_NSECPERSEC)) / RV_TIME_NSECPERUSEC);
tm = &timeout;
//复位所有文件描述符集
RvSelectGetSelectFds(selectEngine, &numFds, &tmpRdSet, &tmpWrSet);
selectEngine->selectThread = RvThreadCurrent();
//标记当前有定时器
selectEngine->suspectTimeout =
RvUint64IsNotEqual(selectEngine->nsecTimeout, RvUint64Const(0, 0));
selectEngine->nsecTimeout = RvUint64Const(0, 0);
select(numFds, &tmpRdSet, &tmpWrSet, NULL, tm);
selectEngine->waiting = RV_FALSE;
//如果有定时器超时标记
if(selectEngine->suspectTimeout)
selectEngine->wakeupTime = RvUint64Const(0, 0);
//处理定时器事件
RvTimerQueueService(&selectEngine->tqueue, 0, &numevents,
selectEngine->timeOutCb, selectEngine->timeOutCbContext);
//获取当前时间
curtime = RvTimestampGet(tqueue->logMgr);
do //循环处理所有超时的定时器队列事件
//获取当前最小的超时定时器事件
event = (RvTimerEvent *)RvPQueuePeek(&tqueue->pqueue);
//如果没有可处理的定时器事件,则跳出循环
if((event == NULL) || (RvInt64IsGreaterThan(event->triggertime, curtime))
||(tqueue->qState == RV_TIMERQUEUE_DISABLED &&
alternativeCb != NULL))
break;
//执行定时器超时处理回调,这里该回调函数为
// MultiThreadedTimerEventHandler,在下面单独描述
alternativeCb(alternativeCbContext);
//如果满足条件则继续处理下一个定时器超时事件
while((result == RV_OK) && (tqueue->qState != RV_TIMERQUEUE_DELETED) &&
((maxevents == 0) || (*eventcount < maxevents)));
//重新更新select引擎的超时时间
RvTimerQueueNextEvent(tqueue,&nextevent);
RvSelectSetTimeOut((RvSelectEngine *)tqueue->selEng, curtime, nextevent,
tqueue->logMgr);
-----------------------------------------------------------------------------------------------------------------------
MultiThreadedTimerEventHandler
//将定时器队列的状态设置为关闭。
// tqueue->qState = RV_TIMERQUEUE_DISABLED
RvTimerQueueControl(&pTransportMgr->pSelect->tqueue, RV_TIMERQUEUE_DISABLED);
//处理队列分配
TransportProcessingQueueAllocateEvent(pTransportMgr, NULL, TIMER_EXPIRED_EVENT,
RV_FALSE , &ev);
//从处理队列中分配一个事件资源
PQUEUE_AllocateEvent(pTransportMgr->hProcessingQueue,(HQEVENT *)ev);
(*ev)->type = TIMER_EXPIRED_EVENT; //记载事件类形
//处理尾部事件
TransportProcessingQueueTailEvent((RvSipTransportMgrHandle)pTransportMgr,ev);
PQUEUE_TailEvent(pTransportMgr->hProcessingQueue,(HQEVENT)ev);
//将分配到的事件资源插入到事件队列尾部
RLIST_InsertTail(processing_queue->hEventQueuePool,
processing_queue->hEventQueue,&listItem);
pEv = (HQEVENT*)listItem;
*pEv = ev;
//使调用RvSelectWaitAndBlock的线程继续执行,该函数给select引擎
//发送一个抢占事件。
RvSelectStopWaiting(processing_queue->pSelect,
processing_queue->preemptionDispatchEvents, processing_queue->pLogMgr);
//给select引擎发送一个消息,消息类型为preemptionDispatchEvents
rvFdPreempt(selectEngine,message);
//触发抢占函数,给select引擎发送preemptionDispatchEvents消息
RvSocketSendBuffer(&selectEngine->preemptionSocket,
&message, sizeof(RvUint8), &selectEngine->localAddress, logMgr, NULL);
四、select引擎收到preemptionDispatchEvents消息
RvSelectWaitAndBlock
selectEngine->waiting = RV_TRUE;
//设置select超时时间
nsecSelectTimeout = nsecTimeout;
//转换时间格式
timeout.tv_sec = RvInt64ToRvInt32(RvInt64Div(nsecSelectTimeout,
RV_TIME64_NSECPERSEC));
timeout.tv_usec = (long)(RvInt64ToRvInt32(RvInt64Mod(nsecSelectTimeout,
RV_TIME64_NSECPERSEC)) / RV_TIME_NSECPERUSEC);
tm = &timeout;
//复位所有文件描述符集
RvSelectGetSelectFds(selectEngine, &numFds, &tmpRdSet, &tmpWrSet);
numResults = select(numFds, &tmpRdSet, &tmpWrSet, NULL, tm);
selectEngine->waiting = RV_FALSE;
rvSelectRemoveNotify(selectEngine); //通知从该select引擎移除的FD对象可以移除了
//执行已经触发的FD
RvSelectHandleSelectFds(selectEngine, &tmpRdSet, &tmpWrSet, numFds, numResults);
RvSelectHandleSingleSelectFd(selectEngine,hasRead,hasWrite, runningSocket,
&numEvents);
//根据fd值,从HASH表中获取FD对象
fdNode = fdBucketHashFind(selectEngine, fd, NULL, NULL);
if (hasRead)
selectEvent = RV_SELECT_READ;
//将select事件转换为用户事件
RvSelectEventsToUser(&fdNode->fd, fdNode->events, logMgr, &selectEvent,
&error);
//执行文件描述符对象的回调,这里为rvFdPreemptionCallback,该函数最终调
//用指定抢占消息的对应函数,当前抢占消息为preemptionDispatchEvents,
//preemptionDispatchEvents消息对应的函数为
// TransportPreemptionSelectPreemptionDispatchEventsEvHandler
callback = fdNode->callback;
callback(selectEngine, fdNode, selectEvent, error);
==============================================================================
TransportPreemptionSelectPreemptionDispatchEventsEvHandler
//事务队列处理
TransportProcessingQueueDispatchEvents(pMgr);
while (1)
//从处理队列中取出一个待处理的事件
PQUEUE_PopEvent(pTransportMgr->hProcessingQueue,(HQEVENT*)&ev);
switch (ev->type)
case TIMER_EXPIRED_EVENT: //当前事件类型为定时器超时
//定时器超时处理。
RvTimerQueueService(&pTransportMgr->pSelect->tqueue, 0, &numevents,
NULL, NULL);
curtime = RvTimestampGet(tqueue->logMgr); //获取当前时间
//从定时器队列中获取当前最近的一个定时器事件
event = (RvTimerEvent *)RvPQueuePeek(&tqueue->pqueue);
//如果定时器不满足超时条件则退出
if((event == NULL) ||
(RvInt64IsGreaterThan(event->triggertime, curtime)) ||
(tqueue->qState == RV_TIMERQUEUE_DISABLED &&
alternativeCb != NULL))
break;
//从定时器队列中移除当前定时器事件
RvPQueueRemove(&tqueue->pqueue, event->index);
// 标记当前状态为RV_TIMER_EVENTSTATE_TRIGGERED
event->state = RV_TIMER_EVENTSTATE_TRIGGERED;
*eventcount += 1;
tqueue->callcount += 1;
//填充回调参数
timerInfo.event = event;
timerInfo.id = event->id;
//执行每个定时器自身设置的回调函数
event->callback(event->userdata, &timerInfo);
tqueue->callcount -= 1;
//根据当前定时器类型是否是循环类型来执行不同流程,如果是循环
//类型则将定时器事件再次丢入定时器队列中,否则将定时器事件从
//事件池中移除。
//将定时器队列的状态标为已经开启状态。
//tqueue->qState = RV_TIMERQUEUE_ENABLED;
RvTimerQueueControl(&pTransportMgr->pSelect->tqueue,
RV_TIMERQUEUE_ENABLED);
//释放已经处理的事件
PQUEUE_FreeEvent(pTransportMgr->hProcessingQueue,(HQEVENT)ev);
Rv定时器实现
最新推荐文章于 2021-02-19 16:52:51 发布