diff --git a/lix/libstore/build/worker.cc b/lix/libstore/build/worker.cc index ae23463b3..2c1ac9c0c 100644 --- a/lix/libstore/build/worker.cc +++ b/lix/libstore/build/worker.cc @@ -236,14 +236,7 @@ try { running = true; Finally const _stop([&] { running = false; }); - auto onInterrupt = kj::newPromiseAndCrossThreadFulfiller>(); - auto interruptCallback = createInterruptCallback([&] { - onInterrupt.fulfiller->fulfill(result::failure(std::make_exception_ptr(makeInterrupted()))); - }); - - auto promise = runImpl(std::move(topGoals)) - .exclusiveJoin(updateStatistics()) - .exclusiveJoin(std::move(onInterrupt.promise)); + auto promise = makeInterruptible(runImpl(std::move(topGoals))).exclusiveJoin(updateStatistics()); // TODO GC interface? if (auto localStore = dynamic_cast(&store); localStore && settings.minFree != 0u) { diff --git a/lix/libutil/signals.hh b/lix/libutil/signals.hh index 75a5b3caf..12d8ced62 100644 --- a/lix/libutil/signals.hh +++ b/lix/libutil/signals.hh @@ -20,7 +20,10 @@ #include "lix/libutil/error.hh" +#include "lix/libutil/result.hh" +#include +#include #include #include #include @@ -107,6 +110,17 @@ struct InterruptCallback std::unique_ptr createInterruptCallback( std::function callback); +template +kj::Promise> makeInterruptible(kj::Promise> p) +{ + auto onInterrupt = kj::newPromiseAndCrossThreadFulfiller>(); + auto interruptCallback = createInterruptCallback([fulfiller{onInterrupt.fulfiller.get()}] { + fulfiller->fulfill(result::failure(std::make_exception_ptr(makeInterrupted()))); + }); + return p.attach(std::move(onInterrupt.fulfiller), std::move(interruptCallback)) + .exclusiveJoin(std::move(onInterrupt.promise)); +} + void triggerInterrupt(); /**