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