19 BasicTaskScheduler0 基本任务调度类基类(一)——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类。任务调度是Live555源码中很重要的部分。
本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso/
本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso
BasicTaskScheduler0 基本任务调度类基类
BasicTaskScheduler0是一个用作传递的类,它继承自TaskScheduler,又派生出BasicTaskScheduler。其定义在live555sourcecontrol\UsageEnvironment\include\BasicUsageEnvironment0.hh文件中。
这个类实现了TaskScheduler中的纯虚接口,并增加了一些数据成员。其中比较重要的两个是fDelayQueue(延时队列)和fHandlers(处理程序集合/链表)。


下面是其定义代码,里面有一些是对注释的翻译。
class HandlerSet; // forward
#define MAX_NUM_EVENT_TRIGGERS 32
// An abstract base class, useful for subclassing 抽象基类,用于子类化
// (e.g., to redefine the implementation of socket event handling)
// 例如,重新定义socket事件处理的实现
class BasicTaskScheduler0 : public TaskScheduler {
public:
//析构的时候 delete fHandlers
virtual ~BasicTaskScheduler0();
//设置select轮询的超时时间的最大值,如果maxDelatTime不大于0,那么就设置为一百万秒
virtual void SingleStep(unsigned maxDelayTime = 0) = 0;
// "maxDelayTime" is in microseconds. It allows a subclass to impose a limit
// maxDelayTime 单位是微秒,它允许一个子类施加限制
// on how long "select()" can delay, in case it wants to also do polling.
// 多长时间”select()”可以延迟,如果它想做轮询。
// 0 (the default value) means: There's no maximum; just look at the delay queue
// 0作为默认值,意思是:没有最大;只是看看延迟队列
public:
// Redefined virtual functions:重新定义虚函数
/* 调度延时任务
* 1、创建一个AlarmHandler对象(定时处理);(new AlarmHandler(proc, clientData, timeToDelay);)
* 2、将创建的alarmHandler对象添加到fDelayQueue中;(fDelayQueue.addEntry(alarmHandler))
* 3、返回这个alarmHandler的token标志
*/
virtual TaskToken scheduleDelayedTask(int64_t microseconds, TaskFunc* proc,
void* clientData);
/* 取消调度延时任务
* 1、从fDelayeQueue中removeEntry这个prevTask
* 2、设置prevTask=NULL
* 3、delete这个prevTask标识的alarmHandler对象
*/
virtual void unscheduleDelayedTask(TaskToken& prevTask);
/* 做事件循环
* 1、判断watchVariable !=0 && *watchVariable != 0是否成立,若成立,函数返回
* 2、调用函数SingleStep();函数返回后继续做步骤1
*/
virtual void doEventLoop(char* watchVariable);
/* 创建事件触发器ID
* 从fTriggeredEventHandlers数组中寻找一个没有使用的位置 pos。如果没有空位,函数返回0
* 将eventHandlerProc放置到上述数组 pos 位置
* 将fTriggeredEventClientDatas数组 pos 位置置为NULL
* 设置fLastUsedTriggerMask的第 pos 位为1
* 设置fLastUsedTriggerNum为 pos
* 返回fLastUsedTriggerMask的值
*/
virtual EventTriggerId createEventTrigger(TaskFunc* eventHandlerProc);
/* 删除事件触发器 eventTriggerId可能代表多个事件触发器
* 设置 fTriggersAwaitingHandling &=~ eventTriggerId
* 即将fTriggersAwaitingHandling中对应于eventTriggerId的非零位 置零
* 从fTriggeredEventHandlers和fTriggeredEventClientDatas中将对应的位置置为NULL
*/
virtual void deleteEventTrigger(EventTriggerId eventTriggerId);
/* 触发事件
* 从fTriggeredEventClientDatas找到eventTriggerId对应的位置,设置为clientData
* 将fTriggersAwaitingHandling中对应eventTriggerId中的非0位置为1
*/
virtual void triggerEvent(EventTriggerId eventTriggerId, void* clientData = NULL);
protected:
BasicTaskScheduler0();
protected:
// implement vt.实施,执行; 使生效,实现; 落实(政策); 把…填满;n.工具,器械; 家具; 手段;[法]履行(契约等);
// To implement delayed operations: 实施延迟操作:
DelayQueue fDelayQueue;
// To implement background reads: 实施后台读
HandlerSet* fHandlers; //处理程序描述对象链表指针
int fLastHandledSocketNum; //当前最近一个调度的HandlerDescriptor对象的socketNum标识
// To implement event triggers: 实施时间触发器
// fTriggersAwaitingHandling触发等待处理的 fLastUsedTriggerMask 最后使用触发器的位置置1
// implemented as 32-bit bitmaps 实现是32位的比特位图
EventTriggerId fTriggersAwaitingHandling, fLastUsedTriggerMask;
TaskFunc* fTriggeredEventHandlers[MAX_NUM_EVENT_TRIGGERS]; //保存事件触发器
void* fTriggeredEventClientDatas[MAX_NUM_EVENT_TRIGGERS]; //保存触发事件客户端数据
unsigned fLastUsedTriggerNum; // in the range(范围) [0,MAX_NUM_EVENT_TRIGGERS) 最后使用触发器的
};
BasicTaskScheduler0的构造与析构
BasicTaskScheduler0的构造内容不多,但是从这里开始要介绍的东西很多。还有注意,这个构造函数是protected权限的。
先来分析一下它的各个数据成员。
int fLastHandledSocketNum; 从字面意思来看,这个成员的意思是保存最后一个处理socket的。但是这只是猜测。这里我们回到前面去看HandlerDescriptor类的定义。其类定义中有一个成员socketNum,用来表示HandlerDescriptor在链表中的唯一存在。是不是这两者就有关联了呢?没错,确实是这样的。这个变量代表的是最后一个被加入的HandlerDescriptor对象。
fTriggersAwaitingHandling和fLastUsedTriggerMask这两个一起来说。
这两者的类型是EventTriggerId,实质上是无符号32未整型(u_int32_t)。这两个变量和后面的两个数组对应起来看,这两个数组都是MAX_NUM_EVENT_TRIGGERS个元素的,也就是32。而这里两个变量是32bit,它们的每一个位与数组的一个元素对应是否就刚刚好呢?这里先不说,后面会解释的。(fTriggersAwaitingHandling等待触发集,fLastUsedTriggerMask最近使用的触发器)
fLastUsedTriggerNum这个参数表示的是最后一个使用触发器的位置(在fTriggeredEventHandlers数组中的下标)。它的范围是[0,31]。将其初始化为31,是因为每一次创建触发器的时候会使用这个值。见createEventTriggerd方法。
数组fTriggeredEventHandlers用于保存事件处理程序函数地址,它的每一个元素是一个函数指针。
数组fTriggeredEventClientDatas用于保存事件处理程序函数调用时候的参数,它的元素是void*类型。
DelayQueue fDelayQueue;是一个延时队列,前面介绍过。用于延时处理事件。注意这里这个链表的节点将是AlarmHandler对象。
HandlerSet* fHandlers;这一个用于保存事件处理程序和其客户数据。要注意的是这里是一个指针,而不是对象。在构造的时候创建了一个对象。

BasicTaskScheduler0::BasicTaskScheduler0()
: fLastHandledSocketNum(-1), fTriggersAwaitingHandling(0), fLastUsedTriggerMask(1), fLastUsedTriggerNum(MAX_NUM_EVENT_TRIGGERS-1) {
fHandlers = new HandlerSet; //创建对象
for (unsigned i = 0; i < MAX_NUM_EVENT_TRIGGERS; ++i) {
fTriggeredEventHandlers[i] = NULL;
fTriggeredEventClientDatas[i] = NULL;
}
}
BasicTaskScheduler0的析构就简单很多了。前面说了,只要一个成员fHandlers是指针的,并且在构造的时候动态创建了一个对象给它。所以析构的时候就只是将其delete了。
BasicTaskScheduler0::~BasicTaskScheduler0() {
delete fHandlers;
}
19 BasicTaskScheduler0 基本任务调度类基类(一)——Live555源码阅读(一)任务调度相关类的更多相关文章
- 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类
21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...
- 20 BasicTaskScheduler0 基本任务调度类基类(二)——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
- 3 EventTime 事件时间类和TimeNow函数——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 这里是时间相关类的第三个部分,也是最后一个部分. EventTime 事件时间类 这个类和Dela ...
- 12 哈希表相关类——Live555源码阅读(一)基本组件类
12 哈希表相关类--Live555源码阅读(一)基本组件类 这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 ...
- 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
- 17 任务调度相关类综述——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
- 11 AlarmHandler定时处理类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- 10 DelayQueue 延时队列类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 www.cnblogs.com/oloroso/ 本文由乌合 ...
- 9 DelayQueueEntry 延时队列节点类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
随机推荐
- Java——包的概念及使用
package是在使用多个类或接口时,为了避免名称重复而采用的一种措施,直接在程序中加入package关键字即可 编译语法: javac -d . HelloWord.java -d:表示生成目录,生 ...
- SublimeText2使用笔记
将Sublime Text2 加入右键菜单(转) 1. 运行中输入 regedit 打开注册表 2. 在HKEY_CLASSES_ROOT/*/shell/ 下新建’项’ ,名称自己觉得.我用的是Su ...
- 安卓官方ViewPager与android.support.design.widget.TabLayout双向交互联动切换 。
该TabLayout的功用,简单的说,就是当用户在该TabLayout的选项卡子item中选择触摸时候,文字和下方的指示器横条滑动指示.android.support.design.widget.Ta ...
- Comet、SSE、技术
1.概念: 利用长时间保留的HTTP请求(‘挂起的GET’)来让服务器向浏览器推送数据的技术,经常被称为Comet. SSE让服务器可以向客户端流式发送文本消息,比如服务器上生成的实时通知或更新.
- 如何在Flash Builder里新建ActionScript工程
新建ActionScript工程 1. File > New > ActionScript Project 2. 按照提示完成工程的创建 使程序直接在Flash Player中运行 1. ...
- 扩展struts2的结果集StrutsResultSupport 自定义Result处理JSON
以前在采用Struts2开发的项目中,对JSON的处理一直都在Action里处理的,在Action中直接Response,最近研读了一下Struts2的源码,发现了一个更加优雅的解决办法,自己定义一个 ...
- MySQL里的found_row()与row_count()的解释及用法
MySQL中有两个函数来计算上一条语句影响了多少行,不同于SqlServer/Oracle,不要因为此方面的差异而引起功能问题 出处:mysqlpub.com MySQL中有两个函数来计算上一条语 ...
- jq实现点击弹出框代码
废话不多说,先贴代码吧 <script> function showBg() { //定义 showBg 函数 var bh = $("body").height(); ...
- youku的视频代码放到网站上如何实现自适应
由于是在博客编辑器里面编辑的内容,所以一直想通过CSS的方法来解决,可是上面的方式都有明显的缺陷,最终被迫采用脚本来控制列的高度,代码如下: <divstyle="text-align ...
- oracle中时间运算
Oracle两个函数相减,默认得到的是天数,按日期格式,精准到响应的精度,如用sysdate(2015/12/7 10:17:52),时间差精确到秒. 在此基础上,oracle两个时间相减默认天数*2 ...