OpenRTMFP/Cumulus Primer(6)CumulusServer啟動流程分析(續2)

鍾超發表於2012-04-14

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::StartableCumulus::GatewayCumulus::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);

個引數含義如下:

  1. The Path Root for the Server Application
  2. Killer for Termanting the Server Application
  3. 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_BEGINSCRIPT_CREATE_PERSISTENT_OBJECTSCRIPT_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_BEGINSCRIPT_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

-

相關文章