调用示例
// 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;
}