Shutdown cleanly on SIGINT

This commit is contained in:
Florent Le Coz
2014-01-04 01:59:14 +01:00
parent df59a09163
commit 3afb63a650
9 changed files with 152 additions and 29 deletions
+50 -3
View File
@@ -1,9 +1,19 @@
#include <xmpp/xmpp_component.hpp>
#include <network/poller.hpp>
#include <config/config.hpp>
#include <logger/logger.hpp>
#include <iostream>
#include <memory>
#include <atomic>
#include <signal.h>
// A flag set by the SIGINT signal handler.
volatile std::atomic<bool> 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;
}