Skip to content

Commit

Permalink
- post startup() of plugins so they are interuptable
Browse files Browse the repository at this point in the history
- add signal handling thread so startup is interuptable
  • Loading branch information
heifner committed Nov 10, 2018
1 parent f3a63c1 commit 90077ed
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
37 changes: 31 additions & 6 deletions application.cpp
Expand Up @@ -28,7 +28,9 @@ class application_impl {
bfs::path _logging_conf{"logging.json"};
bfs::path _config_file_name;

uint64_t _version;
uint64_t _version = 0;

std::atomic_bool _is_quiting{false};
};

application::application()
Expand Down Expand Up @@ -64,8 +66,19 @@ bfs::path application::get_logging_conf() const {

void application::startup() {
try {
for (auto plugin : initialized_plugins)
plugin->startup();
auto ioc = io_serv;
for (auto plugin : initialized_plugins) {
// order of execution for single-threaded io_service is order of post
io_serv->post( [plugin, ioc, this](){
try {
if( is_quiting() ) return;
plugin->startup();
} catch(...) {
shutdown();
throw;
}
} );
}
} catch(...) {
shutdown();
throw;
Expand Down Expand Up @@ -217,28 +230,40 @@ void application::shutdown() {
}

void application::quit() {
my->_is_quiting = true;
io_serv->stop();
}

bool application::is_quiting() const {
return my->_is_quiting;
}

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

// setup seperate io_service and thread of signals
std::shared_ptr<boost::asio::io_service> sig_io_serv = std::make_shared<boost::asio::io_service>();

std::shared_ptr<boost::asio::signal_set> sigint_set(new boost::asio::signal_set(*sig_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));
std::shared_ptr<boost::asio::signal_set> sigterm_set(new boost::asio::signal_set(*sig_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));
std::shared_ptr<boost::asio::signal_set> sigpipe_set(new boost::asio::signal_set(*sig_io_serv, SIGPIPE));
sigpipe_set->async_wait([sigpipe_set,this](const boost::system::error_code& err, int num) {
quit();
sigpipe_set->cancel();
});

std::thread sig_thread( [sig_io_serv]() { sig_io_serv->run(); } );
sig_thread.detach();

io_serv->run();

shutdown(); /// perform synchronous shutdown
Expand Down
13 changes: 12 additions & 1 deletion include/appbase/application.hpp
Expand Up @@ -80,11 +80,18 @@ namespace appbase {
void shutdown();

/**
* Wait until quit(), SIGINT or SIGTERM and then shutdown
* Wait until quit(), SIGINT or SIGTERM and then shutdown.
* Should only be executed from one thread.
*/
void exec();
void quit();

/**
* If in long running process this flag can be checked to see if processing should be stoppped.
* @return true if quit() has been called.
*/
bool is_quiting()const;

static application& instance();

abstract_plugin* find_plugin(const string& name)const;
Expand Down Expand Up @@ -156,6 +163,10 @@ namespace appbase {
}
}

/**
* Do not run io_service in any other threads, as application assumes single-threaded execution in exec().
* @return io_serivice of application
*/
boost::asio::io_service& get_io_service() { return *io_serv; }
protected:
template<typename Impl>
Expand Down

0 comments on commit 90077ed

Please sign in to comment.