OpenRTMFP/Cumulus Primer(6)CumulusServer启动流程分析(续2)
main()函数中的servermain.cpp 中真正启动的是server,它继承自Cumulus::RTMFPServer,而Cumulus::RTMFPServer?又继承自Cumulus::Startable、Cumulus::Gateway、Cumulus::Handler。而Cumulus::Startable继承自Poco::Runnable,所以其是一个可以运行的线程。在OpenRTMFP/CumulusServer中,这是主线程。
Server server(config().getString("application.dir", "./"), *this, config());server.start(params);这是CumulusServer/Server.h中定义的,其构造函数的原型为:
Server(const std::string& root, ApplicationKiller& applicationKiller, const Poco::Util::AbstractConfiguration& configurations);个参数含义如下:
- The Path Root for the Server Application
- Killer for Termanting the Server Application
- Server Configuration
距离来说,在我的 Worksapce 中:
root是/Users/michael/Development/workspace/eclipse/OpenRTMFP-Cumulus/Debug/构造函数的初始化列表极长:
Server::Server(const std::string& root, ApplicationKiller& applicationKiller, const Util::AbstractConfiguration& configurations) : _blacklist(root + "blacklist", *this), _applicationKiller(applicationKiller), _hasOnRealTime(true), _pService(NULL), luaMail(_pState=Script::CreateState(), configurations.getString("smtp.host","localhost"), configurations.getInt("smtp.port",SMTPSession::SMTP_PORT), configurations.getInt("smtp.timeout",60)) {下面调用Poco::File创建目录:
File((string&)WWWPath = root + "www").createDirectory();因为roor是/Users/michael/Development/workspace/eclipse/OpenRTMFP-Cumulus/Debug/目录,所以WWWPath就是/Users/michael/Development/workspace/eclipse/OpenRTMFP-Cumulus/Debug/www目录。然后初始化GlobalTable,这个GlobalTable是和 Lua 有关的东东,这里暂不细说,先知道与 Lua 相关就好。
Service::InitGlobalTable(_pState);下面就涉及到了 Lua script 了:
SCRIPT_BEGIN(_pState) SCRIPT_CREATE_PERSISTENT_OBJECT(Invoker,LUAInvoker,*this) readNextConfig(_pState,configurations,""); lua_setglobal(_pState,"cumulus.configs"); SCRIPT_END}其中SCRIPT_BEGIN、SCRIPT_CREATE_PERSISTENT_OBJECT和SCRIPT_END都是宏,其定义在Script.h文件中,如下:
#define SCRIPT_BEGIN(STATE) \ if (lua_State* __pState = STATE) { \ const char* __error=NULL;#define SCRIPT_CREATE_PERSISTENT_OBJECT(TYPE,LUATYPE,OBJ) \ Script::WritePersistentObject<TYPE,LUATYPE>(__pState,OBJ); \ lua_pop(__pState,1);#define SCRIPT_END }SCRIPT_BEGIN和SCRIPT_END经常用到,当与 Lua 相关的操作出现时,都会以这两个宏作为开头和结尾。
main()函数的server.start()void RTMFPServer::start(RTMFPServerParams& params) {如果OpenRTMFP/CumulusServer正在运行,则返回并终止启动。
if(running()) { ERROR("RTMFPServer server is yet running, call stop method before"); return; }设定端口号,如果端口号为 0,则返回并终止启动。
_port = params.port; if (_port == 0) { ERROR("RTMFPServer port must have a positive value"); return; }设定OpenRTMFP/CumulusEdge的端口号,如果其端口号与OpenRTMFP/CumulusSever端口号相同,则返回并终止启动:
_edgesPort = params.edgesPort; if(_port == _edgesPort) { ERROR("RTMFPServer port must different than RTMFPServer edges.port"); return; }Cirrus:
_freqManage = 2000000; // 2 sec by default if(params.pCirrus) { _pCirrus = new Target(*params.pCirrus); _freqManage = 0; // no waiting, direct process in the middle case! NOTE("RTMFPServer started in man-in-the-middle mode with server %s \ (unstable debug mode)", _pCirrus->address.toString().c_str()); }middle:
_middle = params.middle; if(_middle) NOTE("RTMFPServer started in man-in-the-middle mode between peers \ (unstable debug mode)");UDP Buffer:
(UInt32&)udpBufferSize = params.udpBufferSize==0 ? _socket.getReceiveBufferSize() : params.udpBufferSize; _socket.setReceiveBufferSize(udpBufferSize); _socket.setSendBufferSize(udpBufferSize); _edgesSocket.setReceiveBufferSize(udpBufferSize); _edgesSocket.setSendBufferSize(udpBufferSize); DEBUG("Socket buffer receving/sending size = %u/%u", udpBufferSize, udpBufferSize); (UInt32&)keepAliveServer = params.keepAliveServer < 5 ? 5000 : params.keepAliveServer * 1000; (UInt32&)keepAlivePeer = params.keepAlivePeer < 5 ? 5000 : params.keepAlivePeer * 1000; (UInt8&)edgesAttemptsBeforeFallback = params.edgesAttemptsBeforeFallback; setPriority(params.threadPriority);启动线程,进入循环运行:
Startable::start();}上句具体的源码实现为:
void Startable::start() { if (running()) return;如果在运行则返回并终止启动。然后加一个局部锁。
ScopedLock<FastMutex> lock(_mutex);如果不得不join()到主线程中,那就join()吧
if(_haveToJoin) { _thread.join(); _haveToJoin=false; }然后就运行这个线程吧:
_terminate = false; _thread.start(*this); _haveToJoin = true;}-
转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant
-