Remove redundant async call in collection threads

This commit removes the redundant std:async call in the detached thread
launched for parsing and publishing the VPD for an individual FRU. Since
we have a dedicated detached thread for each FRU, we can do VPD parse
and publish in a synchronous manner from the detached thread itself,
instead of launching a asynchronous task which adds unnecessary
performance cost. This commit also handles any exception thrown while
launching the detached thread for a FRU. In case launching detached
thread for a FRU fails, we add the EEPROM path of the FRU to a "failed
EEPROM" list. This list can be handled by Manager later on.

Test:
```
- Install bitbaked image on Everest system.

- Check vpd-manager service status:
root@p10bmc:~# systemctl show vpd-manager -p NRestarts
NRestarts=0

- Check BMC reaches ready state:
root@p10bmc:~# obmcutil state
CurrentBMCState     : xyz.openbmc_project.State.BMC.BMCState.Ready
CurrentPowerState   : xyz.openbmc_project.State.Chassis.PowerState.On
CurrentHostState    : xyz.openbmc_project.State.Host.HostState.Running
BootProgress        : xyz.openbmc_project.State.Boot.Progress.
ProgressStages.OSRunning
OperatingSystemState: xyz.openbmc_project.State.OperatingSystem.Status.
OSStatus.Inactive

-Check CollectionStatus property of vpd-manager D-Bus service:
root@p10bmc:~# busctl get-property com.ibm.VPD.Manager /com/ibm/VPD/
Manager com.ibm.VPD.Manager CollectionStatus
s "Completed"

- Check execution time change
Measure the time between vpd-manager event loop start and
CollectionStatus = Completed on a Everest system. Following figures were
measured across 3 reboots:
- On current code, (with the extra async call) it is 61 secs.
- With the changes in this PR, it is 60.33 secs.
```

Change-Id: I86dd9f9f6a4c67b8159e4c90d6ffdb005568cf6b
Signed-off-by: Souvik Roy <souvikroyofficial10@gmail.com>
diff --git a/vpd-manager/include/manager.hpp b/vpd-manager/include/manager.hpp
index cb64123..73d82c2 100644
--- a/vpd-manager/include/manager.hpp
+++ b/vpd-manager/include/manager.hpp
@@ -255,6 +255,11 @@
      * @param[in] i_msg - The callback message.
      */
     void processAssetTagChangeCallback(sdbusplus::message_t& i_msg);
+
+    /**
+     * @brief API to process VPD collection thread failed EEPROMs.
+     */
+    void processFailedEeproms();
 #endif
 
     /**
diff --git a/vpd-manager/include/worker.hpp b/vpd-manager/include/worker.hpp
index ac1b3d8..a9725c3 100644
--- a/vpd-manager/include/worker.hpp
+++ b/vpd-manager/include/worker.hpp
@@ -148,6 +148,21 @@
         return m_activeCollectionThreadCount;
     }
 
+    /**
+     * @brief API to get list of EEPROMs for which thread creation failed.
+     *
+     * This API returns reference to list of EEPROM paths for which VPD
+     * collection thread creation has failed. Manager needs to process this list
+     * of EEPROMs and take appropriate action.
+     *
+     * @return reference to list of EEPROM paths for which VPD collection thread
+     * creation has failed
+     */
+    inline std::forward_list<std::string>& getFailedEepromPaths() noexcept
+    {
+        return m_failedEepromPaths;
+    }
+
   private:
     /**
      * @brief An API to parse and publish a FRU VPD over D-Bus.
@@ -546,5 +561,8 @@
 
     // Counting semaphore to limit the number of threads.
     std::counting_semaphore<constants::MAX_THREADS> m_semaphore;
+
+    // List of EEPROM paths for which VPD collection thread creation has failed.
+    std::forward_list<std::string> m_failedEepromPaths;
 };
 } // namespace vpd
diff --git a/vpd-manager/src/manager.cpp b/vpd-manager/src/manager.cpp
index dd00d92..1e3f3d5 100644
--- a/vpd-manager/src/manager.cpp
+++ b/vpd-manager/src/manager.cpp
@@ -286,6 +286,7 @@
         {
             // cancel the timer
             l_timer.cancel();
+            processFailedEeproms();
             m_interface->set_property("CollectionStatus",
                                       std::string("Completed"));
 
@@ -923,4 +924,16 @@
             "VPD recollection failed with error: " + std::string(l_ex.what()));
     }
 }
+
+void Manager::processFailedEeproms()
+{
+    if (m_worker.get() != nullptr)
+    {
+        // TODO:
+        // - iterate through list of EEPROMs for which thread creation has
+        // failed
+        // - For each failed EEPROM, trigger VPD collection
+        m_worker->getFailedEepromPaths().clear();
+    }
+}
 } // namespace vpd
diff --git a/vpd-manager/src/worker.cpp b/vpd-manager/src/worker.cpp
index a0978c8..c1e6b38 100644
--- a/vpd-manager/src/worker.cpp
+++ b/vpd-manager/src/worker.cpp
@@ -1567,19 +1567,26 @@
             continue;
         }
 
-        std::thread{[vpdFilePath, this]() {
-            const auto& l_parseResult = parseAndPublishVPD(vpdFilePath);
+        try
+        {
+            std::thread{[vpdFilePath, this]() {
+                const auto& l_parseResult = parseAndPublishVPD(vpdFilePath);
 
-            // thread returned.
-            m_mutex.lock();
-            m_activeCollectionThreadCount--;
-            m_mutex.unlock();
+                m_mutex.lock();
+                m_activeCollectionThreadCount--;
+                m_mutex.unlock();
 
-            if (!m_activeCollectionThreadCount)
-            {
-                m_isAllFruCollected = true;
-            }
-        }}.detach();
+                if (!m_activeCollectionThreadCount)
+                {
+                    m_isAllFruCollected = true;
+                }
+            }}.detach();
+        }
+        catch (const std::exception& l_ex)
+        {
+            // add vpdFilePath(EEPROM path) to failed list
+            m_failedEepromPaths.push_front(vpdFilePath);
+        }
     }
 }