OpenRTmfp/Cumulus Primer(6)CumulusServer启动流程分析(续2)
- 作者:柳大·Poechant(钟超)
- 博客:Blog.CSDN.net/Poechant
- 邮箱:zhongchao.ustc#gmail.com (# -> @)
- 日期:April 14th,2012
1 main.cpp 中的main()
函数中的server
main.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,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 相关的操作出现时,都会以这两个宏作为开头和结尾。
2 main.cpp 中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
-
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。