Initial commit

This commit is contained in:
Nav
2021-04-04 21:04:12 +01:00
commit a29c5e1fec
549 changed files with 441216 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
#include <iostream>
#include <csignal>
#include <QtCore>
#include <experimental/filesystem>
#include <thread>
#include <src/Exceptions/Exception.hpp>
#include <src/EventManager/Events/ShutdownTargetController.hpp>
#include "src/Logger/Logger.hpp"
#include "SignalHandler.hpp"
using namespace Bloom;
void SignalHandler::run() {
try {
this->startup();
auto signalSet = this->getRegisteredSignalSet();
int signalNumber = 0;
Logger::debug("SignalHandler ready");
while(Thread::getState() == ThreadState::READY) {
if (sigwait(&signalSet, &signalNumber) == 0) {
Logger::debug("SIGNAL " + std::to_string(signalNumber) + " received");
if (this->handlersMappedBySignalNum.find(signalNumber) != this->handlersMappedBySignalNum.end()) {
// We have a registered handler for this signal.
this->handlersMappedBySignalNum.find(signalNumber)->second();
}
}
}
} catch (std::exception& exception) {
Logger::error("SignalHandler fatal error: " + std::string(exception.what()));
}
Logger::debug("SignalHandler shutting down");
Thread::setState(ThreadState::STOPPED);
}
void SignalHandler::startup() {
this->setName("SH");
Logger::debug("Starting SignalHandler");
// Block all signal interrupts
auto signalSet = this->getRegisteredSignalSet();
sigprocmask(SIG_SETMASK, &signalSet, NULL);
// Register handlers here
this->handlersMappedBySignalNum.insert(std::pair(
SIGINT,
std::bind(&SignalHandler::triggerApplicationShutdown, this)
));
this->handlersMappedBySignalNum.insert(std::pair(
SIGTERM,
std::bind(&SignalHandler::triggerApplicationShutdown, this)
));
Thread::setState(ThreadState::READY);
}
sigset_t SignalHandler::getRegisteredSignalSet() const {
sigset_t set = {};
if (sigfillset(&set) == -1) {
throw Exceptions::Exception("sigfillset() failed - error number: " + std::to_string(errno));
}
return set;
}
void SignalHandler::triggerApplicationShutdown() {
Logger::warning("Shutdown signal received");
this->shutdownSignalsReceived++;
if (this->shutdownSignalsReceived > 1) {
// User has likely run out of patience
Logger::warning("Aborting immediately");
exit(EXIT_FAILURE);
}
Logger::info("Attempting clean shutdown");
this->eventManager.triggerEvent(std::make_shared<Events::ShutdownApplication>());
}

View File

@@ -0,0 +1,63 @@
#pragma once
#include <src/Helpers/Thread.hpp>
#include <src/EventManager/EventManager.hpp>
#include "src/Helpers/SyncSafe.hpp"
#include <csignal>
namespace Bloom
{
class SignalHandler: public Thread
{
private:
EventManager& eventManager;
/**
* Mapping of signal numbers to functions.
*/
std::map<int, std::function<void()>> handlersMappedBySignalNum;
/**
* Fetches all signals currently of interest to the application.
*
* Currently this just returns a set of all signals (using sigfillset())
*
* @return
*/
sigset_t getRegisteredSignalSet() const;
/**
* We keep record of the number of shutdown signals received. See definition of triggerApplicationShutdown()
* for more on this.
*/
int shutdownSignalsReceived = 0;
public:
SignalHandler(EventManager& eventManager) : eventManager(eventManager) {};
/**
* Entry point for SignalHandler thread.
*/
void run();
/**
* Initiates the SignalHandler thread.
*/
void startup();
/**
* Triggers the shutdown of the SignalHandler thread.
*/
void triggerShutdown() {
this->setState(ThreadState::SHUTDOWN_INITIATED);
};
/**
* Handler for SIGINT, SIGTERM, etc signals.
*
* Will trigger a ShutdownApplication event to kick-off a clean shutdown or it will terminate the
* program immediately if numerous SIGINT signals have been received.
*/
void triggerApplicationShutdown();
};
}