diff --git a/lix/libutil/signals.cc b/lix/libutil/signals.cc index aca599a67..33cc4a8ed 100644 --- a/lix/libutil/signals.cc +++ b/lix/libutil/signals.cc @@ -1,9 +1,14 @@ #include "lix/libutil/signals.hh" +#include "async.hh" #include "lix/libutil/error.hh" #include "lix/libutil/sync.hh" #include "lix/libutil/terminal.hh" #include "lix/libutil/thread-name.hh" +#include +#include +#include +#include #include #include #include @@ -49,12 +54,27 @@ struct InterruptCallbacks { static Sync>> _interruptCallbacks; -static void signalHandlerThread(sigset_t set) +static void signalHandlerThread(const std::vector set) { setCurrentThreadName("signal handler"); + + AsyncIoRoot aio; + + for (auto sig : set) { + AIO().unixEventPort.captureSignal(sig); + } + + auto onSignal = [&] { + kj::Promise promise(kj::NEVER_DONE); + for (auto sig : set) { + promise = promise.exclusiveJoin(AIO().unixEventPort.onSignal(sig)); + } + return promise; + }; + while (true) { - int signal = 0; - sigwait(&set, &signal); + auto info = onSignal().wait(aio.kj.waitScope); + int signal = info.si_signo; if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP) triggerInterrupt(); @@ -127,17 +147,17 @@ void startSignalHandlerThread() updateWindowSize(); saveSignalMask(); + std::vector signals{SIGINT, SIGTERM, SIGHUP, SIGPIPE, SIGWINCH}; + sigset_t set; sigemptyset(&set); - sigaddset(&set, SIGINT); - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGHUP); - sigaddset(&set, SIGPIPE); - sigaddset(&set, SIGWINCH); + for (auto sig : signals) { + sigaddset(&set, sig); + } if (pthread_sigmask(SIG_BLOCK, &set, nullptr)) throw SysError("blocking signals"); - std::thread(signalHandlerThread, set).detach(); + std::thread(signalHandlerThread, signals).detach(); } void restoreSignals()