#pragma once #include #include #include #include namespace phosphor { namespace watchdog { /* Need a custom deleter for freeing up sd_event */ struct EventDeleter { void operator()(sd_event* event) const { event = sd_event_unref(event); } }; using EventPtr = std::unique_ptr; /* Need a custom deleter for freeing up sd_event_source */ struct EventSourceDeleter { void operator()(sd_event_source* eventSource) const { eventSource = sd_event_source_unref(eventSource); } }; using EventSourcePtr = std::unique_ptr; /** @class Timer * @brief Manages starting timers and handling timeouts */ class Timer { public: Timer() = delete; ~Timer() = default; Timer(const Timer&) = delete; Timer& operator=(const Timer&) = delete; Timer(Timer&&) = delete; Timer& operator=(Timer&&) = delete; /** @brief Constructs timer object * * @param[in] event - sd_event unique pointer * @param[in] userCallBack - Optional function callback * for timer expiration */ Timer(EventPtr& event, std::function userCallBack = nullptr) : event(event), userCallBack(userCallBack) { // Initialize the timer initialize(); } void clearExpired(void) { expire = false; } /** @brief Tells whether the timer is expired or not */ inline auto expired() const { return expire; } /** @brief Returns the current Timer enablement type */ int getEnabled() const; /** @brief Enables / disables the timer. * is an integral constant boolean */ template void setEnabled() { constexpr auto type = T::value ? SD_EVENT_ONESHOT : SD_EVENT_OFF; return setEnabled(type); } /** @brief Returns time remaining in usec before expiration * which is an offset to current steady clock */ std::chrono::microseconds getRemaining() const; /** @brief Starts the timer with specified expiration value. * std::steady_clock is used for base time. * * @param[in] usec - Microseconds from the current time * before expiration. * * @return None. * * @error Throws exception */ void start(std::chrono::microseconds usec); /** @brief Gets the current time from steady clock */ static std::chrono::microseconds getCurrentTime(); private: /** @brief Reference to sd_event unique pointer */ EventPtr& event; /** @brief event source */ EventSourcePtr eventSource; /** @brief Set to true when the timeoutHandler is called into */ bool expire = false; /** @brief Optional function to call on timer expiration * This is called from timeout handler. */ std::function userCallBack; /** @brief Initializes the timer object with infinite * expiration time and sets up the callback handler * * @return None. * * @error Throws exception */ void initialize(); /** @brief Callback function when timer goes off * * @param[in] eventSource - Source of the event * @param[in] usec - time in microseconds * @param[in] userData - User data pointer * */ static int timeoutHandler(sd_event_source* eventSource, uint64_t usec, void* userData); /** @brief Enables / disables the timer * * @param[in] type - Timer type. * This implementation uses only SD_EVENT_OFF * and SD_EVENT_ONESHOT */ void setEnabled(int type); }; } // namespace watchdog } // namespace phosphor