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