From 3afb63a650b8b925ce1ba722dd42b7418f623713 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 21 Dec 2013 21:04:41 +0100 Subject: Shutdown cleanly on SIGINT --- src/main.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 2da180b..6c9560c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,19 @@ #include #include #include +#include #include #include +#include + +#include + +// A flag set by the SIGINT signal handler. +volatile std::atomic stop(false); +// A flag indicating that we are wanting to exit the process. i.e: if this +// flag is set and all connections are closed, we can exit properly. +static bool exiting = false; /** * Provide an helpful message to help the user write a minimal working @@ -20,6 +30,11 @@ int config_help(const std::string& missing_option) return 1; } +static void sigint_handler(int, siginfo_t*, void*) +{ + stop = true; +} + int main(int ac, char** av) { if (ac > 1) @@ -44,8 +59,40 @@ int main(int ac, char** av) Poller p; p.add_socket_handler(xmpp_component); - xmpp_component->start(); - while (p.poll()) - ; + if (!xmpp_component->start()) + { + log_info("Exiting"); + return -1; + } + + // Install the signals used to exit the process cleanly, or reload the + // config + sigset_t mask; + sigemptyset(&mask); + struct sigaction on_sig; + on_sig.sa_sigaction = &sigint_handler; + on_sig.sa_mask = mask; + // we want to catch that signal only once. + // Sending SIGINT again will "force" an exit + on_sig.sa_flags = SA_RESETHAND; + sigaction(SIGINT, &on_sig, nullptr); + sigaction(SIGTERM, &on_sig, nullptr); + + const std::chrono::milliseconds timeout(-1); + while (p.poll(timeout) != -1 || !exiting) + { + if (stop) + { + log_info("Signal received, exiting..."); + exiting = true; + stop = false; + xmpp_component->shutdown(); + } + // If the only existing connection is the one to the XMPP component: + // close the XMPP stream. + if (exiting && p.size() == 1 && xmpp_component->is_document_open()) + xmpp_component->close_document(); + } + log_info("All connection cleanely closed, have a nice day."); return 0; } -- cgit v1.2.3