0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-11 06:28:55 +02:00

ircd: Move all signal handling to charybdis executable.

This commit is contained in:
Jason Volk 2016-10-25 23:25:04 -07:00
parent 2d89b583e9
commit ae40f9c016
3 changed files with 64 additions and 74 deletions

View file

@ -103,6 +103,8 @@ try
sigs.add(SIGTSTP);
sigs.add(SIGQUIT);
sigs.add(SIGTERM);
sigs.add(SIGUSR1);
sigs.add(SIGUSR2);
ircd::at_main_exit([]
{
// Entered when IRCd's main context has finished. ios.run() won't
@ -189,6 +191,8 @@ boost::asio::posix::stream_descriptor *console_in;
static void handle_line(const std::string &line);
static void console();
static void console_cancel();
static void handle_usr2();
static void handle_usr1();
static void handle_quit();
static void handle_interruption();
static void handle_termstop();
@ -216,11 +220,13 @@ sigfd_handler(const boost::system::error_code &ec,
switch(signum)
{
case SIGUSR1: handle_usr1(); break;
case SIGUSR2: handle_usr2(); break;
case SIGINT: handle_interruption(); break;
case SIGTSTP: handle_termstop(); break;
case SIGHUP: handle_hangup(); break;
case SIGQUIT: handle_quit(); return;
case SIGTERM: return;
case SIGTERM: handle_quit(); return;
default: break;
}
@ -232,12 +238,36 @@ handle_quit()
try
{
console_cancel();
ircd::stop();
}
catch(const std::exception &e)
{
ircd::log::error("SIGQUIT handler: %s", e.what());
}
void
handle_usr1()
try
{
// Do ircd rehash config
}
catch(const std::exception &e)
{
ircd::log::error("SIGUSR1 handler: %s", e.what());
}
void
handle_usr2()
try
{
// Do ircd rehash bans
// Do refresh motd
}
catch(const std::exception &e)
{
ircd::log::error("SIGUSR2 handler: %s", e.what());
}
void
handle_hangup()
try

View file

@ -42,9 +42,20 @@ extern bool main_exited;
using main_exit_cb = std::function<void ()>;
void at_main_exit(main_exit_cb);
// Library constructor
//
// Sets up the IRCd, handlers (main context), and then returns without blocking.
// Pass your io_service instance, it will share it with the rest of your program.
// An exception will be thrown on error.
//
void init(boost::asio::io_service &ios, const std::string &newconf_path, main_exit_cb = nullptr);
//
// Notifies IRCd to shutdown. A shutdown will occur asynchronously and this function will return
// immediately. main_exit_cb will be called when IRCd has no more work for the ios (main_exit_cb
// will be the last operation from IRCd posted to the ios).
//
void stop();
} // namespace ircd
#endif // __cplusplus

View file

@ -35,21 +35,15 @@ namespace ircd
main_exit_cb main_exit_func; // Called when main context exits
bool main_exited; // Set when IRCd is finished
bool main_finish; // Set by stop() to request main context exit
ctx::ctx *main_context; // Reference to main context
void seed_random();
void init_system();
void main_exiting() noexcept;
void handle_sigusr2();
void handle_sigusr1();
void handle_sigterm();
void handle_sigquit();
void main() noexcept;
}
//
// Sets up the IRCd, handlers (main context), and then returns without blocking.
// Pass your io_service instance, it will share it with the rest of your program.
// An exception will be thrown on error.
//
void
ircd::init(boost::asio::io_service &io_service,
const std::string &configfile,
@ -71,13 +65,22 @@ ircd::init(boost::asio::io_service &io_service,
at_main_exit(std::move(main_exit_func));
// The master of ceremonies runs the show after this function returns and ios.run().
// The SELF_DESTRUCT flag indicates it will clean itself up and cannot join here.
log::debug("spawning main context");
context(8_MiB, ircd::main, ctx::DEFER_POST | ctx::SELF_DESTRUCT);
context mc(8_MiB, ircd::main, ctx::DEFER_POST); //TODO: optimize stack size
main_context = mc.detach();
log::debug("IRCd initialization completed.");
}
void
ircd::stop()
{
main_finish = true;
if(main_context)
ctx::notify(*main_context);
}
//
// Main context; Main program loop.
// This function is spawned by init(). Do not call this function.
@ -96,76 +99,21 @@ noexcept try
mods::init _mods_;
db::init _db_;
js::init _js_;
client_init _client_;
// Create IRCd's agency
ircd::me = add_client();
// This is where the configuration is finally evalulated. This must occur
// in a context which can block. If execute() does not transact successfully
// IRCd never reaches the main loop and aborts.
log::info("executing configuration");
conf::execute();
log::debug("setting up signals");
boost::asio::signal_set sigfd(*ios);
sigfd.add(SIGTERM);
sigfd.add(SIGQUIT);
sigfd.add(SIGUSR1);
sigfd.add(SIGUSR2);
// This is the main program loop. All it does is handle signals.
// The configuration will have spawned other loops.
log::notice("IRCd ready");
do switch(sigfd.async_wait(yield(continuation())))
// This is the main program loop. Right now all it does is sleep until notified
// to shutdown, but it can do other things eventually. Other subsystems may have
// spawned their own main loops.
log::notice("IRCd ready"); do
{
case SIGTERM: handle_sigterm(); return;
case SIGQUIT: handle_sigquit(); return;
case SIGUSR1: handle_sigusr1(); continue;
case SIGUSR2: handle_sigusr2(); continue;
ctx::wait();
}
while(1);
while(!main_finish);
}
catch(const std::exception &e)
{
log::error("IRCd finished: %s", e.what());
}
void
ircd::handle_sigterm()
{
using namespace ircd;
log::notice("IRCd finished: SIGTERM");
}
void
ircd::handle_sigquit()
{
using namespace ircd;
log::notice("SIGQUIT. Quitting...");
}
void
ircd::handle_sigusr1()
{
using namespace ircd;
log::notice("SIGUSR1. Rehashing configuration...");
// dorehash (no longer hangup!)
}
void
ircd::handle_sigusr2()
{
using namespace ircd;
log::notice("SIGUSR2. Flushing caches...");
// dorehashbans
// doremotd
}
//
// Cleanup function for the main context.
//
@ -183,6 +131,7 @@ noexcept try
}
main_exited = true;
main_context = nullptr;
}
catch(const std::exception &e)
{