Rv定时器实现

一、模块初始化
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);


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值