6 HandlerDescriptor 处理程序描述类——Live555源码阅读(一)基本组件类

这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类。

本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso/

HandlerDescriptor 处理程序描述类

HandlerDescriptor类是一个很重要的类,其保存了处理程序的函数指针和相关的数据的地址。在构建处理任务的时候,会使用到这个类的对象,处理任务的时候也会用到。
HandlerDescriptor类同时将HandlerIterator类和HandlerSet类声明为友元类,方便了后面链表的操作。个人觉得这种封装方式不是特别好。只是个人看法而已。

这里的封装还有一个原因就是因为构造和析构都是private权限的,因为只能在其友元类HandlerSet中来调用,避免暴露接口。

这里要特别提一下数据成员socketNum和conditionSet。socketNum在链表中要来标识一个节点,那么这socketNum的值是如何赋值来的呢?这里先提一下,在使用到这个类对象的时候,会将一个socket套接口作为其值(windows下是SOCKET类型linux/unix下是文件描述符,其实质都是int类型),它必然是唯一的。这个变量名取为socketNum就是因为后面它将用于网络。而conditionSet是条件集合的意思,用来标识对应socketNum代表的套接口可以采取那写操作(读/写/异常)。

还有注意的是handlerProc的类型是一个类成员函数指针,它应该指向一个TaskScheduler的函数成员地址。(《C++必知必会》一个指向成员的指针并不指向一个具体的内存地址,它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员。)

HandlerDescriptor


下面是HandlerDesciptor类的定义

// 处理程序描述类(作为链表的节点)
class HandlerDescriptor {
//构造和析构都是private权限的,因为只能在其友元类HandlerSet中来调用
	// 如果nextHandler为其自身,自身就是双向链表的头结点
	// 否则将自身插入到nextHandler和nextHandler->fPrevHandler之间
	HandlerDescriptor(HandlerDescriptor* nextHandler);
	// 将自身从双向链表中移除。这个函数一般由delete操作来调用
	virtual ~HandlerDescriptor();
public:
	int socketNum;	//socket在链表里面用来标识节点
	int conditionSet;	//条件集合
//typedef void BackgroundHandlerProc(void* clientData, int mask);
	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;
}
原文地址:https://www.cnblogs.com/oloroso/p/4596836.html