blob: 02c1750bd66fa1bdb82e747f9f286d67643f322b [file] [log] [blame]
#pragma once
#include <optional>
#include <sdeventplus/internal/sdevent.hpp>
#include <sdeventplus/types.hpp>
#include <stdplus/handle/copyable.hpp>
#include <systemd/sd-event.h>
namespace sdeventplus
{
/** @class Event
* @brief C++ Wrapper around sd_event objects
*/
class Event
{
public:
/** @brief Duration type used for specifying timeouts
*/
using Timeout = SdEventDuration;
using MaybeTimeout = std::optional<Timeout>;
/** @brief Constructs a new event from sd_event
* Takes a reference on the passed in sd_event
*
* @param[in] event - The sd_event to wrap
* @param[in] sdevent - Optional underlying sd_event implementation
* @throws SdEventError for underlying sd_event errors
*/
Event(sd_event* event,
const internal::SdEvent* sdevent = &internal::sdevent_impl);
/** @brief Constructs a new event from sd_event
* Does not take a reference on the passed in sd_event
* @note This will still take a reference during future copies
* Useful for first creation of an sd_event
*
* @param[in] event - The sd_event to wrap
* @param[in] - Denotes no reference taken during construction
* @param[in] sdevent - Optional underlying sd_event implementation
* @throws SdEventError for underlying sd_event errors
*/
Event(sd_event* event, std::false_type,
const internal::SdEvent* sdevent = &internal::sdevent_impl);
/** @brief Constructs a new non-owning event from an event
* Does not take a reference on the passed in sd_event
* Does not release the reference it is given
* @note This will still take a reference during future copies
* @internal
*
* @param[in] other - The other Event to copy
* @param[in] - Denotes no reference taken or release
*/
Event(const Event& other, sdeventplus::internal::NoOwn);
/** @brief Create a wrapped event around sd_event_new()
*
* @param[in] sdevent - Optional underlying sd_event implementation
* @throws SdEventError for underlying sd_event errors
* @return A new Event
*/
static Event
get_new(const internal::SdEvent* sdevent = &internal::sdevent_impl);
/** @brief Create a wrapped event around sd_event_default()
*
* @param[in] sdevent - Optional underlying sd_event implementation
* @throws SdEventError for underlying sd_event errors
* @return A new default Event
*/
static Event
get_default(const internal::SdEvent* sdevent = &internal::sdevent_impl);
/** @brief Get the underlying sd_event
*
* @return The sd_event
*/
sd_event* get() const;
/** @brief Get the sd_event interface in use
*
* @return The sd_event interface
*/
const internal::SdEvent* getSdEvent() const;
/** @brief Check for pending events and arm timers
*
* @throws SdEventError for underlying sd_event errors
* @return Positive value if events are pending, 0 otherwise
*/
int prepare() const;
/** @brief Waits for new events to process
*
* @param[in] timeout - nullopt for no timeout or a finite timeout
* @throws SdEventError for underlying sd_event errors
* @return Positive value if events are pending, 0 otherwise
* Only returns 0 a finite timeout is reached
*/
int wait(MaybeTimeout timeout) const;
/** @brief Executes the highest priority event
*
* @throws SdEventError for underlying sd_event errors
* @return Positive value if the event loop should continue
* 0 value if the event loop should exit
*/
int dispatch() const;
/** @brief Runs a single iteration of the event loop
*
* @param[in] timeout - nullopt for no timeout or a finite timeout
* @throws SdEventError for underlying sd_event errors
* @return Positive value if an event was dispatched
* Only returns 0 a finite timeout is reached
*/
int run(MaybeTimeout timeout) const;
/** @brief Run the event loop to completion
*
* @throws SdEventError for underlying sd_event errors
* @return Exit status of the event loop from exit()
*/
int loop() const;
/** @brief Sets the exit code for the loop and notifies
* the event loop it should terminate
*
* @param[in] code - The exit code
* @throws SdEventError for underlying sd_event errors
*/
void exit(int code) const;
/** @brief Gets the exit code for the event loop
*
* @throws SdEventError for underlying sd_event errors
* @return The exit code specified by a previous exit()
*/
int get_exit_code() const;
/** @brief Get the status of the event loop watchdog
*
* @throws SdEventError for underlying sd_event errors
* @return 'true' if the watchdog is supported and enabled
* 'false' otherwise
*/
bool get_watchdog() const;
/** @brief Sets the state of the event loop watchdog
*
* @param[in] b - Should the event loop attempt to enable the watchdog
* @throws SdEventError for underlying sd_event errors
* @return 'true' if the watchdog is supported and enabled
* 'false' otherwise
*/
bool set_watchdog(bool b) const;
private:
static sd_event* ref(sd_event* const& event,
const internal::SdEvent*& sdevent, bool& owned);
static void drop(sd_event*&& event, const internal::SdEvent*& sdevent,
bool& owned);
const internal::SdEvent* sdevent;
stdplus::Copyable<sd_event*, const internal::SdEvent*, bool>::Handle<drop,
ref>
event;
};
} // namespace sdeventplus