aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/local-derivation-goal.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build/local-derivation-goal.cc')
-rw-r--r--src/libstore/build/local-derivation-goal.cc35
1 files changed, 20 insertions, 15 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index a32f742f4..f3d0bc8b4 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -147,20 +147,18 @@ void LocalDerivationGoal::killSandbox(bool getStats)
}
-kj::Promise<Result<Goal::WorkResult>> LocalDerivationGoal::tryLocalBuild(bool inBuildSlot) noexcept
+kj::Promise<Result<Goal::WorkResult>> LocalDerivationGoal::tryLocalBuild() noexcept
try {
+retry:
#if __APPLE__
additionalSandboxProfile = parsedDrv->getStringAttr("__sandboxProfile").value_or("");
#endif
- if (!inBuildSlot) {
- state = &DerivationGoal::tryToBuild;
+ if (!slotToken.valid()) {
outputLocks.unlock();
if (worker.localBuilds.capacity() > 0) {
- return worker.localBuilds.acquire().then([this](auto token) {
- slotToken = std::move(token);
- return work();
- });
+ slotToken = co_await worker.localBuilds.acquire();
+ co_return co_await tryToBuild();
}
if (getMachines().empty()) {
throw Error(
@@ -215,7 +213,9 @@ try {
if (!actLock)
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
fmt("waiting for a free build user ID for '%s'", Magenta(worker.store.printStorePath(drvPath))));
- return waitForAWhile();
+ (co_await waitForAWhile()).value();
+ // we can loop very often, and `co_return co_await` always allocates a new frame
+ goto retry;
}
}
@@ -246,22 +246,27 @@ try {
/* Okay, we have to build. */
auto promise = startBuilder();
- /* This state will be reached when we get EOF on the child's
- log pipe. */
- state = &DerivationGoal::buildDone;
-
started();
- return continueOrError(std::move(promise));
+ auto r = co_await promise;
+ if (r.has_value()) {
+ // all good so far
+ } else if (r.has_error()) {
+ co_return r.assume_error();
+ } else {
+ co_return r.assume_exception();
+ }
} catch (BuildError & e) {
outputLocks.unlock();
buildUser.reset();
auto report = done(BuildResult::InputRejected, {}, std::move(e));
report.permanentFailure = true;
- return {std::move(report)};
+ co_return report;
}
+
+ co_return co_await buildDone();
} catch (...) {
- return {std::current_exception()};
+ co_return result::failure(std::current_exception());
}