前因
在 创建 live555 服务的时候
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
会创建
BasicTaskScheduler0::BasicTaskScheduler0()
: fLastHandledSocketNum(-1)
, fTriggersAwaitingHandling(0)
,fLastUsedTriggerMask(1)
,fLastUsedTriggerNum(MAX_NUM_EVENT_TRIGGERS-1)
{
fHandlers = new HandlerSet; //初始化 HandlerSet 实例fHandlers
//....
}
但是在创建rtspserver 的时候 执行 assignHandler
fHandlers->assignHandler(socketNum, conditionSet, handlerProc, clientData);
进一步查看源码
发现被 HandlerSet HandlerDescriptor HandlerIterator 的关系绕晕了,所以特地拉出来分析
因为 HandlerSet 实例 fHandlers ,但是 HandlerSet 类中私有HandlerDescriptor 实例也是fHandlers,所以看代码的时候要特别注意
首先查看HandlerSet对象 声明 ,用来事件处理
class HandlerSet {
public:
HandlerSet();
virtual ~HandlerSet();
void assignHandler(int socketNum, int conditionSet, TaskScheduler::BackgroundHandlerProc* handlerProc, void* clientData);
void clearHandler(int socketNum);
void moveHandler(int oldSocketNum, int newSocketNum);
private:
HandlerDescriptor* lookupHandler(int socketNum);
private:
friend class HandlerIterator;
HandlerDescriptor fHandlers;//就是这个对象,在看源码的时候要注意
};
HandlerDescriptor 相当与一个基本单元对象 存放有前节点地址 后节点地址
class HandlerDescriptor {
HandlerDescriptor(HandlerDescriptor* nextHandler);
virtual ~HandlerDescriptor();
public:
int socketNum;
int conditionSet;
TaskScheduler::BackgroundHandlerProc* handlerProc;
void* clientData;
private:
// Descriptors are linked together in a doubly-linked list:
friend class HandlerSet;
friend class HandlerIterator;
HandlerDescriptor* fNextHandler;
HandlerDescriptor* fPrevHandler;
};
HandlerIterator 类 迭代器,遍历 HandlerDescriptor
class HandlerIterator {
public:
HandlerIterator(HandlerSet& handlerSet);
virtual ~HandlerIterator();
HandlerDescriptor* next(); // returns NULL if none
void reset();
private:
HandlerSet& fOurSet;
HandlerDescriptor* fNextPtr;
};
分析逻辑源码
逻辑代码 在进行 assignHandler时
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;
}
- 在HandlerDescriptor 和socketNum 对应关系表 查看socketNum 对应的HandlerDescriptor
- 如果没有找到,即handler == NULL 重新创建HandlerDescriptor 和 socketNum 的关系
- 初始化HandlerDescriptor 的三个变量conditionSet (条件集合) handlerProc(处理方法) clientData(被处理的对象)
很明显需要查看 lookupHandler 函数 .这个函数有点绕
HandlerDescriptor* HandlerSet::lookupHandler(int socketNum) {
HandlerDescriptor* handler;
HandlerIterator iter(*this);
while ((handler = iter.next()) != NULL) {
if (handler->socketNum == socketNum) break;
}
return handler;
}
上面的代码通过HandlerIterator 遍历获取HandlerDescriptor的实例 handler ,但是HandlerIterator迭代器用HandlerSet来初始化 这里的this是 正在运行HandlerSet 实例fHandlers
根据上面 类的声明, HandlerSet& fOurSet; 是 HandlerIterator 私有变量,带参数的构造
查看 HandlerIterator 构造函数实现
HandlerIterator::HandlerIterator(HandlerSet& handlerSet)
: fOurSet(handlerSet) {
reset();
}
void HandlerIterator::reset() {
fNextPtr = fOurSet.fHandlers.fNextHandler;
}
初始化 fOurSet 后 ,就开始遍历查看 next()实现
HandlerDescriptor* HandlerIterator::next() {
HandlerDescriptor* result = fNextPtr;
if (result == &fOurSet.fHandlers) { // no more
result = NULL;
} else {
fNextPtr = fNextPtr->fNextHandler;
}
return result;
}
这里 有 fNextPtr 和 fNextPtr = fNextPtr->fNextHandler; 就说明 HandlerIterator next()是进行链表的下一个元素访问
如果fNextPtr 存在 ,fNextPtr就变成访问 下一个元素 HandlerDescriptor ,但是 当前HandlerDescriptor 被赋值在result 和 &fOurSet.fHandlers 相同就为null,这样就说明 这个socketnum 和HandlerDescriptor 对应关系存在,不用增加
这里的 fOurSet就是HandlerSet fHandlers ,fHandlers .fHandlers 就是访问 成员变量HandlerDescriptor fHandlers
但是这里是第一次创建 所以返回null ,因此最后会创建一个HandlerDescriptor 和 socketnum 关系
if (handler == NULL) { // No existing handler, so create a new descr:
handler = new HandlerDescriptor(fHandlers.fNextHandler);
handler->socketNum = socketNum;
}
HandlerDescriptor::HandlerDescriptor(HandlerDescriptor* nextHandler)
: conditionSet(0), handlerProc(NULL) {
// Link this descriptor into a doubly-linked list:
if (nextHandler == this) { // initialization
fNextHandler = fPrevHandler = this;
} else {
fNextHandler = nextHandler;
fPrevHandler = nextHandler->fPrevHandler;
nextHandler->fPrevHandler = this;
fPrevHandler->fNextHandler = this;
}
}
这个实现思想,也是很绕的,基本上就是这个看代码思路
总结下, HandlerIterator 操作的其实是HandlerDescriptor 的上一个节点地址和下一个节点地址,而HandlerSet用来保存实例 HandlerDescriptor,最后将自己送给 HandlerIterator,被HandlerIterator 迭代器操作,准确来说操作的是保存在HandlerSet 中的HandlerDescriptor 实例
反正代码逻辑怪怪的,决定只需要记住功能就好了,主要是跟踪 socket 才分析的