From 2123696e4de17f3f98f12581b2ca6f1ff1500b07 Mon Sep 17 00:00:00 2001 From: Carl Philipp Klemm <philipp@uvos.xyz> Date: Tue, 31 Oct 2023 16:35:44 +0100 Subject: [PATCH] Add a timeout to biocontrol waiting, and retry if biocontrol fails --- biocontrol.cpp | 43 ++++++++++++++++++++++++++++++------------- biocontrol.h | 8 ++++---- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/biocontrol.cpp b/biocontrol.cpp index 122f253..d0ea035 100644 --- a/biocontrol.cpp +++ b/biocontrol.cpp @@ -1,6 +1,8 @@ #include "biocontrol.h" +#include <chrono> #include <string> +#include <thread> #include <unistd.h> #include <errno.h> #include <stdexcept> @@ -11,6 +13,7 @@ #include <errno.h> #include <sstream> #include <fstream> +#include <signal.h> #include "log.h" @@ -52,6 +55,11 @@ void BioControl::execBiocontrol(const std::string& command, const std::string& u { int biopipe = open(biopipefilename, O_RDONLY | O_CLOEXEC); + if(biopipe < 0) + { + kill(childPid, SIGTERM); + throw std::runtime_error(std::string(__func__) + ": unable to open pipe: " + std::string(strerror(errno))); + } if(biopipe >= 0) { @@ -65,21 +73,29 @@ void BioControl::execBiocontrol(const std::string& command, const std::string& u Log(Log::DEBUG)<<"Wating for biocontrol to exit"; int exitCode; - waitpid(childPid, &exitCode, 0); + int timeout = 7200*2; + ret = 0; + while((ret = waitpid(childPid, &exitCode, WNOHANG)) == 0 && --timeout > 0) + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + if(ret == 0) + { + kill(childPid, SIGKILL); + throw std::runtime_error(std::string(__func__) + ": biocontol has hanged"); + } + if(exitCode != 0) { close(biopipe); throw std::runtime_error(std::string(__func__) + ": biocontol failed with: " + std::to_string(exitCode)); } - - if(biopipe < 0) - throw std::runtime_error(std::string(__func__) + ": unable to open pipe: " + std::string(strerror(errno))); } } -bool BioControl::measure_eis(const std::filesystem::path& outPath, const std::string& userstr) +bool BioControl::measure_eis(const std::filesystem::path& outPath, const std::string& userstr, bool retry) { std::string mesurement; + try { execBiocontrol("geis", userstr, mesurement); @@ -87,7 +103,8 @@ bool BioControl::measure_eis(const std::filesystem::path& outPath, const std::st catch(const std::runtime_error& err) { Log(Log::ERROR)<<err.what(); - return false; + + return retry ? measure_eis(outPath, userstr, false) : false; } std::fstream file(outPath, std::ios_base::out); @@ -103,7 +120,7 @@ bool BioControl::measure_eis(const std::filesystem::path& outPath, const std::st return true; } -bool BioControl::measure_ocv(float& ocv) +bool BioControl::measure_ocv(float& ocv, bool retry) { std::string mesurement; try @@ -114,12 +131,12 @@ bool BioControl::measure_ocv(float& ocv) catch(const std::runtime_error& err) { Log(Log::ERROR)<<err.what(); - return false; + return retry ? measure_ocv(ocv, false) : false; } catch(const std::invalid_argument& err) { Log(Log::ERROR)<<"Could not convert "<<mesurement<<": "<<err.what(); - return false; + return retry ? measure_ocv(ocv, false) : false; } return true; @@ -132,12 +149,12 @@ bool BioControl::shorted(bool& shorted) return true; } -bool BioControl::charge(float fraction, float current, const std::filesystem::path& outPath, const std::string& userstr) +bool BioControl::charge(float fraction, float current, const std::filesystem::path& outPath, const std::string& userstr, bool retry) { - return chargeToVoltage(3.1 + fraction*(4.2-3.1), current, outPath, userstr); + return chargeToVoltage(3.1 + fraction*(4.2-3.1), current, outPath, userstr, retry); } -bool BioControl::chargeToVoltage(float voltage, float current, const std::filesystem::path& outPath, const std::string& userstr) +bool BioControl::chargeToVoltage(float voltage, float current, const std::filesystem::path& outPath, const std::string& userstr, bool retry) { float ocv; bool ret = measure_ocv(ocv); @@ -163,7 +180,7 @@ bool BioControl::chargeToVoltage(float voltage, float current, const std::filesy catch(const std::runtime_error& err) { Log(Log::ERROR)<<err.what(); - return false; + return retry ? chargeToVoltage(voltage, current, outPath, userstr, false) : false; } std::fstream file(outPath, std::ios_base::out); diff --git a/biocontrol.h b/biocontrol.h index 21b3985..957c9be 100644 --- a/biocontrol.h +++ b/biocontrol.h @@ -16,9 +16,9 @@ public: BioControl() = default; BioControl(const std::filesystem::path& exepath, const std::string& ipAddr); - bool measure_eis(const std::filesystem::path& outPath, const std::string& userstr); - bool measure_ocv(float& ocv); + bool measure_eis(const std::filesystem::path& outPath, const std::string& userstr, bool retry = true); + bool measure_ocv(float& ocv, bool retry = true); bool shorted(bool& shorted); - bool charge(float fraction, float current, const std::filesystem::path& outPath, const std::string& userstr); - bool chargeToVoltage(float voltage, float current, const std::filesystem::path& outPath, const std::string& userstr); + bool charge(float fraction, float current, const std::filesystem::path& outPath, const std::string& userstr, bool retry = true); + bool chargeToVoltage(float voltage, float current, const std::filesystem::path& outPath, const std::string& userstr, bool retry = true); }; -- GitLab