异想天开

What's the true meaning of light, Could you tell me why

openRTMFP阅读笔记0

日期:2014-09-30 14:02:40
  
最后更新日期:2014-10-26 11:40:42
【技术文章】
早几天忽然在电脑里面,看到去年写的阅读源码笔记。继续照着这个思路,居然还能找到思绪,好神奇。

1.用source insight打开openRTMFP源码,搜索main函数。
[code lang="cpp"]
int main(int argc, char* argv[]) {
DetectMemoryLeak();
return CumulusServer().run(argc, argv);
}
[/code]
看到第一个类-CumulusServer 。

2. CumulusServer的继承关系
[code lang="cpp"]
class CumulusServer: public ServerApplication, private Cumulus::Logger, private ApplicationKiller {
main() {}
};
[/code]
CumulusServer并没有定义run方法,run方法来自于poco库的ServerApplication类。

打开poco库源码,其定义如下:
[code lang="cpp"]
class Util_API ServerApplication: public Application {
一系列的run方法
};
[/code]
为了跨平台-windows和unix等以及支持宽字符,ServerApplication类有一系列的run方法适用不同的平台。而我们关心的unix平台的run(int argc, char** argv)方法:
[code lang="cpp"]
int ServerApplication::run(int argc, char** argv)
{
bool runAsDaemon = isDaemon(argc, argv);
if (runAsDaemon)
{
beDaemon();
}
try
{
init(argc, argv);
if (runAsDaemon)
{
int rc = chdir("/");
if (rc != 0) return EXIT_OSERR;
}
}
catch (Exception& exc)
{
logger().log(exc);
return EXIT_CONFIG;
}
return run();
}
[/code]
首先判断是否为守护进程,然后初始化,最后调用run方法。派生类 ServerApplication也是调用基类的run(void)方法。子类的run(void)方法是个虚函数.
其run方法:
[code lang="cpp"]
initialize(*this);
rc = EXIT_SOFTWARE;
rc = main(_args);
uninitialize();
[/code]
main方法也为虚函数。那么即调用CumulusServer的main方法,main方法启动服务
[code lang="cpp"]
Server server(*this,config());
server.start(_params);
[/code]

3. Server类
[code lang="cpp"]
class Server : public Cumulus::RTMFPServer, private ServiceRegistry, private ServerHandler {
};

class RTMFPServer : private Gateway,protected Handler,private Startable,private SocketHandler {
start( RTMFPServerParams& params ) {} // 线程开始函数
onstart() {}
};
[/code]
start( RTMFPServerParams& params )方法调用基类Startable::start(),即开始创建线程,调用run方法。


4.RTMFPServer的run方法包含,server启动过程。
[code lang="cpp"]
_pSocket->bind(SocketAddress("0.0.0.0",_port));
_mainSockets.add(*_pSocket,*this);

NOTE("RTMFP server starts on %u port",_port);
onStart();

RTMFPManager manager(*this);
bool terminate=false;
while(!terminate)
handle(terminate);
[/code]

5.封装线程的使用
[code lang="cpp"]
class StartableProcess : public Poco::Runnable{
public:
StartableProcess(Startable& startable);
private:
void run();
Startable& _startable;
};

class Startable {
friend class StartableProcess;
public:
void start();
void stop();
bool running() const;
const std::string& name() const;

protected:
Startable(const std::string& name);
virtual ~Startable();
virtual void run()=0;
virtual void prerun();

private:
Poco::Thread _thread;
mutable Poco::FastMutex _mutex;
mutable Poco::FastMutex _mutexStop;
Poco::Event _wakeUpEvent;
std::string _name;
StartableProcess _process;
};
[/code]
这个Startable类的构造函数构造_process时,将自己的引用传递进去。这个类可以这样使用它,先继承Startable类,重写run方法,调用Startable::start(void)方法即可创建一个线程。
这样调用形式被封装到了 Startable类-Startable::start(void)方法。注意这个方法一般是在父线程中调用。若不封装成这个类,使用poco库则这样调用。
[code lang="cpp"]
Poco::Thread _thread;
StartableProcess _process;
_thread.start(_process);
[/code]
封装后,则直接在Startable::start()方法里面:
[code lang="cpp"]
_thread.start(_process);
[/code]
启动它即可。