libutil: add interruptible promise wrapping

the worker already wants to make a promise explicitly control-C-able,
and some other things in the future will want this as well. we do not
yet have the option to use the signal interfaces kj offers, but if we
can manage to remove all uses of the old-style notifiers we might get
there. until then we can at least wrap the old interfaces to be a bit
nicer to use, and eventually easier to replace with kj-provided code.

Change-Id: I079fdfe7720485820a9862c3615335d4e1df13e7
This commit is contained in:
eldritch horrors
2025-01-24 13:48:44 +00:00
parent d6a203b795
commit ca68979174
2 changed files with 15 additions and 8 deletions
+1 -8
View File
@@ -236,14 +236,7 @@ try {
running = true;
Finally const _stop([&] { running = false; });
auto onInterrupt = kj::newPromiseAndCrossThreadFulfiller<Result<Results>>();
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<LocalStore *>(&store); localStore && settings.minFree != 0u) {
+14
View File
@@ -20,7 +20,10 @@
#include "lix/libutil/error.hh"
#include "lix/libutil/result.hh"
#include <kj/async.h>
#include <memory>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
@@ -107,6 +110,17 @@ struct InterruptCallback
std::unique_ptr<InterruptCallback> createInterruptCallback(
std::function<void()> callback);
template<typename T>
kj::Promise<Result<T>> makeInterruptible(kj::Promise<Result<T>> p)
{
auto onInterrupt = kj::newPromiseAndCrossThreadFulfiller<Result<T>>();
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();
/**