blob: ac9a13d70c5f9839bad20745d8bd7e51c1399f67 [file] [log] [blame]
Brad Bishop14631dc2017-06-14 22:34:03 -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{
14
15using EventPtr = sd_event*;
16class Event;
17
18/** @brief Get an instance of the 'default' event. */
19Event newDefault();
20
21namespace details
22{
23
24/** @brief unique_ptr functor to release an event reference. */
25struct EventDeleter
26{
27 void operator()(sd_event* ptr) const
28 {
29 deleter(ptr);
30 }
31
32 decltype(&sd_event_unref) deleter = sd_event_unref;
33};
34
35/* @brief Alias 'event' to a unique_ptr type for auto-release. */
36using Event = std::unique_ptr<sd_event, EventDeleter>;
37
38} // namespace details
39
40/** @class Event
41 * @brief Provides C++ bindings to the sd_event_* class functions.
42 */
43class Event
44{
45 public:
46 /* Define all of the basic class operations:
47 * Not allowed:
48 * - Default constructor to avoid nullptrs.
49 * - Copy operations due to internal unique_ptr.
50 * Allowed:
51 * - Move operations.
52 * - Destructor.
53 */
54 Event() = delete;
55 Event(const Event&) = delete;
56 Event& operator=(const Event&) = delete;
57 Event(Event&&) = default;
58 Event& operator=(Event&&) = default;
59 ~Event() = default;
60
61 /** @brief Conversion constructor from 'EventPtr'.
62 *
63 * Increments ref-count of the event-pointer and releases it when
64 * done.
65 */
66 explicit Event(EventPtr e);
67
68 /** @brief Constructor for 'Event'.
69 *
70 * Takes ownership of the event-pointer and releases it when done.
71 */
72 Event(EventPtr e, std::false_type);
73
74 /** @brief Release ownership of the stored event-pointer. */
75 EventPtr release()
76 {
77 return evt.release();
78 }
79
80 /** @brief Wait indefinitely for new event sources. */
81 void loop()
82 {
83 sd_event_loop(evt.get());
84 }
85
86 /** @brief Attach to a DBus loop. */
87 void attach(sdbusplus::bus::bus& bus)
88 {
89 bus.attach_event(evt.get(), SD_EVENT_PRIORITY_NORMAL);
90 }
91
92 /** @brief C++ wrapper for sd_event_now. */
93 auto now()
94 {
95 using namespace std::chrono;
96
97 uint64_t usec;
98 sd_event_now(evt.get(), CLOCK_MONOTONIC, &usec);
99 microseconds d(usec);
100 return steady_clock::time_point(d);
101 }
102
103 private:
104
105 EventPtr get()
106 {
107 return evt.get();
108 }
109
110 details::Event evt;
111};
112
113inline Event::Event(EventPtr l) : evt(sd_event_ref(l))
114{
115
116}
117
118inline Event::Event(EventPtr l, std::false_type) : evt(l)
119{
120
121}
122
123inline Event newDefault()
124{
125 sd_event* e = nullptr;
126 sd_event_default(&e);
127 return Event(e, std::false_type());
128}
129
130} // namespace event
131} // namespace sdevent