1 #pragma once 2 3 #include <sys/signalfd.h> 4 5 #include <function2/function2.hpp> 6 #include <sdeventplus/event.hpp> 7 #include <sdeventplus/source/base.hpp> 8 #include <sdeventplus/types.hpp> 9 10 namespace sdeventplus 11 { 12 namespace source 13 { 14 15 namespace detail 16 { 17 class SignalData; 18 } // namespace detail 19 20 /** @class Signal 21 * @brief A wrapper around the sd_event_source signal type 22 * See sd_event_add_signal(3) for more information 23 */ 24 class Signal : public Base 25 { 26 public: 27 /** @brief Type of the user provided callback function */ 28 using Callback = fu2::unique_function<void( 29 Signal& source, const struct signalfd_siginfo* si)>; 30 31 /** @brief Creates a new signal event source on the provided event loop 32 * This type of source defaults to Enabled::On, executing the 33 * callback for each signal observed. You are required to block 34 * the signal in all threads prior to creating this source. 35 * 36 * @param[in] event - The event to attach the handler 37 * @param[in] sig - Signum to watch, see signal(7) 38 * @param[in] callback - The function executed on event dispatch 39 * @throws SdEventError for underlying sd_event errors 40 */ 41 Signal(const Event& event, int sig, Callback&& callback); 42 43 /** @brief Constructs a non-owning signal source handler 44 * Does not own the passed reference to the source because 45 * this is meant to be used only as a reference inside an event 46 * source. 47 * @internal 48 * 49 * @param[in] other - The source wrapper to copy 50 * @param[in] - Signifies that this new copy is non-owning 51 * @throws SdEventError for underlying sd_event errors 52 */ 53 Signal(const Signal& other, sdeventplus::internal::NoOwn); 54 55 /** @brief Sets the callback 56 * 57 * @param[in] callback - The function executed on event dispatch 58 */ 59 void set_callback(Callback&& callback); 60 61 /** @brief Gets the signum watched by the source 62 * 63 * @throws SdEventError for underlying sd_event errors 64 * @return Integer signum 65 */ 66 int get_signal() const; 67 68 private: 69 /** @brief Returns a reference to the source owned signal 70 * 71 * @return A reference to the signal 72 */ 73 detail::SignalData& get_userdata() const; 74 75 /** @brief Returns a reference to the callback executed for this source 76 * 77 * @return A reference to the callback 78 */ 79 Callback& get_callback(); 80 81 /** @brief Creates a new signal source attached to the Event 82 * 83 * @param[in] event - The event to attach the handler 84 * @param[in] sig - Signum to watch, see signal(7) 85 * @param[in] callback - The function executed on event dispatch 86 * @throws SdEventError for underlying sd_event errors 87 * @return A new sd_event_source 88 */ 89 static sd_event_source* create_source(const Event& event, int sig); 90 91 /** @brief A wrapper around the callback that can be called from sd-event 92 * 93 * @param[in] source - The sd_event_source associated with the call 94 * @param[in] userdata - The provided userdata for the source 95 * @return 0 on success or a negative errno otherwise 96 */ 97 static int signalCallback(sd_event_source* source, 98 const struct signalfd_siginfo* si, 99 void* userdata); 100 }; 101 102 namespace detail 103 { 104 105 class SignalData : public Signal, public BaseData 106 { 107 private: 108 Signal::Callback callback; 109 110 public: 111 SignalData(const Signal& base, Signal::Callback&& callback); 112 113 friend Signal; 114 }; 115 116 } // namespace detail 117 118 } // namespace source 119 } // namespace sdeventplus 120