aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/build/worker.cc11
-rw-r--r--src/libutil/signals.cc7
-rw-r--r--src/libutil/signals.hh3
3 files changed, 16 insertions, 5 deletions
diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc
index 0ca805b4d..0e8694a6d 100644
--- a/src/libstore/build/worker.cc
+++ b/src/libstore/build/worker.cc
@@ -294,7 +294,13 @@ std::vector<GoalPtr> Worker::run(std::function<Targets (GoalFactory &)> req)
topGoals.insert(goal);
}
- auto promise = runImpl().exclusiveJoin(updateStatistics());
+ auto onInterrupt = kj::newPromiseAndCrossThreadFulfiller<Result<void>>();
+ auto interruptCallback = createInterruptCallback([&] {
+ return result::failure(std::make_exception_ptr(makeInterrupted()));
+ });
+
+ auto promise =
+ runImpl().exclusiveJoin(updateStatistics()).exclusiveJoin(std::move(onInterrupt.promise));
// TODO GC interface?
if (auto localStore = dynamic_cast<LocalStore *>(&store); localStore && settings.minFree != 0) {
@@ -316,9 +322,6 @@ try {
debug("entered goal loop");
while (1) {
-
- checkInterrupt();
-
if (topGoals.empty()) break;
/* Wait for input. */
diff --git a/src/libutil/signals.cc b/src/libutil/signals.cc
index 4e9ed0ba1..dac2964ae 100644
--- a/src/libutil/signals.cc
+++ b/src/libutil/signals.cc
@@ -12,13 +12,18 @@ std::atomic<bool> _isInterrupted = false;
thread_local std::function<bool()> interruptCheck;
+Interrupted makeInterrupted()
+{
+ return Interrupted("interrupted by the user");
+}
+
void _interrupted()
{
/* Block user interrupts while an exception is being handled.
Throwing an exception while another exception is being handled
kills the program! */
if (!std::uncaught_exceptions()) {
- throw Interrupted("interrupted by the user");
+ throw makeInterrupted();
}
}
diff --git a/src/libutil/signals.hh b/src/libutil/signals.hh
index 02f8d2ca3..538ff94b4 100644
--- a/src/libutil/signals.hh
+++ b/src/libutil/signals.hh
@@ -16,10 +16,13 @@ namespace nix {
/* User interruption. */
+class Interrupted;
+
extern std::atomic<bool> _isInterrupted;
extern thread_local std::function<bool()> interruptCheck;
+Interrupted makeInterrupted();
void _interrupted();
void inline checkInterrupt()