Dixon/src/RobotNode/main.cpp
Russell Gilbert adda211b76 Improves shutdown handling and adds logging
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.
2026-02-20 17:07:10 +00:00

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;
}