Adds logging to heart component and signal handler for improved debugging. Changes signal handler to set a "StopPending" state to allow the main loop to handle shutdown. Fixes a potential thread join issue during shutdown.
91 lines
No EOL
2.4 KiB
C++
91 lines
No EOL
2.4 KiB
C++
#include <csignal>
|
|
#include <iostream>
|
|
#include "DixonBrain.h"
|
|
#include "Version.h" // The generated header
|
|
#include "Logging/DixonLogger.h"
|
|
|
|
|
|
void signal_thread_func(sigset_t set) {
|
|
int sig;
|
|
Dixon::DixonLogger logger("signal_thread_func");
|
|
|
|
while (true) {
|
|
// This blocks until a signal actually happens
|
|
if (sigwait(&set, &sig) == 0) {
|
|
logger.info("Signal {} received.", sig);
|
|
|
|
// Set the state so the main loop starts the shutdown
|
|
DixonNodeState::instance().setNodeStatus(NodeStatus::StopPending);
|
|
|
|
// If you want to allow a "Force Quit" on the second Ctrl-C:
|
|
static int interrupt_count = 0;
|
|
if (++interrupt_count >= 3) {
|
|
logger.warn("Force quitting...");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// Check if the main thread has finished cleaning up
|
|
if (DixonNodeState::instance().getNodeStatus() == NodeStatus::Stopped) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
sigset_t prepare_signal_set()
|
|
{
|
|
sigset_t set;
|
|
sigemptyset(&set);
|
|
sigaddset(&set, SIGINT);
|
|
sigaddset(&set, SIGTERM);
|
|
return set;
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
Dixon::DixonLogger logger("main");
|
|
|
|
// The "Splash Screen"
|
|
logger.info("Dixon core is starting. Version: {}", "1.x.x");
|
|
|
|
const sigset_t set = prepare_signal_set();
|
|
pthread_sigmask(SIG_BLOCK, &set, nullptr);
|
|
|
|
std::thread sig_thread(signal_thread_func, set);
|
|
sig_thread.detach(); // Let it run independently
|
|
|
|
// Create the brain controller
|
|
DixonBrain brain;
|
|
|
|
// Start the brain's control loop
|
|
brain.start();
|
|
|
|
logger.info("Dixon core is alive.");
|
|
const DixonNodeState& state = DixonNodeState::instance();
|
|
|
|
auto count = 1;
|
|
while (state.getNodeStatus() != NodeStatus::Stopped)
|
|
{
|
|
|
|
if (state.getNodeStatus() == NodeStatus::StopPending)
|
|
{
|
|
logger.info("calling 'stop' on Dixon Brain.");
|
|
brain.stop();
|
|
}
|
|
|
|
count++;
|
|
if (count>100)
|
|
{
|
|
count = 0;
|
|
auto const currentState = static_cast<int>(DixonNodeState::instance().getNodeStatus());
|
|
logger.info("Dixon is alive, state is {}.", currentState);
|
|
//log->log(spdlog::level::info, "Dixon state is {}",
|
|
//static_cast<int>(D);
|
|
}
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
}
|
|
|
|
logger.info("Dixon has left the building.");
|
|
return 0;
|
|
} |