aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-08-14 11:55:58 +0200
committereldritch horrors <pennae@lix.systems>2024-08-19 09:13:44 +0000
commitfca523d66126ea1df7c3eda9ab1a2c9b7b1c7ba5 (patch)
treed50f79bbf56b23b0593c5c619085e69cd5900969 /src/libstore/build
parent5e9db0976158e6990c99fe3cb1b2ec0bd41d7d28 (diff)
libstore: turn HookReply into a variant type
we'll need this once we want to pass extra information out of accepting replies, such as fd sets or possibly even async output reader promises. Change-Id: I5e2f18cdb80b0d2faf3067703cc18bd263329b3f
Diffstat (limited to 'src/libstore/build')
-rw-r--r--src/libstore/build/derivation-goal.cc59
-rw-r--r--src/libstore/build/derivation-goal.hh14
2 files changed, 47 insertions, 26 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index b7f8005ae..a1f628afc 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -732,25 +732,34 @@ Goal::WorkResult DerivationGoal::tryToBuild(bool inBuildSlot)
&& settings.maxBuildJobs.get() != 0;
if (!buildLocally) {
- switch (tryBuildHook(inBuildSlot)) {
- case rpAccept:
- /* Yes, it has started doing so. Wait until we get
- EOF from the hook. */
- actLock.reset();
- buildResult.startTime = time(0); // inexact
- state = &DerivationGoal::buildDone;
- return started();
- case rpPostpone:
- /* Not now; wait until at least one child finishes or
- the wake-up timeout expires. */
- if (!actLock)
- actLock = std::make_unique<Activity>(*logger, lvlTalkative, actBuildWaiting,
- fmt("waiting for a machine to build '%s'", Magenta(worker.store.printStorePath(drvPath))));
- outputLocks.unlock();
- return WaitForAWhile{};
- case rpDecline:
- /* We should do it ourselves. */
- break;
+ auto hookReply = tryBuildHook(inBuildSlot);
+ auto result = std::visit(
+ overloaded{
+ [&](HookReply::Accept) -> std::optional<WorkResult> {
+ /* Yes, it has started doing so. Wait until we get
+ EOF from the hook. */
+ actLock.reset();
+ buildResult.startTime = time(0); // inexact
+ state = &DerivationGoal::buildDone;
+ return started();
+ },
+ [&](HookReply::Postpone) -> std::optional<WorkResult> {
+ /* Not now; wait until at least one child finishes or
+ the wake-up timeout expires. */
+ if (!actLock)
+ actLock = std::make_unique<Activity>(*logger, lvlTalkative, actBuildWaiting,
+ fmt("waiting for a machine to build '%s'", Magenta(worker.store.printStorePath(drvPath))));
+ outputLocks.unlock();
+ return WaitForAWhile{};
+ },
+ [&](HookReply::Decline) -> std::optional<WorkResult> {
+ /* We should do it ourselves. */
+ return std::nullopt;
+ },
+ },
+ hookReply);
+ if (result) {
+ return std::move(*result);
}
}
@@ -1113,7 +1122,7 @@ Goal::WorkResult DerivationGoal::resolvedFinished(bool inBuildSlot)
HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
{
- if (!worker.hook.available || !useDerivation) return rpDecline;
+ if (!worker.hook.available || !useDerivation) return HookReply::Decline{};
if (!worker.hook.instance)
worker.hook.instance = std::make_unique<HookInstance>();
@@ -1156,14 +1165,14 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
debug("hook reply is '%1%'", reply);
if (reply == "decline")
- return rpDecline;
+ return HookReply::Decline{};
else if (reply == "decline-permanently") {
worker.hook.available = false;
worker.hook.instance.reset();
- return rpDecline;
+ return HookReply::Decline{};
}
else if (reply == "postpone")
- return rpPostpone;
+ return HookReply::Postpone{};
else if (reply != "accept")
throw Error("bad hook reply '%s'", reply);
@@ -1173,7 +1182,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
"build hook died unexpectedly: %s",
chomp(drainFD(worker.hook.instance->fromHook.get())));
worker.hook.instance.reset();
- return rpDecline;
+ return HookReply::Decline{};
} else
throw;
}
@@ -1215,7 +1224,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
builderOutFD = &hook->builderOut;
worker.childStarted(shared_from_this(), fds, false);
- return rpAccept;
+ return HookReply::Accept{};
}
diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh
index da935ceb5..f7d86ed2e 100644
--- a/src/libstore/build/derivation-goal.hh
+++ b/src/libstore/build/derivation-goal.hh
@@ -14,7 +14,19 @@ using std::map;
struct HookInstance;
-typedef enum {rpAccept, rpDecline, rpPostpone} HookReply;
+struct HookReplyBase {
+ struct [[nodiscard]] Accept {};
+ struct [[nodiscard]] Decline {};
+ struct [[nodiscard]] Postpone {};
+};
+
+struct [[nodiscard]] HookReply
+ : HookReplyBase,
+ std::variant<HookReplyBase::Accept, HookReplyBase::Decline, HookReplyBase::Postpone>
+{
+ HookReply() = delete;
+ using variant::variant;
+};
/**
* Unless we are repairing, we don't both to test validity and just assume it,