blob: 6b20c296d0203d8dd230c59706d24fbf5fa22d96 [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>
Brad Bishop605662d2017-05-30 12:39:09 -04007
8// TODO: openbmc/openbmc#1720 - add error handling for sd_event API failures
9
10namespace sdevent
11{
12namespace source
13{
14
15using SourcePtr = sd_event_source*;
16
17namespace details
18{
19
20/** @brief unique_ptr functor to release a source reference. */
21struct SourceDeleter
22{
23 void operator()(sd_event_source* ptr) const
24 {
25 deleter(ptr);
26 }
27
28 decltype(&sd_event_source_unref) deleter = sd_event_source_unref;
29};
30
31/* @brief Alias 'source' to a unique_ptr type for auto-release. */
32using source = std::unique_ptr<sd_event_source, SourceDeleter>;
33
34} // namespace details
35
36/** @class Source
37 * @brief Provides C++ bindings to the sd_event_source* functions.
38 */
39class Source
40{
Brad Bishopd1eac882018-03-29 10:34:05 -040041 public:
42 /* Define all of the basic class operations:
43 * Not allowed:
44 * - Default constructor to avoid nullptrs.
45 * - Copy operations due to internal unique_ptr.
46 * Allowed:
47 * - Move operations.
48 * - Destructor.
49 */
50 Source() = delete;
51 Source(const Source&) = delete;
52 Source& operator=(const Source&) = delete;
53 Source(Source&&) = default;
54 Source& operator=(Source&&) = default;
55 ~Source() = default;
Brad Bishop605662d2017-05-30 12:39:09 -040056
Brad Bishopd1eac882018-03-29 10:34:05 -040057 /** @brief Conversion constructor from 'SourcePtr'.
58 *
59 * Increments ref-count of the source-pointer and releases it
60 * when done.
61 */
62 explicit Source(SourcePtr s) : src(sd_event_source_ref(s))
63 {
64 }
Brad Bishop605662d2017-05-30 12:39:09 -040065
Brad Bishopd1eac882018-03-29 10:34:05 -040066 /** @brief Constructor for 'source'.
67 *
68 * Takes ownership of the source-pointer and releases it when done.
69 */
70 Source(SourcePtr s, std::false_type) : src(s)
71 {
72 }
Brad Bishop605662d2017-05-30 12:39:09 -040073
Brad Bishopd1eac882018-03-29 10:34:05 -040074 /** @brief Check if source contains a real pointer. (non-nullptr). */
75 explicit operator bool() const
76 {
77 return bool(src);
78 }
Brad Bishop605662d2017-05-30 12:39:09 -040079
Brad Bishopd1eac882018-03-29 10:34:05 -040080 /** @brief Test whether or not the source can generate events. */
81 auto enabled()
82 {
83 int enabled;
84 sd_event_source_get_enabled(src.get(), &enabled);
85 return enabled;
86 }
Brad Bishop605662d2017-05-30 12:39:09 -040087
Brad Bishopd1eac882018-03-29 10:34:05 -040088 /** @brief Allow the source to generate events. */
89 void enable(int enable)
90 {
91 sd_event_source_set_enabled(src.get(), enable);
92 }
Brad Bishop605662d2017-05-30 12:39:09 -040093
Brad Bishopd1eac882018-03-29 10:34:05 -040094 /** @brief Set the expiration on a timer source. */
95 void setTime(const std::chrono::steady_clock::time_point& expires)
96 {
97 using namespace std::chrono;
98 auto epoch = expires.time_since_epoch();
99 auto time = duration_cast<microseconds>(epoch);
100 sd_event_source_set_time(src.get(), time.count());
101 }
Brad Bishop605662d2017-05-30 12:39:09 -0400102
Brad Bishopd1eac882018-03-29 10:34:05 -0400103 /** @brief Get the expiration on a timer source. */
104 auto getTime()
105 {
106 using namespace std::chrono;
107 uint64_t usec;
108 sd_event_source_get_time(src.get(), &usec);
109 microseconds d(usec);
110 return steady_clock::time_point(d);
111 }
Brad Bishop605662d2017-05-30 12:39:09 -0400112
Brad Bishopd1eac882018-03-29 10:34:05 -0400113 private:
114 details::source src;
Brad Bishop605662d2017-05-30 12:39:09 -0400115};
116} // namespace source
117} // namespace sdevent