main: Leverage common function for loop

sdeventplus now has a common function that works around dbus memory
leaks when being used with sdbus.

Change-Id: Id4a405508296c63158abfa28c4063a386704480b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/mainapp.cpp b/src/mainapp.cpp
index 7d64ec7..bd65335 100644
--- a/src/mainapp.cpp
+++ b/src/mainapp.cpp
@@ -28,6 +28,7 @@
 #include <sdbusplus/server/manager.hpp>
 #include <sdeventplus/event.hpp>
 #include <sdeventplus/source/signal.hpp>
+#include <sdeventplus/utility/sdbus.hpp>
 #include <stdplus/signal.hpp>
 #include <string>
 #include <xyz/openbmc_project/Common/error.hpp>
@@ -225,13 +226,11 @@
         // Add systemd object manager.
         sdbusplus::server::manager_t watchdogManager(bus, path.c_str());
 
-        // Attach the bus to sd_event to service user requests
-        bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
-
         // Create a watchdog object
         Watchdog watchdog(bus, path.c_str(), event, std::move(actionTargetMap),
                           std::move(maybeFallback), minInterval,
-                          defaultInterval);
+                          defaultInterval,
+                          /*exitAfterTimeout=*/!continueAfterTimeout);
 
         std::optional<sdbusplus::bus::match_t> watchPostcodeMatch;
         if (watchPostcodes)
@@ -248,26 +247,15 @@
         // Claim the bus
         bus.request_name(service.c_str());
 
-        bool done = false;
-        auto intCb = [&](sdeventplus::source::Signal&,
-                         const struct signalfd_siginfo*) { done = true; };
+        auto intCb = [](sdeventplus::source::Signal& s,
+                        const struct signalfd_siginfo*) {
+            s.get_event().exit(0);
+        };
         stdplus::signal::block(SIGINT);
         sdeventplus::source::Signal sigint(event, SIGINT, intCb);
         stdplus::signal::block(SIGTERM);
         sdeventplus::source::Signal sigterm(event, SIGTERM, std::move(intCb));
-
-        // Loop until our timer expires and we don't want to continue
-        while (!done && (continueAfterTimeout || !watchdog.timerExpired()))
-        {
-            // Process all outstanding bus events before running the loop.
-            // This prevents the sd-bus handling logic from leaking memory.
-            // TODO: Remove when upstream fixes this bug
-            while (bus.process_discard() > 0)
-                ;
-
-            // Run and never timeout
-            event.run(std::nullopt);
-        }
+        return sdeventplus::utility::loopWithBus(event, bus);
     }
     catch (const InternalFailure& e)
     {
@@ -276,5 +264,5 @@
         // Need a coredump in the error cases.
         std::terminate();
     }
-    return 0;
+    return 1;
 }
diff --git a/src/watchdog.cpp b/src/watchdog.cpp
index eda2d7f..c401022 100644
--- a/src/watchdog.cpp
+++ b/src/watchdog.cpp
@@ -161,6 +161,11 @@
                         entry("ERROR=%s", e.what()));
     }
 
+    if (exitAfterTimeout)
+    {
+        timer.get_event().exit(0);
+    }
+
     tryFallbackOrDisable();
 }
 
diff --git a/src/watchdog.hpp b/src/watchdog.hpp
index 16f05f1..a0693ee 100644
--- a/src/watchdog.hpp
+++ b/src/watchdog.hpp
@@ -55,25 +55,26 @@
 
     /** @brief Constructs the Watchdog object
      *
-     *  @param[in] bus             - DBus bus to attach to.
-     *  @param[in] objPath         - Object path to attach to.
-     *  @param[in] event           - reference to sdeventplus::Event loop
-     *  @param[in] actionTargets   - map of systemd targets called on timeout
-     *  @param[in] fallback        - fallback watchdog
-     *  @param[in] minInterval     - minimum intervale value allowed
-     *  @param[in] defaultInterval - default interval to start with
+     *  @param[in] bus              - DBus bus to attach to.
+     *  @param[in] objPath          - Object path to attach to.
+     *  @param[in] event            - reference to sdeventplus::Event loop
+     *  @param[in] actionTargets    - map of systemd targets called on timeout
+     *  @param[in] fallback         - fallback watchdog
+     *  @param[in] minInterval      - minimum intervale value allowed
+     *  @param[in] defaultInterval  - default interval to start with
+     *  @param[in] exitAfterTimeout - should the event loop be terminated
      */
     Watchdog(sdbusplus::bus_t& bus, const char* objPath,
              const sdeventplus::Event& event,
              ActionTargetMap&& actionTargetMap = {},
              std::optional<Fallback>&& fallback = std::nullopt,
              uint64_t minInterval = DEFAULT_MIN_INTERVAL_MS,
-             uint64_t defaultInterval = 0) :
+             uint64_t defaultInterval = 0, bool exitAfterTimeout = false) :
         WatchdogInherits(bus, objPath),
         bus(bus), actionTargetMap(std::move(actionTargetMap)),
         fallback(fallback), minInterval(minInterval),
         timer(event, std::bind(&Watchdog::timeOutHandler, this)),
-        objPath(objPath)
+        objPath(objPath), exitAfterTimeout(exitAfterTimeout)
     {
         // Use default if passed in otherwise just use default that comes
         // with object
@@ -186,6 +187,9 @@
 
     /** @brief Object path of the watchdog */
     std::string_view objPath;
+
+    /** @brief Do we terminate after exit */
+    bool exitAfterTimeout;
 };
 
 } // namespace watchdog