blob: f511cf0852a0b71118e07d3a93b50826a5c8bab9 [file] [log] [blame]
Brad Bishope54a98f2017-06-14 23:10:37 -04001#pragma once
2
3#include <functional>
4#include <memory>
5#include <phosphor-logging/elog.hpp>
6#include <phosphor-logging/elog-errors.hpp>
7#include <systemd/sd-event.h>
8#include <xyz/openbmc_project/Common/error.hpp>
9
10#include "sdevent/source.hpp"
11#include "sdevent/event.hpp"
12
13namespace sdevent
14{
15namespace event
16{
17namespace io
18{
19
Marri Devender Rao60885582017-11-07 04:58:14 -060020using namespace phosphor::logging;
Brad Bishope54a98f2017-06-14 23:10:37 -040021/** @class IO
22 * @brief Provides C++ bindings to the sd_event_source* io functions.
23 */
24class IO
25{
26 private:
27 using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
28 Error::InternalFailure;
29
30 public:
31 /* Define all of the basic class operations:
32 * Not allowed:
33 * - Default constructor to avoid nullptrs.
34 * - Copy operations due to internal unique_ptr.
35 * Allowed:
36 * - Move operations.
37 * - Destructor.
38 */
39 IO() = delete;
40 IO(const IO&) = delete;
41 IO& operator=(const IO&) = delete;
42 IO(IO&&) = default;
43 IO& operator=(IO&&) = default;
44 ~IO() = default;
45
46 using Callback = std::function<void(source::Source&)>;
47
48 /** @brief Register an io callback.
49 *
50 * @param[in] event - The event to register on.
51 * @param[in] fd - The file descriptor to poll.
52 * @param[in] callback - The callback method.
53 */
54 IO(
55 sdevent::event::Event& event,
56 int fd,
57 Callback callback)
58 : src(nullptr),
59 cb(std::make_unique<Callback>(std::move(callback)))
60 {
61 sd_event_source* source = nullptr;
62 auto rc = sd_event_add_io(
63 event.get(),
64 &source,
65 fd,
66 EPOLLIN,
67 callCallback,
68 cb.get());
69 if (rc < 0)
70 {
Marri Devender Rao60885582017-11-07 04:58:14 -060071 log<level::ERR>("Error in call to sd_event_add_io",
72 entry("RC=%d", rc),
73 entry("FD=%d", fd));
74 elog<InternalFailure>();
Brad Bishope54a98f2017-06-14 23:10:37 -040075 }
76
77 src = decltype(src){source, std::false_type()};
78 }
79
80 /** @brief Set the IO source enable state. */
81 void enable(int enable)
82 {
83 src.enable(enable);
84 }
85
86 /** @brief Query the IO enable state. */
87 auto enabled()
88 {
89 return src.enabled();
90 }
91
92 private:
93 source::Source src;
94 std::unique_ptr<Callback> cb = nullptr;
95
96 static int callCallback(sd_event_source* s, int fd, uint32_t events,
97 void* context)
98 {
99 source::Source source(s);
100 auto c = static_cast<Callback*>(context);
101 (*c)(source);
102
103 return 0;
104 }
105};
106} // namespace io
107} // namespace event
108} // namespace sdevent