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

本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso

HandlerSet 处理程序链表类

这里使用的Set这个单词,Set是集合的意思,这里实质上是一个双向循环链表。这个类比较重要,这里会详细的介绍。
HandlerSet类只有一个数据成员,就是HandlerDescriptor fHandlers;这是作为链表的头结点而存在的。



HandlerSet的定义,代码如下

class HandlerSet {
public://设置fHandlers的下一个和上一个指向fHandler自己HandlerSet();//逐个释放链表节点virtual ~HandlerSet();// 从链表中查找socketNum代表的HandlerDescriptor,如果没有找到就创建一个并加入到链表void assignHandler(int socketNum, int conditionSet, TaskScheduler::BackgroundHandlerProc* handlerProc, void* clientData);//从链表中查找socketNum对应的HandlerDescriptor,找到了就deletevoid clearHandler(int socketNum);// 从链表中查找oldSocketNum代表的HandlerDescriptor,找到了就将其sockerNum成员替换为newSocketNumvoid moveHandler(int oldSocketNum, int newSocketNum);
private:// 从链表中查找socketNum代表的HandlerDescriptor,没找到返回NULLHandlerDescriptor* lookupHandler(int socketNum);
private:friend class HandlerIterator;HandlerDescriptor fHandlers;    //处理程序描述对象 链表头节点
};

HandlerSet的构造

在其构造函数中,默认对头结点HandlerDescriptor fHandlers进行了初始化操作。

HandlerSet::HandlerSet(): fHandlers(&fHandlers) {fHandlers.socketNum = -1; // shouldn't ever get looked at, but in case...
}

这里调用了HandlerDescriptor的构造,这个可以在之前的介绍中查看。这里可以看到,其将头结点的数据成员socketNum设置为了-1,之前我们说过,socketNum在链表中被用来标识节点,这里说明了其是一个特殊的存在,头结点不做为保存处理程序的节点。


HandlerSet的析构

析构函数就是释放链表,就是逐个释放除了头结点之外的节点。代码如下

HandlerSet::~HandlerSet() {// Delete each handler descriptor:while (fHandlers.fNextHandler != &fHandlers) {delete fHandlers.fNextHandler; // changes fHandlers->fNextHandler}
}

lookupHandler方法

这里先说这个方法,因为后面的几个方法都用到了它。从方法名也可以看出来,这个方法是用来查找节点的。
这里要说以下的就是,这里面用到了迭代器。方法中创建了一个迭代器,并将自身绑定给了迭代器。前面说过迭代器构造的时候会将其fNextPtr指向链表的头结点的下一个。也就是说会从第二个节点开始查找。如果本身就只有头节点呢?因为在只有头结点的情况下,下一个节点就是头结点,其socketNum为-1,这里是没问题的。

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

assignHandler(分配处理程序)方法

通过前面的描述可知,HandlerSet类都是在操作内部的一个双向链表。但是HandlerSet是没有一个addNode方法的,这个方法就由assignHandler来做了。
assignHandler的参数有四个,对应了一个节点对象的四个数据成员** socketNum/conditionSet/handlerProc/clientData **。前面说过socketNum成员在链表中用来标识节点,在这个成员方法中就可以看出来。这个方法会在BasicTaskScheduler的setBackgroundHandling方法中被用到。其socketNum参数应该是传一个socket套接口给它。
assignHandler方法先是从链表中查找socketNum标识的节点是否存在,如果不存在就new一个,并设置新节点的socketNum为参数的socketNum。这样链表中就存在了一个标识为参数socketNum的节点。然后把这个节点的 处理程序指针,客户端数据地址,条件集合都更新为参数中的。

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;
}

clearHandler和moveHandler方法

这两个方法比较类似,放在一起来说。
clearHandler方法是从链表中找socketNum标识的节点,然后delete这个节点。有之前的描述可以知道,这里把找到的节点从链表中移除了。如果没有找到呢? lookupHandler会返回NULL,delete NULL,是可以的。

void HandlerSet::clearHandler(int socketNum) {HandlerDescriptor* handler = lookupHandler(socketNum);delete handler;
}
  • moveHandler则是从链表中找oldSocketNum标识的节点,找到了就将其标识替换为newSocketNum。如果没有找到就声明也不做了。这里和前面说的assignHandler方法来对比下。assignHandler是找到了就替换其他的三个数据成员,这里是找到了就替换标识。
void HandlerSet::moveHandler(int oldSocketNum, int newSocketNum) {HandlerDescriptor* handler = lookupHandler(oldSocketNum);if (handler != NULL) {handler->socketNum = newSocketNum;}
}

转载于:https://www.cnblogs.com/oloroso/p/4596843.html

7 HandlerSet 处理程序链表类——Live555源码阅读(一)基本组件类相关推荐

  1. 12 哈希表相关类——Live555源码阅读(一)基本组件类

    12 哈希表相关类--Live555源码阅读(一)基本组件类 这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 ...

  2. 16 BasicHashTable基本哈希表类(三)——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  3. 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  4. 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment

    24 UsageEnvironment使用环境抽象基类--Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类--Live555源码阅读 ...

  5. 17 任务调度相关类综述——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  6. live555 源码分析:RTSPServer 组件结构

    前面几篇文章分析了 live555 中 RTSP 的处理逻辑,RTSP 处理有关组件的处理逻辑有点复杂,本文就再来梳理一下它们之间的关系. live555 中 RTSP 处理有关组件关系如下图: 事件 ...

  7. Live555源码阅读笔记(一):源码介绍文档 及 源码目录结构

    目录 一.Live555介绍 1.Live555项目介绍 2.官网及帮助文档介绍 二.源码目录结构 1.UsageEnvironment 2.BasicUsageEnvironment 3.group ...

  8. 39 网络相关函数(七)——live555源码阅读(四)网络

    39 网络相关函数(七)--live555源码阅读(四)网络 39 网络相关函数(七)--live555源码阅读(四)网络 简介 14)readSocket从套接口读取数据 recv/recvfrom ...

  9. Live555源码阅读笔记(四):groupsock 目录详解

    一.groupsock 目录介绍 groupsock 目录总共有16个源码文件,编译后生成 libgroupsock.a,这个库中的类封装了网络接口和套接字,特别是"Groupsock&qu ...

  10. Yii源码阅读笔记 - 日志组件

    2015-03-09 一 By youngsterxyf 使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category); Yii: ...

最新文章

  1. LeetCode Linked List Random Node(蓄水池采样算法)
  2. Array Splitting
  3. 使用freemarker生成xml模板
  4. C语言求最大公约数GCD的算法(附完整源码)
  5. 数据结构简答题和论述题
  6. mysql操作入门(四)-----数据排序(升序、降序、多字段排序)
  7. 刷屏的海底捞超级APP究竟是怎样与阿里云合作的
  8. TP、TN、FP、FN、Recall、Miss Rate、MCC、F1 Score 等指标计算
  9. EA 2022 HSN Plugfest- UNH-IOL以太网联盟高速以太网插拔互操作性测试活动[多图] 400G/800G/112G PAM4
  10. 仿b站demo(效果图)
  11. 升级云服务器的python3,导致宝塔面板打不开
  12. 华为mate20 pro Android,被谷歌移除的华为Mate 20 Pro重回Android Q名单
  13. strcpy()、strncpy()函数
  14. Spring系列学习之Spring Mobile
  15. python命令行窗口最大化_基于python的豆瓣FM(终端命令行界面)
  16. 20180402-C · US Tuition Costs · ggplot2, 地图 热力图 · R 语言数据可视化 案例 源码
  17. 谷歌时代结束 - Google中国名称已经改回
  18. 给oracle scott权限,Oracle Scott创建视图权限不足解决办法
  19. 强烈推荐iOS开发取色器
  20. 数据库连接报错:1086 - Unknown storage engine ‘InnoDB‘

热门文章

  1. 20 道 Redis 面试题,面试官能问的都被我找到了
  2. Ubuntu 网速显示,ssh配置
  3. 如何开始学习使用TensorFlow?
  4. Codeforces Round #468 (Div. 2, based on Technocup 2018 Final Round)
  5. java 静态相关内容
  6. setCompoundDrawables和setCompoundDrawablesWithIntrinsicBounds区别
  7. 如何使用Java读写系统属性?
  8. C语言函数指针简单应用
  9. Win7虚拟Wifi热点(设置后能连接wifi但无法上网的可按后面提示操作)
  10. Requirements Analysis with 'pseud-Formal' Method