0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 10:12:39 +01:00

ircd/charybdis: Add at_main_exit() callback to indicate IRCd has finished

to the host program. Without any indication, the outer program's handlers
will continue to keep ios.run() from returning.
This commit is contained in:
Jason Volk 2016-09-09 10:48:33 -07:00
parent 0f3ef3204b
commit 07177e8a6b
3 changed files with 41 additions and 5 deletions

View file

@ -89,6 +89,12 @@ try
sigs.add(SIGTSTP); sigs.add(SIGTSTP);
sigs.add(SIGQUIT); sigs.add(SIGQUIT);
sigs.add(SIGTERM); sigs.add(SIGTERM);
ircd::at_main_exit([]
{
// Entered when IRCd's main context has finished. ios.run() won't
// return because our signal handler out here is still using it.
sigs.cancel();
});
sigs.async_wait(sigfd_handler); sigs.async_wait(sigfd_handler);
if(cmdline) if(cmdline)

View file

@ -52,8 +52,12 @@ extern bool debugmode;
extern boost::asio::io_service *ios; extern boost::asio::io_service *ios;
extern client::client me; extern client::client me;
// Set callback for when IRCd's main context has completed.
using main_exit_cb = std::function<void ()>;
void at_main_exit(main_exit_cb);
void init(boost::asio::io_service &ios, const std::string &newconf_path); // Library constructor
void init(boost::asio::io_service &ios, const std::string &newconf_path, main_exit_cb = nullptr);
} // namespace ircd } // namespace ircd
#endif // __cplusplus #endif // __cplusplus

View file

@ -30,10 +30,12 @@ namespace ircd
{ {
bool debugmode; // set by command line bool debugmode; // set by command line
boost::asio::io_service *ios; // user's io service boost::asio::io_service *ios; // user's io service
main_exit_cb main_exit_func; // Called when main context exits
ctx::ctx *mc; // IRCd's main context ctx::ctx *mc; // IRCd's main context
void seed_random(); void seed_random();
void init_system(); void init_system();
void main_exiting() noexcept;
void handle_sigusr2(); void handle_sigusr2();
void handle_sigusr1(); void handle_sigusr1();
void handle_sigterm(); void handle_sigterm();
@ -48,7 +50,8 @@ namespace ircd
*/ */
void void
ircd::init(boost::asio::io_service &io_service, ircd::init(boost::asio::io_service &io_service,
const std::string &configfile) const std::string &configfile,
main_exit_cb main_exit_func)
{ {
ircd::ios = &io_service; ircd::ios = &io_service;
init_system(); init_system();
@ -63,6 +66,7 @@ ircd::init(boost::asio::io_service &io_service,
// The master of ceremonies runs the show after this function returns and ios.run() // The master of ceremonies runs the show after this function returns and ios.run()
// It cannot spawn when no ios is running so it is deferred just in case. // It cannot spawn when no ios is running so it is deferred just in case.
log::debug("spawning main context"); log::debug("spawning main context");
at_main_exit(std::move(main_exit_func));
context mc(8_MiB, ircd::main, ctx::DEFER_POST); context mc(8_MiB, ircd::main, ctx::DEFER_POST);
// The context will not be joined and block this function when no parent context // The context will not be joined and block this function when no parent context
@ -79,6 +83,7 @@ noexcept try
{ {
// Ownership is taken of the main context to delete it at function end // Ownership is taken of the main context to delete it at function end
const custom_ptr<ctx::ctx> mc(ircd::mc, ctx::free); const custom_ptr<ctx::ctx> mc(ircd::mc, ctx::free);
const scope main_exit(&main_exiting);
log::debug("IRCd entered main context."); log::debug("IRCd entered main context.");
log::info("executing configuration"); log::info("executing configuration");
@ -103,8 +108,7 @@ noexcept try
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
log::error("main context: %s", e.what()); log::error("IRCd finished: %s", e.what());
return;
} }
void void
@ -112,7 +116,7 @@ ircd::handle_sigterm()
{ {
using namespace ircd; using namespace ircd;
log::notice("SIGTERM. Terminating..."); log::notice("IRCd finished: SIGTERM");
} }
void void
@ -142,6 +146,28 @@ ircd::handle_sigusr2()
// doremotd // doremotd
} }
void
ircd::main_exiting()
noexcept try
{
if(main_exit_func)
{
log::debug("Notifying user of IRCd completion");
main_exit_func();
}
}
catch(const std::exception &e)
{
log::critical("main context exit: %s", e.what());
throw;
}
void
ircd::at_main_exit(main_exit_cb main_exit_func)
{
ircd::main_exit_func = std::move(main_exit_func);
}
void void
ircd::init_system() ircd::init_system()
{ {