Migrate to a common timer class

This change pulls in sdeventplus and uses the timer implementation as
a drop in for the currently included timer.

Tested:
    Unit tests still build but are not currently running. Manually
    tested this change on a zaius machine and made sure timers went off.

Change-Id: I2808196581fc766843931403b83fead16926b0ae
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/Makefile.am b/Makefile.am
index a3fd0d6..fa3f92b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,6 @@
 		dhcp_configuration.hpp \
 		vlan_interface.hpp \
 		rtnetlink_server.hpp \
-		timer.hpp \
 		dns_updater.hpp \
 		watch.hpp \
 		argument.hpp
@@ -52,7 +51,6 @@
 		dhcp_configuration.cpp \
 		vlan_interface.cpp \
 		rtnetlink_server.cpp \
-		timer.cpp \
 		dns_updater.cpp \
 		watch.cpp
 
@@ -71,6 +69,7 @@
 phosphor_network_manager_LDFLAGS = \
 		$(SYSTEMD_LIBS) \
 		$(SDBUSPLUS_LIBS) \
+		$(SDEVENTPLUS_LIBS) \
 		$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
 		$(PHOSPHOR_LOGGING_LIBS) \
 		-lstdc++fs
@@ -78,6 +77,7 @@
 phosphor_network_manager_CXXFLAGS = \
 		$(SYSTEMD_CFLAGS) \
 		$(SDBUSPLUS_CFLAGS) \
+		$(SDEVENTPLUS_CFLAGS) \
 		$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
 		$(PHOSPHOR_LOGGING_CFLAGS) \
 		-flto
diff --git a/configure.ac b/configure.ac
index 48adff4..b7bfd18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,6 +34,8 @@
 PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],,\
 AC_MSG_ERROR(["Requires sdbusplus package."]))
 
+PKG_CHECK_MODULES([SDEVENTPLUS], [sdeventplus],,\
+AC_MSG_ERROR(["Requires sdeventplus package."]))
 
 AC_PATH_PROG([SDBUSPLUSPLUS], [sdbus++])
 
diff --git a/network_manager.cpp b/network_manager.cpp
index c1b0ba6..35a9fc8 100644
--- a/network_manager.cpp
+++ b/network_manager.cpp
@@ -4,7 +4,7 @@
 
 #include "ipaddress.hpp"
 #include "network_config.hpp"
-#include "timer.hpp"
+#include "types.hpp"
 #include "util.hpp"
 
 #include <arpa/inet.h>
@@ -25,8 +25,8 @@
 namespace network
 {
 
-extern std::unique_ptr<phosphor::network::Timer> refreshObjectTimer;
-extern std::unique_ptr<phosphor::network::Timer> restartTimer;
+extern std::unique_ptr<Timer> refreshObjectTimer;
+extern std::unique_ptr<Timer> restartTimer;
 using namespace phosphor::logging;
 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
 
@@ -207,15 +207,8 @@
     using namespace std::chrono;
     if (refreshObjectTimer && restartTimer)
     {
-        // start the restart timer.
-        auto restartTime =
-            duration_cast<microseconds>(phosphor::network::restartTimeout);
-        restartTimer->startTimer(restartTime);
-
-        // start the refresh timer.
-        auto refreshTime =
-            duration_cast<microseconds>(phosphor::network::refreshTimeout);
-        refreshObjectTimer->startTimer(refreshTime);
+        restartTimer->restartOnce(restartTimeout);
+        refreshObjectTimer->restartOnce(refreshTimeout);
     }
 }
 
diff --git a/network_manager_main.cpp b/network_manager_main.cpp
index 5f6b81b..7709f7d 100644
--- a/network_manager_main.cpp
+++ b/network_manager_main.cpp
@@ -3,16 +3,18 @@
 #include "dns_updater.hpp"
 #include "network_manager.hpp"
 #include "rtnetlink_server.hpp"
-#include "timer.hpp"
+#include "types.hpp"
 #include "watch.hpp"
 
 #include <linux/netlink.h>
 
+#include <functional>
 #include <memory>
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/server/manager.hpp>
+#include <sdeventplus/event.hpp>
 #include <xyz/openbmc_project/Common/error.hpp>
 
 namespace phosphor
@@ -21,8 +23,8 @@
 {
 
 std::unique_ptr<phosphor::network::Manager> manager = nullptr;
-std::unique_ptr<phosphor::network::Timer> refreshObjectTimer = nullptr;
-std::unique_ptr<phosphor::network::Timer> restartTimer = nullptr;
+std::unique_ptr<Timer> refreshObjectTimer = nullptr;
+std::unique_ptr<Timer> restartTimer = nullptr;
 
 /** @brief refresh the network objects. */
 void refreshObjects()
@@ -42,24 +44,17 @@
     restartSystemdUnit("systemd-networkd.service");
 }
 
-} // namespace network
-} // namespace phosphor
-
 void initializeTimers()
 {
-    std::function<void()> refreshFunc(
-        std::bind(&phosphor::network::refreshObjects));
-
-    std::function<void()> restartFunc(
-        std::bind(&phosphor::network::restartNetwork));
-
-    phosphor::network::refreshObjectTimer =
-        std::make_unique<phosphor::network::Timer>(refreshFunc);
-
-    phosphor::network::restartTimer =
-        std::make_unique<phosphor::network::Timer>(restartFunc);
+    auto event = sdeventplus::Event::get_default();
+    refreshObjectTimer =
+        std::make_unique<Timer>(event, std::bind(refreshObjects));
+    restartTimer = std::make_unique<Timer>(event, std::bind(restartNetwork));
 }
 
+} // namespace network
+} // namespace phosphor
+
 void createNetLinkSocket(phosphor::Descriptor& smartSock)
 {
     using namespace phosphor::logging;
@@ -81,7 +76,7 @@
 {
     using namespace phosphor::logging;
 
-    initializeTimers();
+    phosphor::network::initializeTimers();
 
     auto bus = sdbusplus::bus::new_default();
 
diff --git a/rtnetlink_server.cpp b/rtnetlink_server.cpp
index 3121e4d..2e2436b 100644
--- a/rtnetlink_server.cpp
+++ b/rtnetlink_server.cpp
@@ -1,6 +1,5 @@
 #include "rtnetlink_server.hpp"
 
-#include "timer.hpp"
 #include "types.hpp"
 #include "util.hpp"
 
@@ -22,7 +21,7 @@
 namespace network
 {
 
-extern std::unique_ptr<phosphor::network::Timer> refreshObjectTimer;
+extern std::unique_ptr<Timer> refreshObjectTimer;
 
 namespace rtnetlink
 {
@@ -47,13 +46,11 @@
             {
                 // starting the timer here to make sure that we don't want
                 // create the child objects multiple times.
-                if (refreshObjectTimer->isExpired())
+                if (refreshObjectTimer->hasExpired())
                 {
-                    using namespace std::chrono;
-                    auto time = duration_cast<microseconds>(refreshTimeout);
                     // if start timer throws exception then let the application
                     // crash
-                    refreshObjectTimer->startTimer(time);
+                    refreshObjectTimer->restartOnce(refreshTimeout);
                 } // end if
             }     // end if
 
diff --git a/test/Makefile.am b/test/Makefile.am
index b32e210..b726e53 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -21,6 +21,7 @@
 generic_cxx_flags = $(PTHREAD_CFLAGS) \
 					$(SYSTEMD_CFLAGS) \
 					$(SDBUSPLUS_CFLAGS) \
+					$(SDEVENTPLUS_CFLAGS) \
 					$(PHOSPHOR_LOGGING_CFLAGS) \
 					$(PHOSPHOR_DBUS_INTERFACES_CFLAGS)
 
@@ -28,6 +29,7 @@
 					$(OESDK_TESTCASE_FLAGS) \
 					$(SYSTEMD_LIBS) \
 					$(SDBUSPLUS_LIBS) \
+					$(SDEVENTPLUS_LIBS) \
 					$(PHOSPHOR_LOGGING_LIBS) \
 					$(PHOSPHOR_DBUS_INTERFACES_LIBS)
 
@@ -49,7 +51,6 @@
 			$(top_builddir)/ipaddress.o \
 			$(top_builddir)/routing_table.o \
 			$(top_builddir)/util.o \
-			$(top_builddir)/timer.o \
 			$(top_builddir)/rtnetlink_server.o \
 			$(top_builddir)/system_configuration.o \
 			$(top_builddir)/dhcp_configuration.o \
diff --git a/test/test_network_manager.cpp b/test/test_network_manager.cpp
index 1c0a116..d97b182 100644
--- a/test/test_network_manager.cpp
+++ b/test/test_network_manager.cpp
@@ -1,6 +1,5 @@
 #include "mock_syscall.hpp"
 #include "network_manager.hpp"
-#include "timer.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 
 #include <arpa/inet.h>
diff --git a/test/test_rtnetlink.cpp b/test/test_rtnetlink.cpp
index 4be3743..ee43bf4 100644
--- a/test/test_rtnetlink.cpp
+++ b/test/test_rtnetlink.cpp
@@ -1,13 +1,15 @@
 #include "mock_syscall.hpp"
 #include "network_manager.hpp"
 #include "rtnetlink_server.hpp"
-#include "timer.hpp"
 #include "types.hpp"
 
 #include <linux/rtnetlink.h>
 #include <net/if.h>
 
+#include <chrono>
+#include <functional>
 #include <sdbusplus/bus.hpp>
+#include <sdeventplus/event.hpp>
 
 #include <gtest/gtest.h>
 
@@ -34,9 +36,8 @@
 
 void initializeTimers()
 {
-    std::function<void()> refreshFunc(std::bind(&refreshObjects));
-
-    refreshObjectTimer = std::make_unique<Timer>(refreshFunc);
+    refreshObjectTimer = std::make_unique<Timer>(
+        sdeventplus::Event::get_default(), std::bind(refreshObjects));
 }
 
 class TestRtNetlink : public testing::Test
diff --git a/timer.cpp b/timer.cpp
deleted file mode 100644
index d257433..0000000
--- a/timer.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-#include "timer.hpp"
-
-#include <chrono>
-#include <phosphor-logging/elog-errors.hpp>
-#include <phosphor-logging/log.hpp>
-#include <xyz/openbmc_project/Common/error.hpp>
-
-namespace phosphor
-{
-namespace network
-{
-
-using namespace phosphor::logging;
-using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-// Initializes the timer object
-void Timer::initialize()
-{
-    // This can not be called more than once.
-    if (eventSource)
-    {
-        log<level::ERR>("Timer already initialized");
-        elog<InternalFailure>();
-    }
-
-    auto r = sd_event_default(&timeEvent);
-    if (r < 0)
-    {
-        log<level::ERR>("Failure in creating the sd_event",
-                        entry("ERROR=%d", r));
-
-        elog<InternalFailure>();
-    }
-
-    // Add infinite expiration time
-    r = sd_event_add_time(timeEvent, &eventSource,
-                          CLOCK_MONOTONIC, // Time base
-                          UINT64_MAX,      // Expire time - way long time
-                          0,               // Use default event accuracy
-                          timeoutHandler,  // Callback handler on timeout
-                          this);           // User data
-    if (r < 0)
-    {
-        log<level::ERR>("Failure to set initial expiration time value",
-                        entry("ERROR=%d", r));
-
-        elog<InternalFailure>();
-    }
-
-    // Disable the timer for now
-    r = setTimer(SD_EVENT_OFF);
-    if (r < 0)
-    {
-        log<level::ERR>("Failure to disable timer", entry("ERROR=%d", r));
-
-        elog<InternalFailure>();
-    }
-    return;
-}
-
-/** @brief callback handler on timeout */
-int Timer::timeoutHandler(sd_event_source* eventSource, uint64_t usec,
-                          void* userData)
-{
-    auto timer = static_cast<Timer*>(userData);
-    timer->expired = true;
-
-    // Call optional user call back function if available
-    if (timer->userCallBack)
-    {
-        timer->userCallBack();
-    }
-
-    sd_event_source_set_enabled(eventSource, SD_EVENT_OFF);
-    return 0;
-}
-
-// Gets the time from steady_clock
-std::chrono::microseconds Timer::getTime()
-{
-    using namespace std::chrono;
-    auto usec = steady_clock::now().time_since_epoch();
-    return duration_cast<microseconds>(usec);
-}
-
-// Enables or disables the timer
-int Timer::setTimer(int action)
-{
-    return sd_event_source_set_enabled(eventSource, action);
-}
-
-// Sets the time and arms the timer
-int Timer::startTimer(std::chrono::microseconds timeValue)
-{
-    // Disable the timer
-    setTimer(SD_EVENT_OFF);
-    expired = false;
-
-    // Get the current MONOTONIC time and add the delta
-    auto expireTime = getTime() + timeValue;
-
-    // Set the time
-    auto r = sd_event_source_set_time(eventSource, expireTime.count());
-    if (r < 0)
-    {
-        log<level::ERR>("Failure to set timer", entry("ERROR=%d", r));
-
-        elog<InternalFailure>();
-    }
-
-    // A ONESHOT timer means that when the timer goes off,
-    // its moves to disabled state.
-    r = setTimer(SD_EVENT_ONESHOT);
-    if (r < 0)
-    {
-        log<level::ERR>("Failure to start timer", entry("ERROR=%d", r));
-
-        elog<InternalFailure>();
-    }
-    return r;
-}
-
-} // namespace network
-} // namespace phosphor
diff --git a/timer.hpp b/timer.hpp
deleted file mode 100644
index 32b6f17..0000000
--- a/timer.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-#pragma once
-
-#include <systemd/sd-event.h>
-
-#include <chrono>
-#include <functional>
-
-namespace phosphor
-{
-namespace network
-{
-
-/** @class Timer
- *  @brief Usage would be,instantiate the timer with the call back
- *         and start the timer for the given time.
- */
-class Timer
-{
-  public:
-    /** @brief Only need the default Timer */
-    Timer() = delete;
-    Timer(const Timer&) = delete;
-    Timer& operator=(const Timer&) = delete;
-    Timer(Timer&&) = delete;
-    Timer& operator=(Timer&&) = delete;
-
-    /** @brief Constructs timer object
-     *
-     *  @param[in] funcCallBack - optional function callback for timer
-     *                            expirations
-     */
-    Timer(std::function<void()> userCallBack = nullptr) :
-        userCallBack(userCallBack)
-    {
-        // Initialize the timer
-        initialize();
-    }
-
-    ~Timer()
-    {
-        if (eventSource)
-        {
-            eventSource = sd_event_source_unref(eventSource);
-        }
-        if (timeEvent)
-        {
-            timeEvent = sd_event_unref(timeEvent);
-        }
-    }
-
-    inline auto isExpired() const
-    {
-        return expired;
-    }
-
-    /** @brief Starts the timer with specified expiration value.
-     *  input is an offset from the current steady_clock
-     */
-    int startTimer(std::chrono::microseconds usec);
-
-    /** @brief Enables / disables the timer */
-    int setTimer(int action);
-
-  private:
-    /** @brief the sd_event structure */
-    sd_event* timeEvent = nullptr;
-
-    /** @brief Source of events */
-    sd_event_source* eventSource = nullptr;
-
-    bool expired = true;
-
-    /** @brief Initializes the timer object with infinite
-     *         expiration time and sets up the callback handler
-     *
-     *  @return None.
-     *
-     *  @error std::runtime exception thrown
-     */
-    void initialize();
-
-    /** @brief Callback function when timer goes off
-     *
-     *  @param[in] eventSource - Source of the event
-     *  @param[in] usec        - time in micro seconds
-     *  @param[in] userData    - User data pointer
-     *
-     */
-    static int timeoutHandler(sd_event_source* eventSource, uint64_t usec,
-                              void* userData);
-
-    /** @brief Gets the current time from steady clock */
-    static std::chrono::microseconds getTime();
-
-    /** @brief Optional function to call on timer expiration */
-    std::function<void()> userCallBack;
-};
-
-} // namespace network
-} // namespace phosphor
diff --git a/types.hpp b/types.hpp
index b8038b4..9ffe5ad 100644
--- a/types.hpp
+++ b/types.hpp
@@ -8,6 +8,8 @@
 #include <list>
 #include <map>
 #include <memory>
+#include <sdeventplus/clock.hpp>
+#include <sdeventplus/utility/timer.hpp>
 #include <set>
 #include <string>
 #include <vector>
@@ -76,5 +78,7 @@
 using IntfAddrMap = std::map<IntfName, AddrList>;
 using InterfaceList = std::set<IntfName>;
 
+using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>;
+
 } // namespace network
 } // namespace phosphor