#include "common.hh" #include "io.hh" #include "looper.hh" #include "signal_handler.hh" #include "unique_pipe.hh" #include #include namespace { std::unordered_map g_fds; int signum(SignalHandler::Signal signal) { switch (signal) { case SignalHandler::Signal::INT: return SIGINT; case SignalHandler::Signal::TERM: return SIGTERM; case SignalHandler::Signal::HUP: return SIGHUP; } assert(false); return 0; } void signal_handler(int signum) { auto it = g_fds.find(signum); if (it != g_fds.end()) { char c = 1; io::write(it->second, &c, 1); } } class SignalHandlerImpl : public SignalHandler { public: SignalHandlerImpl(std::shared_ptr looper, Signal signal, std::function callback) : looper_(looper), signal_(signum(signal)), callback_(std::move(callback)) { looper_->add(pipe_.reader(), Looper::EVENT_READ, std::bind(&SignalHandlerImpl::call, this, std::placeholders::_1)); g_fds[signal_] = pipe_.writer(); ::signal(signal_, signal_handler); } ~SignalHandlerImpl() { signal(signal_, SIG_DFL); looper_->remove(pipe_.reader()); g_fds.erase(signal_); } private: void call(uint8_t) { char buf[10]; io::read(pipe_.reader(), buf, 10); callback_(); } unique_pipe pipe_; std::shared_ptr looper_; int signal_; std::function callback_; }; } // namespace std::unique_ptr SignalHandler::create( std::shared_ptr looper, Signal signal, std::function callback) { return std::make_unique( std::move(looper), signal, std::move(callback)); }