mirror of
https://github.com/NixOS/nix
synced 2025-07-01 00:07:58 +02:00
Fix interrupt handling
This commit is contained in:
parent
951357e5fb
commit
83ae6503e8
4 changed files with 41 additions and 13 deletions
|
@ -27,8 +27,7 @@ public:
|
|||
fds[0].events = 0;
|
||||
if (poll(fds, 1, -1) == -1) abort(); // can't happen
|
||||
assert(fds[0].revents & POLLHUP);
|
||||
/* We got POLLHUP, so send an INT signal to the main thread. */
|
||||
kill(getpid(), SIGINT);
|
||||
triggerInterrupt();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1197,18 +1197,22 @@ static void signalHandlerThread(sigset_t set)
|
|||
int signal = 0;
|
||||
sigwait(&set, &signal);
|
||||
|
||||
if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP) {
|
||||
_isInterrupted = 1;
|
||||
if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP)
|
||||
triggerInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto interruptCallbacks(_interruptCallbacks.lock());
|
||||
for (auto & callback : *interruptCallbacks) {
|
||||
try {
|
||||
callback();
|
||||
} catch (...) {
|
||||
ignoreException();
|
||||
}
|
||||
}
|
||||
void triggerInterrupt()
|
||||
{
|
||||
_isInterrupted = 1;
|
||||
|
||||
{
|
||||
auto interruptCallbacks(_interruptCallbacks.lock());
|
||||
for (auto & callback : *interruptCallbacks) {
|
||||
try {
|
||||
callback();
|
||||
} catch (...) {
|
||||
ignoreException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -433,5 +433,21 @@ struct InterruptCallback
|
|||
std::unique_ptr<InterruptCallback> createInterruptCallback(
|
||||
std::function<void()> callback);
|
||||
|
||||
void triggerInterrupt();
|
||||
|
||||
/* A RAII class that causes the current thread to receive SIGUSR1 when
|
||||
the signal handler thread receives SIGINT. That is, this allows
|
||||
SIGINT to be multiplexed to multiple threads. */
|
||||
struct ReceiveInterrupts
|
||||
{
|
||||
pthread_t target;
|
||||
std::unique_ptr<InterruptCallback> callback;
|
||||
|
||||
ReceiveInterrupts()
|
||||
: target(pthread_self())
|
||||
, callback(createInterruptCallback([&]() { pthread_kill(target, SIGUSR1); }))
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue