summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorFlorent Le Coz <louiz@louiz.org>2013-12-21 21:04:41 +0100
committerFlorent Le Coz <louiz@louiz.org>2014-01-04 01:59:14 +0100
commit3afb63a650b8b925ce1ba722dd42b7418f623713 (patch)
tree594cdfdd2a0abf302229ec000c2177ec001bfeaf /src/main.cpp
parentdf59a09163bd988ad4da533c4f39de057a3701ba (diff)
downloadbiboumi-3afb63a650b8b925ce1ba722dd42b7418f623713.tar.gz
biboumi-3afb63a650b8b925ce1ba722dd42b7418f623713.tar.bz2
biboumi-3afb63a650b8b925ce1ba722dd42b7418f623713.tar.xz
biboumi-3afb63a650b8b925ce1ba722dd42b7418f623713.zip
Shutdown cleanly on SIGINT
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp53
1 files changed, 50 insertions, 3 deletions
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 <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;
}