From 6c416ff2ca955e3a5a5fbcc2e11c1c01c3ed76f3 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sat, 18 Oct 2025 19:43:44 +0200 Subject: [PATCH] libstore: make build hook exit status reusable this makes it possible to wait for the hook to exit in one place, process its exit status for some purpose, and later process it in another place for a different purpose. rpc will need this to shut down a hook cleanly after the hook has completed its assignments. Change-Id: I5af2d5aac4b02a0a200d720d0e6f0b5df5496aaf --- lix/libstore/build/derivation-goal.cc | 2 +- lix/libstore/build/hook-instance.cc | 2 +- lix/libstore/build/hook-instance.hh | 39 ++++++++++++++++++++++----- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/lix/libstore/build/derivation-goal.cc b/lix/libstore/build/derivation-goal.cc index 78d7f67dc..0cad92073 100644 --- a/lix/libstore/build/derivation-goal.cc +++ b/lix/libstore/build/derivation-goal.cc @@ -792,7 +792,7 @@ void replaceValidPath(const Path & storePath, const Path & tmpPath) int DerivationGoal::getChildStatus() { - return hook->pid.kill(); + return hook->kill(); } void DerivationGoal::closeReadPipes() diff --git a/lix/libstore/build/hook-instance.cc b/lix/libstore/build/hook-instance.cc index 06551d753..0f76d61fc 100644 --- a/lix/libstore/build/hook-instance.cc +++ b/lix/libstore/build/hook-instance.cc @@ -88,7 +88,7 @@ try { HookInstance::~HookInstance() { try { - if (pid) pid.kill(); + kill(); } catch (...) { ignoreExceptionInDestructor(); } diff --git a/lix/libstore/build/hook-instance.hh b/lix/libstore/build/hook-instance.hh index fabc99b39..7d55d0a20 100644 --- a/lix/libstore/build/hook-instance.hh +++ b/lix/libstore/build/hook-instance.hh @@ -23,11 +23,6 @@ struct HookInstance std::unique_ptr client; rpc::build_remote::HookInstance::Client rpc; - /** - * The process ID of the hook. - */ - Pid pid; - std::map activities; static kj::Promise>> create(); @@ -43,9 +38,41 @@ struct HookInstance , conn(std::move(conn)) , client(std::move(client)) , rpc(std::move(rpc)) - , pid(std::move(pid)) + , pidOrStatus(std::move(pid)) { } ~HookInstance(); + + int wait() + { + return childStatusOr<&Pid::wait>(); + } + + int kill() + { + return childStatusOr<&Pid::kill>(); + } + +private: + /** + * The process ID of the hook if it's running, or its exit status if not. + */ + std::variant pidOrStatus; + + template + int childStatusOr() + { + return std::visit( + overloaded{ + [&](Pid & pid) { + int status = (pid.*fn)(); + pidOrStatus = status; + return status; + }, + [](int status) { return status; }, + }, + pidOrStatus + ); + } }; }