Debug EOS:nodeos + mongo_db_plugin (9)

main入口函数执行到最后一个步骤:exec函数。

void application::exec() { std::shared_ptr<boost::asio::signal_set> sigint_set(new boost::asio::signal_set(*io_serv, SIGINT)); sigint_set->async_wait([sigint_set,this](const boost::system::error_code& err, int num) { quit(); sigint_set->cancel(); }); std::shared_ptr<boost::asio::signal_set> sigterm_set(new boost::asio::signal_set(*io_serv, SIGTERM)); sigterm_set->async_wait([sigterm_set,this](const boost::system::error_code& err, int num) { quit(); sigterm_set->cancel(); }); std::shared_ptr<boost::asio::signal_set> sigpipe_set(new boost::asio::signal_set(*io_serv, SIGPIPE)); sigpipe_set->async_wait([sigpipe_set,this](const boost::system::error_code& err, int num) { quit(); sigpipe_set->cancel(); }); io_serv->run();// 与上面initialize_logging的get_io_service()获取到的io\_serv是同一个对象 shutdown(); /// 同步推出 }

这个函数与initialize_logging的循环中涉及到相同的信号机制boost::asio::signal_set。

boost::asio::signal_set

boost库的信号量技术。它要使用到boost::asio::io_service,这也是上面提到多次的。信号量对象在初始化的时候的随机去一段上面的代码如下:

std::shared_ptr<boost::asio::signal_set> sigint_set(new boost::asio::signal_set(*io_serv, SIGINT));

共享指针这里不谈了,感兴趣的同学请转到这里。它的构造函数是传入了一个boost::asio::io_service以及一个信号number SIGINT。这个SIGINT的声明为:

#define SIGINT 2 /* Interrupt (ANSI). */

这个构造函数实现了向信号量集合中添加了一个信号2。

接着,我要通过async_wait来使用信号量。可以贴上上面initialize_logging函数的logging_conf_loop函数。

void logging_conf_loop() { std::shared_ptr<boost::asio::signal_set> sighup_set(new boost::asio::signal_set(app().get_io_service(), SIGHUP)); sighup_set->async_wait([sighup_set](const boost::system::error_code& err, int /*num*/) { if(!err) { ilog("Received HUP. Reloading logging configuration."); auto config_path = app().get_logging_conf(); if(fc::exists(config_path)) ::detail::configure_logging(config_path); for(auto iter : fc::get_appender_map()) iter.second->initialize(app().get_io_service()); logging_conf_loop(); } }); }

可以直接通过sighup_set->async_wait的方式来使用。它的声明定义是:

void (boost::system::error_code, int))

会在所监听的信号触发时调用函数体。当发生错误的时候,退出logging_conf_loop函数的递归调用。

总结

写到这里,我们的nodeos的命令就启动成功了,由于篇幅限制,我们没有仔细去研究所有依赖的plugin,以及controller的逻辑。本文重点研究了mongo_db_plugin的源码实现,通过该插件,我们全面分析了nodeos命令启动的所有流程。而对于mongo_db_plugin插件本身的学习,我们也明白了链数据是如何同步到mongo里面的。接下来,我会继续深入分析其他相关插件的初始化流程以及启动流程,还有controller的逻辑细节,以及出块逻辑等等。

参考资料

EOSIO/eos

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssjyw.html