blob: 9ef579127fdb8a57f85c4e7b5afdb19d45ca7ee7 [file] [log] [blame]
Brad Bishop605662d2017-05-30 12:39:09 -04001#pragma once
2
Patrick Venture3d6d3182018-08-31 09:33:09 -07003#include <systemd/sd-event.h>
4
Brad Bishop605662d2017-05-30 12:39:09 -04005#include <chrono>
6#include <memory>
7#include <sdbusplus/bus.hpp>
Brad Bishop605662d2017-05-30 12:39:09 -04008
9// TODO: openbmc/openbmc#1720 - add error handling for sd_event API failures
10
11namespace sdevent
12{
13namespace event
14{
15namespace timer
16{
17class Timer;
18} // namespace timer
Patrick Ventureac803952018-08-31 09:28:31 -070019} // namespace event
Brad Bishop605662d2017-05-30 12:39:09 -040020namespace event
21{
22
23using EventPtr = sd_event*;
24class Event;
25
26/** @brief Get an instance of the 'default' event. */
27Event newDefault();
28
29namespace details
30{
31
32/** @brief unique_ptr functor to release an event reference. */
33struct EventDeleter
34{
35 void operator()(sd_event* ptr) const
36 {
37 deleter(ptr);
38 }
39
40 decltype(&sd_event_unref) deleter = sd_event_unref;
41};
42
43/* @brief Alias 'event' to a unique_ptr type for auto-release. */
44using Event = std::unique_ptr<sd_event, EventDeleter>;
45
46} // namespace details
47
48/** @class Event
49 * @brief Provides C++ bindings to the sd_event_* class functions.
50 */
51class Event
52{
Brad Bishopd1eac882018-03-29 10:34:05 -040053 public:
54 /* Define all of the basic class operations:
55 * Not allowed:
56 * - Default constructor to avoid nullptrs.
57 * - Copy operations due to internal unique_ptr.
58 * Allowed:
59 * - Move operations.
60 * - Destructor.
61 */
62 Event() = delete;
63 Event(const Event&) = delete;
64 Event& operator=(const Event&) = delete;
65 Event(Event&&) = default;
66 Event& operator=(Event&&) = default;
67 ~Event() = default;
Brad Bishop605662d2017-05-30 12:39:09 -040068
Brad Bishopd1eac882018-03-29 10:34:05 -040069 /** @brief Conversion constructor from 'EventPtr'.
70 *
71 * Increments ref-count of the event-pointer and releases it when
72 * done.
73 */
74 explicit Event(EventPtr e);
Brad Bishop605662d2017-05-30 12:39:09 -040075
Brad Bishopd1eac882018-03-29 10:34:05 -040076 /** @brief Constructor for 'Event'.
77 *
78 * Takes ownership of the event-pointer and releases it when done.
79 */
80 Event(EventPtr e, std::false_type);
Brad Bishop605662d2017-05-30 12:39:09 -040081
Brad Bishopd1eac882018-03-29 10:34:05 -040082 /** @brief Release ownership of the stored event-pointer. */
83 EventPtr release()
84 {
85 return evt.release();
86 }
Brad Bishop605662d2017-05-30 12:39:09 -040087
Brad Bishopd1eac882018-03-29 10:34:05 -040088 /** @brief Wait indefinitely for new event sources. */
89 void loop()
90 {
91 sd_event_loop(evt.get());
92 }
Brad Bishop605662d2017-05-30 12:39:09 -040093
Brad Bishopd1eac882018-03-29 10:34:05 -040094 /** @brief Attach to a DBus loop. */
95 void attach(sdbusplus::bus::bus& bus)
96 {
97 bus.attach_event(evt.get(), SD_EVENT_PRIORITY_NORMAL);
98 }
Brad Bishop605662d2017-05-30 12:39:09 -040099
Brad Bishopd1eac882018-03-29 10:34:05 -0400100 /** @brief C++ wrapper for sd_event_now. */
101 auto now()
102 {
103 using namespace std::chrono;
Brad Bishop605662d2017-05-30 12:39:09 -0400104
Brad Bishopd1eac882018-03-29 10:34:05 -0400105 uint64_t usec;
106 sd_event_now(evt.get(), CLOCK_MONOTONIC, &usec);
107 microseconds d(usec);
108 return steady_clock::time_point(d);
109 }
Brad Bishop605662d2017-05-30 12:39:09 -0400110
Brad Bishopd1eac882018-03-29 10:34:05 -0400111 friend class timer::Timer;
Brad Bishop605662d2017-05-30 12:39:09 -0400112
Brad Bishopd1eac882018-03-29 10:34:05 -0400113 private:
114 EventPtr get()
115 {
116 return evt.get();
117 }
Brad Bishop605662d2017-05-30 12:39:09 -0400118
Brad Bishopd1eac882018-03-29 10:34:05 -0400119 details::Event evt;
Brad Bishop605662d2017-05-30 12:39:09 -0400120};
121
122inline Event::Event(EventPtr l) : evt(sd_event_ref(l))
123{
Brad Bishop605662d2017-05-30 12:39:09 -0400124}
125
126inline Event::Event(EventPtr l, std::false_type) : evt(l)
127{
Brad Bishop605662d2017-05-30 12:39:09 -0400128}
129
130inline Event newDefault()
131{
132 sd_event* e = nullptr;
133 sd_event_default(&e);
134 return Event(e, std::false_type());
135}
136
137} // namespace event
138} // namespace sdevent