Live555 BasicUsageEnvironment模块BasicUsageEnvironment.hh之BasicTaskScheduler0源码分析
2017-03-29 15:46
603 查看
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) class BasicTaskScheduler0: public TaskScheduler { public: virtual ~BasicTaskScheduler0(); virtual void SingleStep(unsigned maxDelayTime = 0) = 0; // "maxDelayTime" is in microseconds. It allows a subclass to impose a limit // on how long "select()" can delay, in case it wants to also do polling. // 0 (the default value) means: There's no maximum; just look at the delay queue public: // Redefined virtual functions: virtual TaskToken scheduleDelayedTask(int64_t microseconds, TaskFunc* proc, void* clientData); virtual void unscheduleDelayedTask(TaskToken& prevTask); virtual void doEventLoop(char* watchVariable); virtual EventTriggerId createEventTrigger(TaskFunc* eventHandlerProc); virtual void deleteEventTrigger(EventTriggerId eventTriggerId); virtual void triggerEvent(EventTriggerId eventTriggerId, void* clientData = NULL); protected: BasicTaskScheduler0(); protected: // To implement delayed operations: DelayQueue fDelayQueue; // To implement background reads: HandlerSet* fHandlers; int fLastHandledSocketNum; // To implement event triggers: EventTriggerId fTriggersAwaitingHandling, fLastUsedTriggerMask; // implemented as 32-bit bitmaps TaskFunc* fTriggeredEventHandlers[MAX_NUM_EVENT_TRIGGERS]; void* fTriggeredEventClientDatas[MAX_NUM_EVENT_TRIGGERS]; unsigned fLastUsedTriggerNum; // in the range [0,MAX_NUM_EVENT_TRIGGERS) };
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::~BasicTaskScheduler0() {
delete fHandlers;
}
TaskToken BasicTaskScheduler0::scheduleDelayedTask(int64_t microseconds,
TaskFunc* proc,
void* clientData) {
if (microseconds < 0) microseconds = 0;
DelayInterval timeToDelay((long)(microseconds/1000000), (long)(microseconds%1000000));
AlarmHandler* alarmHandler = new AlarmHandler(proc, clientData, timeToDelay);
fDelayQueue.addEntry(alarmHandler);
return (void*)(alarmHandler->token());
}
void BasicTaskScheduler0::unscheduleDelayedTask(TaskToken& prevTask) {
DelayQueueEntry* alarmHandler = fDelayQueue.removeEntry((long)prevTask);
prevTask = NULL;
delete alarmHandler;
}
void BasicTaskScheduler0::doEventLoop(char* watchVariable) {
// Repeatedly loop, handling readble sockets and timed events:
while (1) {
if (watchVariable != NULL && *watchVariable != 0) break;
SingleStep();
}
}
EventTriggerId BasicTaskScheduler0::createEventTrigger(TaskFunc* eventHandlerProc) {
unsigned i = fLastUsedTriggerNum;
EventTriggerId mask = fLastUsedTriggerMask;
do {
i = (i+1)%MAX_NUM_EVENT_TRIGGERS;
mask >>= 1;
if (mask == 0) mask = 0x80000000;
if (fTriggeredEventHandlers[i] == NULL) {
// This trigger number is free; use it:
fTriggeredEventHandlers[i] = eventHandlerProc;
fTriggeredEventClientDatas[i] = NULL; // sanity
fLastUsedTriggerMask = mask;
fLastUsedTriggerNum = i;
return mask;
}
} while (i != fLastUsedTriggerNum);
// All available event triggers are allocated; return 0 instead:
return 0;
}
void BasicTaskScheduler0::deleteEventTrigger(EventTriggerId eventTriggerId) {
fTriggersAwaitingHandling &=~ eventTriggerId;
if (eventTriggerId == fLastUsedTriggerMask) { // common-case optimization:
fTriggeredEventHandlers[fLastUsedTriggerNum] = NULL;
fTriggeredEventClientDatas[fLastUsedTriggerNum] = NULL;
} else {
// "eventTriggerId" should have just one bit set.
// However, we do the reasonable thing if the user happened to 'or' together two or more "EventTriggerId"s:
EventTriggerId mask = 0x80000000;
for (unsigned i = 0; i < MAX_NUM_EVENT_TRIGGERS; ++i) {
if ((eventTriggerId&mask) != 0) {
fTriggeredEventHandlers[i] = NULL;
fTriggeredEventClientDatas[i] = NULL;
}
mask >>= 1;
}
}
}
void BasicTaskScheduler0::triggerEvent(EventTriggerId eventTriggerId, void* clientData) {
// First, record the "clientData":
if (eventTriggerId == fLastUsedTriggerMask) { // common-case optimization:
fTriggeredEventClientDatas[fLastUsedTriggerNum] = clientData;
} else {
EventTriggerId mask = 0x80000000;
for (unsigned i = 0; i < MAX_NUM_EVENT_TRIGGERS; ++i) {
if ((eventTriggerId&mask) != 0) {
fTriggeredEventClientDatas[i] = clientData;
fLastUsedTriggerMask = mask;
fLastUsedTriggerNum = i;
}
mask >>= 1;
}
}
// Then, note this event as being ready to be handled.
// (Note that because this function (unlike others in the library) can be called from an external thread, we do this last, to
// reduce the risk of a race condition.)
fTriggersAwaitingHandling |= eventTriggerId;
}
BasicTaskScheduler0调用了DelayQueue类跟HandlerSet类。
HandlerSet类参考http://blog.csdn.net/sz76211822/article/details/68059848
DelayQueue类参考http://blog.csdn.net/sz76211822/article/details/68060399
相关文章推荐
- live555源码之BasicTaskScheduler实现
- 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类
- Mesos源码分析(10): MesosSchedulerDriver的启动及运行一个Task
- Mesos源码分析(10): MesosSchedulerDriver的启动及运行一个Task
- Hadoop学习之--Capaycity Scheduler源码分析
- live555源码分析----RTP的打包与发送
- 方法、hadoop源码之JobQueueTaskScheduler-by小雨
- Storm-源码分析- bolt (backtype.storm.task)
- Task Scheduler Basic Function
- Storm-源码分析-Topology Submit-Task-TopologyContext (backtype.storm.task)
- Storm-源码分析- Scheduler (backtype.storm.scheduler)
- hadoop源码之JobQueueTaskScheduler
- Hadoop0.21.0源码流程分析(3)-Task节点管理启动任务
- live555 源码分析
- live555源码分析----mpg文件的处理(续)
- live555源码分析---- PLAY命令的处理
- Storm-源码分析- Component ,Executor ,Task之间关系
- live555库的rtsp服务器源码分析总结,流程详解RTSPServer
- Hadoop0.21.0源码流程分析(3)-Task节点管理启动任务
- mapreduce源码分析之默认的任务调度器——JobQueueTaskScheduler