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.
This commit is contained in:
parent
3a4e00a409
commit
adda211b76
5 changed files with 34 additions and 12 deletions
|
|
@ -9,7 +9,8 @@ namespace cardio
|
||||||
: _lastBeat(std::chrono::steady_clock::now()),
|
: _lastBeat(std::chrono::steady_clock::now()),
|
||||||
chip_(std::string("/dev/") + chipName),
|
chip_(std::string("/dev/") + chipName),
|
||||||
isOn_(false),
|
isOn_(false),
|
||||||
request_(get_line_request(chip_, lineOffset))
|
request_(get_line_request(chip_, lineOffset)),
|
||||||
|
logger_("Heart")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,14 +28,19 @@ namespace cardio
|
||||||
const auto val = isOn_ ? gpiod::line::value::ACTIVE : gpiod::line::value::INACTIVE;
|
const auto val = isOn_ ? gpiod::line::value::ACTIVE : gpiod::line::value::INACTIVE;
|
||||||
request_.set_value(DEFAULT_HEART_PIN, val);
|
request_.set_value(DEFAULT_HEART_PIN, val);
|
||||||
_lastBeat = now;
|
_lastBeat = now;
|
||||||
|
|
||||||
|
if (isOn_) {
|
||||||
|
logger_.debug("Heart::beat()");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heart::stop()
|
void Heart::stop()
|
||||||
{
|
{
|
||||||
std::cout << "Heart::stop() called.\n";
|
logger_.info("Stopping heart.");
|
||||||
isOn_ = false;
|
isOn_ = false;
|
||||||
request_.set_value(DEFAULT_HEART_PIN, gpiod::line::value::INACTIVE);
|
request_.set_value(DEFAULT_HEART_PIN, gpiod::line::value::INACTIVE);
|
||||||
|
logger_.info("Stopped heart.");
|
||||||
}
|
}
|
||||||
|
|
||||||
gpiod::line_request Heart::get_line_request(gpiod::chip& chip, const unsigned int lineOffset)
|
gpiod::line_request Heart::get_line_request(gpiod::chip& chip, const unsigned int lineOffset)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "../Logging/DixonLogger.h"
|
||||||
#include <gpiod.hpp>
|
#include <gpiod.hpp>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
|
@ -21,5 +22,6 @@ namespace cardio
|
||||||
gpiod::chip chip_;
|
gpiod::chip chip_;
|
||||||
bool isOn_;
|
bool isOn_;
|
||||||
gpiod::line_request request_;
|
gpiod::line_request request_;
|
||||||
|
Dixon::DixonLogger logger_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@ void DixonBrain::stop()
|
||||||
|
|
||||||
state_.setNodeStatus(NodeStatus::Stopping);
|
state_.setNodeStatus(NodeStatus::Stopping);
|
||||||
|
|
||||||
if (loopThread_.joinable())
|
|
||||||
loopThread_.join();
|
|
||||||
|
|
||||||
heart_.stop();
|
heart_.stop();
|
||||||
|
|
||||||
state_.setNodeStatus(NodeStatus::Stopped);
|
state_.setNodeStatus(NodeStatus::Stopped);
|
||||||
|
|
||||||
logger_.info("DixonBrain stopped.");
|
logger_.info("DixonBrain stopped.");
|
||||||
|
|
||||||
|
if (loopThread_.joinable())
|
||||||
|
loopThread_.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DixonBrain::runLoop()
|
void DixonBrain::runLoop()
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,30 @@
|
||||||
|
|
||||||
void signal_thread_func(sigset_t set) {
|
void signal_thread_func(sigset_t set) {
|
||||||
int sig;
|
int sig;
|
||||||
// Loop so we can catch multiple signals if the shutdown takes a moment
|
Dixon::DixonLogger logger("signal_thread_func");
|
||||||
while (DixonNodeState::instance().getNodeStatus() != NodeStatus::Stopping) {
|
|
||||||
|
while (true) {
|
||||||
|
// This blocks until a signal actually happens
|
||||||
if (sigwait(&set, &sig) == 0) {
|
if (sigwait(&set, &sig) == 0) {
|
||||||
std::cout << "\nShutdown signal received (" << sig << ")." << std::endl;
|
logger.info("Signal {} received.", sig);
|
||||||
DixonNodeState::instance().setNodeStatus(NodeStatus::Stopping);
|
|
||||||
// After setting 'Stopping', the loop will exit on next check
|
// 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 prepare_signal_set()
|
||||||
{
|
{
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
1.0.47
|
1.0.56
|
||||||
Loading…
Reference in a new issue