Shutdown cleanly on SIGINT
This commit is contained in:
+50
-3
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user