nvidia-gpu: Fix a number of object lifetime issues
Moves all subsensors and objects treated as shared_ptrs
to be using shared_from_this. This way, if there's an object lifetime
issue we don't segfault.
Also separates construction and asio init for NvidiaSmaDevice
so that when we bind to this, its valid after we leave the ctor
Change-Id: I8e3115bc276d2e0eaac0b1dc9a9d2c46e6751d4b
Signed-off-by: Marc Olberding <molberding@nvidia.com>
diff --git a/src/nvidia-gpu/Inventory.cpp b/src/nvidia-gpu/Inventory.cpp
index 6796a32..e41802a 100644
--- a/src/nvidia-gpu/Inventory.cpp
+++ b/src/nvidia-gpu/Inventory.cpp
@@ -152,9 +152,15 @@
 
     mctpRequester.sendRecvMsg(
         eid, requestBuffer,
-        [this, propertyId](const std::error_code& result,
-                           std::span<const uint8_t> buffer) {
-            this->handleInventoryPropertyResponse(propertyId, result, buffer);
+        [weak{weak_from_this()}, propertyId](const std::error_code& ec,
+                                             std::span<const uint8_t> buffer) {
+            std::shared_ptr<Inventory> self = weak.lock();
+            if (!self)
+            {
+                lg2::error("Invalid Inventory reference");
+                return;
+            }
+            self->handleInventoryPropertyResponse(propertyId, ec, buffer);
         });
 }
 
@@ -277,15 +283,22 @@
         else
         {
             retryTimer.expires_after(retryDelay);
-            retryTimer.async_wait([this](const boost::system::error_code& ec) {
-                if (ec)
-                {
-                    lg2::error("Retry timer error for {NAME}: {ERROR}", "NAME",
-                               name, "ERROR", ec.message());
-                    return;
-                }
-                this->processNextProperty();
-            });
+            retryTimer.async_wait(
+                [weak{weak_from_this()}](const boost::system::error_code& ec) {
+                    std::shared_ptr<Inventory> self = weak.lock();
+                    if (!self)
+                    {
+                        lg2::error("Invalid reference to Inventory");
+                        return;
+                    }
+                    if (ec)
+                    {
+                        lg2::error("Retry timer error for {NAME}: {ERROR}",
+                                   "NAME", self->name, "ERROR", ec.message());
+                        return;
+                    }
+                    self->processNextProperty();
+                });
             return;
         }
     }