DSS加载module及和module交互的流程,如下:
(1)、DSS在fork子进程后调用StartServer启动服务
调用OS、OSThread、Socket、SocketUtils、QTSSDictionaryMap、
QTSServerInterface、QTSServer等类的Initialize函数进行初始化。
(2)、select_startevents函数
initialize the select() implementation ofthe event queue.
(3)、QTSServer::Initialize函数
继续调用QTSSModule、QTSServerPres、QTSSMessages、RTSPRequestInterface、
RTSPSessionInterface、RTPSessionInterface、RTPStream、RTSPSession、
QTSSFile、QTSSUserProfile等类的Initialize函数,进行dictionary的初始化。
加载了第一个模块QTSSErrorLogModule。
this->SetDefaultIPAddr() //set default IP addr& DNS name
// begin listening,注意这里传的是false参数。
this->CreateListeners(false,fSrvrPrefs,inPortOverride)
(4)、TaskThreadPool::AddThreads(numThreads) // numThreads为 1
到这里,第一个线程创建、运行、被添加到线程池里。
在startBroadcastRTSPSession函数里,又调用AddThreads函数在线程池里添加了一个线程。
(5)、TimeoutTask::Initialize()
Startup the server's global tasks, and start listening. The timeoutTask mechanism istask
based, we therefore mustdo this after adding task threads. This be done before starting
the sockets and servertasks.
sThread= NEW TimeoutTaskThread();
sThread->signal(Task::kStartEvent);
创建一个TimeoutTaskThread类对象,实际上这个类的名字容易产生混淆,它并不是一个线程类,而 是一个基于Task类的任务类。
因为前面已经在线程池里添加了一个任务线程,所以在这里调用signal的时候,就会找到这个线程,
并把事件加入到这个线程的任务队列里,等待被处理。(这时,刚才创建的线程应该也在
TaskThread::Entry函数里等待事件的发生)
(6)、IdleTask::Initialize()
// 创建并启动空闲任务线程
sIdleThread= NEW IdleTaskThread(); sIdleThread->Start();
(7)、Socket::StartThread()
// 启动Socket类的sEventThread类所对应的线程。sEventThread类在Socket::Initialize函数里创建
// 到目前为止,这已是第三个启动的线程,分别是任务线程、空闲任务线程、事务线程。