live555源码分析(一):BasicTaskScheduler事件循环

调用示例

// testRTSPClient.cpp
int main(int argc, char** argv) {
  TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);

  if (argc < 2) {
    usage(*env, argv[0]);
    return 1;
  }
  
  for (int i = 1; i <= argc-1; ++i) {
    openURL(*env, argv[0], argv[i]);
  }

  // 后续的活动都发生在事件循环中
  env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
    
  return 0;
}

源码分析

入口函数

整个流程是跑在一个while循环中,主要的功能是监听socket事件(读、写、错误等事件),采用的IO多路复用机制是select。

void BasicTaskScheduler0::doEventLoop(char volatile* watchVariable) {
  while (1) {
    if (watchVariable != NULL && *watchVariable != 0) break;
    SingleStep();
  }
}

SingleStep函数

这部分省略了部分代码,梳理下主要的流程如下:

1)select多路复用机制来处理多路I/O;

2)通过while循环执行任务,执行完成一个即break;

3)如果找完了依然没有找到,继续从头找;

4)事件响应(主要代码:(*fTriggeredEventHandlers[fLastUsedTriggerNum])(fTriggeredEventClientDatas[fLastUsedTriggerNum]);)

5)处理延迟任务;

void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) 
{
	…
	
	//  通过select多路复用机制来处理多路I/O   更好的解决方案epoll
	int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
	
	…
	
	//  只执行一个任务 执行完直接break
	while ((handler = iter.next()) != NULL) {
	    int sock = handler->socketNum; // alias
	    int resultConditionSet = 0;
	
	    // 读、写、错误等事件回调
	    if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
	    if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
	    if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
	    if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
	      fLastHandledSocketNum = sock;
	      // 事件回调函数
	      (*handler->handlerProc)(handler->clientData, resultConditionSet);
	      break;
	    }
	  }
	  
	// 如果找完了依然没有找到 从头找
	if (handler == NULL && fLastHandledSocketNum >= 0) {
	    // We didn't call a handler, but we didn't get to check all of them,
	    // so try again from the beginning:
	    iter.reset();
	    while ((handler = iter.next()) != NULL) {
	      int sock = handler->socketNum; // alias
	      int resultConditionSet = 0;
	      if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
	      if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
	      if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
	      if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
		fLastHandledSocketNum = sock;
		// 事件回调
		(*handler->handlerProc)(handler->clientData, resultConditionSet);
		break;
	      }
	    }
	    if (handler == NULL) fLastHandledSocketNum = -1;//because we didn't call a handler
	  }
	
	 …
	
	// 响应事件
	if (fTriggersAwaitingHandling != 0) {
	    if (fTriggersAwaitingHandling == fLastUsedTriggerMask) {
	      // Common-case optimization for a single event trigger:
	      fTriggersAwaitingHandling &=~ fLastUsedTriggerMask;
	      if (fTriggeredEventHandlers[fLastUsedTriggerNum] != NULL) {
		(*fTriggeredEventHandlers[fLastUsedTriggerNum])(fTriggeredEventClientDatas[fLastUsedTriggerNum]);
	      }
	    } else {
	      unsigned i = fLastUsedTriggerNum;
	      EventTriggerId mask = fLastUsedTriggerMask;
	
	      do {
		i = (i+1)%MAX_NUM_EVENT_TRIGGERS;
		mask >>= 1;
		if (mask == 0) mask = 0x80000000;
	
		if ((fTriggersAwaitingHandling&mask) != 0) {
		  fTriggersAwaitingHandling &=~ mask;
		  if (fTriggeredEventHandlers[i] != NULL) {
		    (*fTriggeredEventHandlers[i])(fTriggeredEventClientDatas[i]);
		  }
	
		  fLastUsedTriggerMask = mask;
		  fLastUsedTriggerNum = i;
		  break;
		}
	      } while (i != fLastUsedTriggerNum);
	    }
	  }
	
	// 处理延迟任务
	fDelayQueue.handleAlarm();
}

HandlerDescriptor

实现一个双向链表,调度任务通过链表进行增删改查。

HandlerDescriptor::HandlerDescriptor(HandlerDescriptor* nextHandler)
  : conditionSet(0), handlerProc(NULL) {
  if (nextHandler == this) {
    fNextHandler = fPrevHandler = this;
  } else {
    fNextHandler = nextHandler;
    fPrevHandler = nextHandler->fPrevHandler;
    nextHandler->fPrevHandler = this;
    fPrevHandler->fNextHandler = this;
  }
}

HandlerDescriptor::~HandlerDescriptor() {
  fNextHandler->fPrevHandler = fPrevHandler;
  fPrevHandler->fNextHandler = fNextHandler;
}

// HandlerSet: 节点管理
HandlerSet::HandlerSet()
  : fHandlers(&fHandlers) {
  fHandlers.socketNum = -1; 
}

HandlerSet::~HandlerSet() {
  while (fHandlers.fNextHandler != &fHandlers) {
    delete fHandlers.fNextHandler;
  }
}

void HandlerSet
::assignHandler(int socketNum, int conditionSet, TaskScheduler::BackgroundHandlerProc* handlerProc, void* clientData) {
  // First, see if there's already a handler for this socket:
  HandlerDescriptor* handler = lookupHandler(socketNum);
  if (handler == NULL) { // No existing handler, so create a new descr:
    handler = new HandlerDescriptor(fHandlers.fNextHandler);
    handler->socketNum = socketNum;
  }

  handler->conditionSet = conditionSet;
  handler->handlerProc = handlerProc;
  handler->clientData = clientData;
}

void HandlerSet::clearHandler(int socketNum) {
  HandlerDescriptor* handler = lookupHandler(socketNum);
  delete handler;
}

void HandlerSet::moveHandler(int oldSocketNum, int newSocketNum) {
  HandlerDescriptor* handler = lookupHandler(oldSocketNum);
  if (handler != NULL) {
    handler->socketNum = newSocketNum;
  }
}

HandlerDescriptor* HandlerSet::lookupHandler(int socketNum) {
  HandlerDescriptor* handler;
  HandlerIterator iter(*this);
  while ((handler = iter.next()) != NULL) {
    if (handler->socketNum == socketNum) break;
  }
  return handler;
}

// HandlerIterator: 节点迭代器管理
HandlerIterator::HandlerIterator(HandlerSet& handlerSet)
  : fOurSet(handlerSet) {
  reset();
}

HandlerIterator::~HandlerIterator() {
}

void HandlerIterator::reset() {
  fNextPtr = fOurSet.fHandlers.fNextHandler;
}

HandlerDescriptor* HandlerIterator::next() {
  HandlerDescriptor* result = fNextPtr;
  if (result == &fOurSet.fHandlers) { // no more
    result = NULL;
  } else {
    fNextPtr = fNextPtr->fNextHandler;
  }

  return result;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值