23 #include <sys/eventfd.h>
24 #include <sys/signalfd.h>
34 ::pthread_sigmask(SIG_BLOCK, new_mask, old_mask);
39 ::sigprocmask(SIG_BLOCK, new_mask, old_mask);
57 SignalTrap(
Scope scope, std::initializer_list<core::posix::Signal> blocked_signals)
59 state(
State::not_running),
60 event_fd(::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK))
63 throw std::system_error(errno, std::system_category());
65 ::sigemptyset(&blocked_signals_mask);
67 for(
auto signal : blocked_signals)
68 ::sigaddset(&blocked_signals_mask,
static_cast<int>(signal));
98 return ::sigismember(&blocked_signals_mask,
static_cast<int>(signal));
103 static constexpr
int signal_fd_idx = 0;
104 static constexpr
int event_fd_idx = 1;
106 static constexpr
int signal_info_buffer_size = 5;
109 throw std::runtime_error(
"SignalTrap::run can only be run once.");
124 } scope{::signalfd(-1, &blocked_signals_mask, SFD_CLOEXEC | SFD_NONBLOCK)};
126 if (scope.signal_fd == -1)
127 throw std::system_error(errno, std::system_category());
130 signalfd_siginfo signal_info[signal_info_buffer_size];
134 fds[signal_fd_idx] = {scope.signal_fd, POLLIN, 0};
135 fds[event_fd_idx] = {event_fd, POLLIN, 0};
137 auto rc = ::poll(fds, 2, -1);
150 if (fds[signal_fd_idx].revents & POLLIN)
152 auto result = ::read(scope.signal_fd, signal_info,
sizeof(signal_info));
154 for (uint i = 0; i < result /
sizeof(signalfd_siginfo); i++)
160 signal_info[i].ssi_signo));
165 if (fds[event_fd_idx].revents & POLLIN)
167 std::int64_t value{1};
170 auto result = ::read(event_fd, &value,
sizeof(value));
182 static const std::int64_t value = {1};
183 if (
sizeof(value) != ::write(event_fd, &value,
sizeof(value)))
184 throw std::system_error(errno, std::system_category());
189 return on_signal_raised;
194 std::atomic<State> state;
196 core::Signal<core::posix::Signal> on_signal_raised;
197 ::sigset_t old_signals_mask;
198 ::sigset_t blocked_signals_mask;
203 std::initializer_list<core::posix::Signal> blocked_signals)
205 return std::make_shared<impl::SignalTrap>(
211 std::initializer_list<core::posix::Signal> blocked_signals)
213 return std::make_shared<impl::SignalTrap>(