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