Use two-phase init to prevent calling a pure virtual
When the background reader starts "too early", before the derived class'
constructor has finished, it results in calling a pure virtual:
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
#5 0xb6a5e0c8 in std::terminate() () from /lib/libstdc++.so.6
#6 0xb6a5efec in __cxa_pure_virtual () from /lib/libstdc++.so.6
#7 0x0050bf34 in operator() (__closure=0x263ca04) at /home/jkt/work/prog/_build/_br-cfb/build/velia-custom/src/ietf-hardware/FspYh.cpp:97
#8 std::__invoke_impl<void, velia::ietf_hardware::FspYh::FspYh(const std::filesystem::__cxx11::path&, const std::string&, std::shared_ptr<velia::ietf_hardware::TransientI2C>)::<lambda()> > (__f=...)
at /home/jkt/work/prog/_build/_br-cfb/per-package/velia/host/opt/ext-toolchain/arm-buildroot-linux-gnueabihf/include/c++/13.2.0/bits/invoke.h:61
#9 std::__invoke<velia::ietf_hardware::FspYh::FspYh(const std::filesystem::__cxx11::path&, const std::string&, std::shared_ptr<velia::ietf_hardware::TransientI2C>)::<lambda()> > (__fn=...)
at /home/jkt/work/prog/_build/_br-cfb/per-package/velia/host/opt/ext-toolchain/arm-buildroot-linux-gnueabihf/include/c++/13.2.0/bits/invoke.h:96
#10 std::thread::_Invoker<std::tuple<velia::ietf_hardware::FspYh::FspYh(const std::filesystem::__cxx11::path&, const std::string&, std::shared_ptr<velia::ietf_hardware::TransientI2C>)::<lambda()> > >::_M_invoke<0> (this=0x263ca04) at /home/jkt/work/prog/_build/_br-cfb/per-package/velia/host/opt/ext-toolchain/arm-buildroot-linux-gnueabihf/include/c++/13.2.0/bits/std_thread.h:292
#11 std::thread::_Invoker<std::tuple<velia::ietf_hardware::FspYh::FspYh(const std::filesystem::__cxx11::path&, const std::string&, std::shared_ptr<velia::ietf_hardware::TransientI2C>)::<lambda()> > >::operator() (this=0x263ca04) at /home/jkt/work/prog/_build/_br-cfb/per-package/velia/host/opt/ext-toolchain/arm-buildroot-linux-gnueabihf/include/c++/13.2.0/bits/std_thread.h:299
#12 std::thread::_State_impl<std::thread::_Invoker<std::tuple<velia::ietf_hardware::FspYh::FspYh(const std::filesystem::__cxx11::path&, const std::string&, std::shared_ptr<velia::ietf_hardware::TransientI2C>)::<lambda()> > > >::_M_run(void) (this=0x263ca00)
at /home/jkt/work/prog/_build/_br-cfb/per-package/velia/host/opt/ext-toolchain/arm-buildroot-linux-gnueabihf/include/c++/13.2.0/bits/std_thread.h:244
#13 0xb6a8bdb4 in ?? () from /lib/libstdc++.so.6
#14 0xb687534c in ?? () from /lib/libc.so.6
Change-Id: Ie73d64e5d6d669db3264cfa7b44467a866a21577
diff --git a/src/ietf-hardware/FspYh.cpp b/src/ietf-hardware/FspYh.cpp
index bb3c9af..eb976c1 100644
--- a/src/ietf-hardware/FspYh.cpp
+++ b/src/ietf-hardware/FspYh.cpp
@@ -83,6 +83,10 @@
, m_staticData(velia::ietf_hardware::data_reader::StaticData(m_namePrefix, "ne", {{"class", "iana-hardware:power-supply"}})().data)
{
m_exit = false;
+}
+
+void FspYh::startThread()
+{
m_psuWatcher = std::thread([this] {
while (!m_exit) {
if (m_i2c->isPresent()) {
@@ -158,6 +162,12 @@
return res;
}
+FspYhPsu::FspYhPsu(const std::filesystem::path& hwmonDir, const std::string& psu, std::shared_ptr<TransientI2C> i2c)
+ : FspYh(hwmonDir, psu, i2c)
+{
+ startThread();
+}
+
void FspYhPsu::createPower()
{
m_hwmon = std::make_shared<velia::ietf_hardware::sysfs::HWMon>(m_hwmonDir);
@@ -243,6 +253,12 @@
return "PSU is unplugged.";
}
+FspYhPdu::FspYhPdu(const std::filesystem::path& hwmonDir, const std::string& pdu, std::shared_ptr<TransientI2C> i2c)
+ : FspYh(hwmonDir, pdu, i2c)
+{
+ startThread();
+}
+
void FspYhPdu::createPower()
{
m_hwmon = std::make_shared<velia::ietf_hardware::sysfs::HWMon>(m_hwmonDir);
diff --git a/src/ietf-hardware/FspYh.h b/src/ietf-hardware/FspYh.h
index 50b3834..dd6e558 100644
--- a/src/ietf-hardware/FspYh.h
+++ b/src/ietf-hardware/FspYh.h
@@ -56,16 +56,17 @@
virtual void createPower() = 0;
virtual std::string missingAlarmDescription() const = 0;
+ void startThread();
};
struct FspYhPsu : public FspYh {
- using FspYh::FspYh;
+ FspYhPsu(const std::filesystem::path& hwmonDir, const std::string& psu, std::shared_ptr<TransientI2C> i2c);
void createPower() override;
std::string missingAlarmDescription() const override;
};
struct FspYhPdu : public FspYh {
- using FspYh::FspYh;
+ FspYhPdu(const std::filesystem::path& hwmonDir, const std::string& pdu, std::shared_ptr<TransientI2C> i2c);
void createPower() override;
std::string missingAlarmDescription() const override;
};