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