xref: /openbmc/sdeventplus/src/sdeventplus/source/io.hpp (revision a8c11e3ca342b090aec615c832b85686bd4655f6)
1 #pragma once
2 
3 #include <systemd/sd-event.h>
4 
5 #include <function2/function2.hpp>
6 #include <sdeventplus/source/base.hpp>
7 
8 #include <cstdint>
9 #include <type_traits>
10 
11 namespace sdeventplus
12 {
13 namespace source
14 {
15 
16 namespace detail
17 {
18 class IOData;
19 } // namespace detail
20 
21 /** @class IO
22  *  @brief A wrapper around the sd_event_source IO type
23  *         See sd_event_add_io(3) for more information
24  */
25 class IO : public Base
26 {
27   public:
28     using Callback = fu2::unique_function<void(IO&, int fd, uint32_t revents)>;
29 
30     /** @brief Adds a new IO source handler to the Event
31      *         This type of source defaults to Enabled::On, executing the
32      *         callback for each IO epoll event observed.
33      *
34      *  @param[in] event    - The event to attach the handler
35      *  @param[in] fd       - The file descriptor producing the events
36      *  @param[in] events   - The event mask passed which determines triggers
37      *                        See epoll_ctl(2) for more info on the mask
38      *  @param[in] callback - The function executed on event dispatch
39      */
40     IO(const Event& event, int fd, uint32_t events, Callback&& callback);
41 
42     /** @brief Constructs a non-owning io source handler
43      *         Does not own the passed reference to the source because
44      *         this is meant to be used only as a reference inside an event
45      *         source.
46      *  @internal
47      *
48      *  @param[in] other - The source wrapper to copy
49      *  @param[in]       - Signifies that this new copy is non-owning
50      */
51     IO(const IO& event, sdeventplus::internal::NoOwn);
52 
53     /** @brief Sets the callback
54      *
55      *  @param[in] callback - The function executed on event dispatch
56      */
57     void set_callback(Callback&& callback);
58 
59     /** @brief Gets the file descriptor tied to the source
60      *
61      *  @throws SdEventError for underlying sd_event errors
62      *  @return The watched file descriptor
63      */
64     int get_fd() const;
65 
66     /** @brief Sets the file descriptor the source watches
67      *
68      *  @param[in] fd - The file descriptor to watch
69      *  @throws SdEventError for underlying sd_event errors
70      */
71     void set_fd(int fd) const;
72 
73     /** @brief Gets the events mask used to determine what
74      *         events trigger the callback action
75      *
76      *  @throws SdEventError for underlying sd_event errors
77      *  @return The events mask
78      */
79     uint32_t get_events() const;
80 
81     /** @brief Sets the events mask used to determine what events
82      *         trigger the callback handler
83      *
84      *  @param[in] events - The events mask
85      *  @throws SdEventError for underlying sd_event errors
86      */
87     void set_events(uint32_t events) const;
88 
89     /** @brief Gets the events mask describing the events
90      *         seen in the most recent callback
91      *
92      *  @throws SdEventError for underlying sd_event errors
93      *  @return The events mask
94      */
95     uint32_t get_revents() const;
96 
97   private:
98     /** @brief Returns a reference to the source owned io
99      *
100      *  @return A reference to the io
101      */
102     detail::IOData& get_userdata() const;
103 
104     /** @brief Returns a reference to the callback executed for this source
105      *
106      *  @return A reference to the callback
107      */
108     Callback& get_callback();
109 
110     /** @brief Creates a new IO source attached to the Event
111      *
112      *  @param[in] event  - The event to attach the handler
113      *  @param[in] fd     - The file descriptor producing the events
114      *  @param[in] events - The event mask passed which determines triggers
115      *                      See epoll_ctl(2) for more info on the mask
116      *  @throws SdEventError for underlying sd_event errors
117      *  @return A new sd_event_source
118      */
119     static sd_event_source* create_source(const Event& event, int fd,
120                                           uint32_t events);
121 
122     /** @brief A wrapper around the callback that can be called from sd-event
123      *
124      *  @param[in] source   - The sd_event_source associated with the call
125      *  @param[in] userdata - The provided userdata for the source
126      *  @return 0 on success or a negative errno otherwise
127      */
128     static int ioCallback(sd_event_source* source, int fd, uint32_t revents,
129                           void* userdata);
130 };
131 
132 namespace detail
133 {
134 
135 class IOData : public IO, public BaseData
136 {
137   private:
138     IO::Callback callback;
139 
140   public:
141     IOData(const IO& base, IO::Callback&& callback);
142 
143     friend IO;
144 };
145 
146 } // namespace detail
147 
148 } // namespace source
149 } // namespace sdeventplus
150