1.介绍
处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系。处理程序相关类主要是用于对相关的处理函数的指针和数据的包装,方便在DelayQueue相关类中的使用等。
先来总的说以下三个类的关系。
HandlerDescriptor是一个节点类,而HandlerSet是一个链表类,链表节点就是HandlerDescriptor对象。HandlerIterator是一个迭代器类,其绑定一个HandlerSet对象。
处理程序相关的三个类都定义在live555sourcecontrol\BasicUsageEnvironment\include\HandlerSet.hh文件中。
1.1. HandlerDescriptor
// 处理程序描述类(作为链表的节点)
//构造和析构都是private权限的,因为只能在其友元类HandlerSet中来调用
// 如果nextHandler为其自身,自身就是双向链表的头结点
// 否则将自身插入到nextHandler和nextHandler->fPrevHandler之间
class HandlerDescriptor {
HandlerDescriptor(HandlerDescriptor* nextHandler);
virtual ~HandlerDescriptor();// 将自身从双向链表中移除。这个函数一般由delete操作来调用
public:
int socketNum; //socket在链表里面用来标识节点
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;/上一个处理程序描述
};
- HandlerDescriptor构造函数
从其构造函数可以看出,其默认只被用于链表中作为节点存在。并且这个构造函数是private权限的,只有在本类或者友元类中可以使用其来构造对象。
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;
}
}
- HandlerDescriptor析构函数
从其析构函数可以看出,并不仅仅是将自身释放,而且将节点从链表中移除了。
HandlerDescriptor::~HandlerDescriptor() {
// Unlink this descriptor from a doubly-linked list:
fNextHandler->fPrevHandler = fPrevHandler;
fPrevHandler->fNextHandler = fNextHandler;
}
1.2. HandlerSet
双向循环链表,HandlerSet类只有一个数据成员,就是HandlerDescriptor fHandlers;这是作为链表的头结点而存在的。
class HandlerSet {
public:
HandlerSet();//设置fHandlers的下一个和上一个指向fHandler自己
virtual ~HandlerSet();//逐个释放链表节点
// 从链表中查找socketNum代表的HandlerDescriptor,如果没有找到就创建一个并加入到链表
void assignHandler(int socketNum, int conditionSet, TaskScheduler::BackgroundHandlerProc* handlerProc, void* clientData);
//从链表中查找socketNum对应的HandlerDescriptor,找到了就delete
void clearHandler(int socketNum);
// 从链表中查找oldSocketNum代表的HandlerDescriptor,找到了就将其sockerNum成员替换为newSocketNum
void moveHandler(int oldSocketNum, int newSocketNum);
private:
// 从链表中查找socketNum代表的HandlerDescriptor,没找到返回NULL
HandlerDescriptor* lookupHandler(int socketNum);
private:
friend class HandlerIterator;
HandlerDescriptor fHandlers;
};
1.3. HandlerIterator
HandlerIterator是一个迭代器类,其有两个数据成员,分别是HandlerSet类对象的引用fOurSet,以及一个HandlerDescriptor对象指针fNextPtr。并且HandlerIterator同时是节点和链表的友元类。
fOurSet是一个引用,就说明了HandlerIterator的初始化必须要绑定一个HandlerSet对象。而HandlerSet类的对象又是一个链表,其节点是HandlerDescriptor对象。迭代器对象仅在HandlerSet类中使用。
迭代器构造的时候,会将其fNextPtr指向链表的头节点的下一个。
class HandlerIterator {
public:
HandlerIterator(HandlerSet& handlerSet);
virtual ~HandlerIterator();
HandlerDescriptor* next(); // 返回fNextPtr,并将fNextPtr指向下一个处理程序描述对象
void reset();//将 fNextPtr 指向链表的头结点的下一个
private:
HandlerSet& fOurSet;
HandlerDescriptor* fNextPtr;
};