一、基础组件总览
本篇开始分析live555的基础组件,也就是基础运行环境所需要的组件类。UasgeEnvionment相关类的关系如下图所示
UsageEnvironment类是个抽象类,提供基础的运行环境,它依赖于TaskScheduler类来进行任务的调度。
BasicUsageEnvironment0继承自UsageEnvironment,是对UsageEnvironment的初步实现,但是也是个抽象类,真正的实现在BasicUsageEnvironment类。
BasicUsageEnvironment真正实现了基础运行环境,主要是实现了控制台对信息和错误的打印。
TaskScheduler类是任务调度的基础抽象类,里面有对三种任务(延迟任务、事件任务和后台IO任务)调度的函数抽象。
BasicTaskScheduler0类继承自TaskScheduler,是对TaskScheduler的初步实现,但是也是个抽象类,里面对三种任务对应的成员变量做了定义。
BasicTaskScheduler真正实现了任务的调度,分别是对延迟任务、事件任务和后台IO任务的调度。
DelayQueue类定义了延迟任务的队列,包含了对延迟任务的增删减除等功能。
DelayQueueEntry类其实就是DelayQueue队列的元素,也就是对延迟任务的定义。
AlarmHandler类是对DelayQueueEntry的真正实现,BasicTaskScheduler真正使用的是AlarmHandler。
DelayInterval是对时间差的一个封装,供DelayQueue相关类使用。
Timeval是一个工具类,可以实现时间的算术运算和比较大小。
二、UsageEnvironment
UsageEnvironment代码定义在目录UsageEnvironment/include/UsageEnvironment.h
下,这是一个抽象类。头文件:
class UsageEnvironment {
public:
Boolean reclaim();
// returns True iff we were actually able to delete our object
// task scheduler:
TaskScheduler& taskScheduler() const {return fScheduler;}
// result message handling:
typedef char const* MsgString;
virtual MsgString getResultMsg() const = 0;
virtual void setResultMsg(MsgString msg) = 0;
virtual void setResultMsg(MsgString msg1, MsgString msg2) = 0;
virtual void setResultMsg(MsgString msg1, MsgString msg2, MsgString msg3) = 0;
virtual void setResultErrMsg(MsgString msg, int err = 0) = 0;
// like setResultMsg(), except that an 'errno' message is appended. (If "err == 0", the "getErrno()" code is used instead.)
virtual void appendToResultMsg(MsgString msg) = 0;
virtual void reportBackgroundError() = 0;
// used to report a (previously set) error message within
// a background event
virtual void internalError(); // used to 'handle' a 'should not occur'-type error condition within the library.
// 'errno'
virtual int getErrno() const = 0;
// 'console' output:
virtual UsageEnvironment& operator<<(char const* str) = 0;
virtual UsageEnvironment& operator<<(int i) = 0;
virtual UsageEnvironment& operator<<(unsigned u) = 0;
virtual UsageEnvironment& operator<<(double d) = 0;
virtual UsageEnvironment& operator<<(void* p) = 0;
// a pointer to additional, optional, client-specific state
void* liveMediaPriv;
void* groupsockPriv;
protected:
UsageEnvironment(TaskScheduler& scheduler); // abstract base class
virtual ~UsageEnvironment(); // we are deleted only by reclaim()
private:
TaskScheduler& fScheduler;
};
有三个成员变量,分别是:
liveMediaPriv
:媒体相关的状态
groupsockPriv
:网络相关的状态
fScheduler
:任务调度器,负责任务的调度
有一系列成员函数,基本都是做信息打印用的,都比较简单,这里不做过多分析。除了信息打印的外,还有个 reclaim()
函数,做资源回收用,但是只有在媒体资源和网络资源为NULL时才会执行。
Boolean UsageEnvironment::reclaim() {
// We delete ourselves only if we have no remainining state:
if (liveMediaPriv == NULL && groupsockPriv == NULL) {
delete this;
return True;
}
return False;
}
三、BasicUsageEnvironment0
BasicUsageEnvironment0继承自UsageEnvironment,是对UsageEnvironment的初步实现,但是也是个抽象类,真正的实现在BasicUsageEnvironment类。它主要实现了将消息信息放进消息buffer里。主要通过函数appendToResultMsg
来实现:
void BasicUsageEnvironment0::appendToResultMsg(MsgString msg) {
char* curPtr = &fResultMsgBuffer[fCurBufferSize];
unsigned spaceAvailable = fBufferMaxSize - fCurBufferSize;
unsigned msgLength = strlen(msg);
// Copy only enough of "msg" as will fit:
if (msgLength > spaceAvailable-1) {
msgLength = spaceAvailable-1;
}
memmove(curPtr, (char*)msg, msgLength);
fCurBufferSize += msgLength;
fResultMsgBuffer[fCurBufferSize] = '\0';
}
看起来也比较简单,先是计算出缓冲区剩余大小,然后跟消息长度做比较,如果消息太长,就丢弃过长的部分不做缓冲,防止缓冲区溢出。
四、BasicUsageEnvironment
BasicUsageEnvironment真正实现了基础运行环境,主要是通过重载输出运算符实现了对不同类型的消息打印到stderr的功能。
UsageEnvironment& BasicUsageEnvironment::operator<<(char const* str) {
if (str == NULL) str = "(NULL)"; // sanity check
fprintf(stderr, "%s", str);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(int i) {
fprintf(stderr, "%d", i);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(unsigned u) {
fprintf(stderr, "%u", u);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(double d) {
fprintf(stderr, "%f", d);
return *this;
}
UsageEnvironment& BasicUsageEnvironment::operator<<(void* p) {
fprintf(stderr, "%p", p);
return *this;
}