From ae5d8dae1b796967c40b1f22b844d07f5697033e Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Tue, 24 Sep 2024 00:21:16 +0200 Subject: libstore: turn Goal::WaitForGoals into a promise also gets rid of explicit strong references to dependencies of any goal, and weak references to dependers as well. those are now only held within promises representing goal completion and thus independent of the goal's relation to each other. the weak references to dependers was only needed for notifications, and that's much better handled entirely by kj itself. Change-Id: I00d06df9090f8d6336ee4bb0c1313a7052fb016b --- src/libstore/build/worker.hh | 60 +++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 15 deletions(-) (limited to 'src/libstore/build/worker.hh') diff --git a/src/libstore/build/worker.hh b/src/libstore/build/worker.hh index 834ecfda3..925d289bf 100644 --- a/src/libstore/build/worker.hh +++ b/src/libstore/build/worker.hh @@ -28,10 +28,10 @@ struct HookInstance; class GoalFactory { public: - virtual std::shared_ptr makeDerivationGoal( + virtual std::pair, kj::Promise> makeDerivationGoal( const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal ) = 0; - virtual std::shared_ptr makeBasicDerivationGoal( + virtual std::pair, kj::Promise> makeBasicDerivationGoal( const StorePath & drvPath, const BasicDerivation & drv, const OutputsSpec & wantedOutputs, @@ -41,12 +41,14 @@ public: /** * @ref SubstitutionGoal "substitution goal" */ - virtual std::shared_ptr makePathSubstitutionGoal( + virtual std::pair, kj::Promise> + makePathSubstitutionGoal( const StorePath & storePath, RepairFlag repair = NoRepair, std::optional ca = std::nullopt ) = 0; - virtual std::shared_ptr makeDrvOutputSubstitutionGoal( + virtual std::pair, kj::Promise> + makeDrvOutputSubstitutionGoal( const DrvOutput & id, RepairFlag repair = NoRepair, std::optional ca = std::nullopt @@ -58,7 +60,8 @@ public: * It will be a `DerivationGoal` for a `DerivedPath::Built` or * a `SubstitutionGoal` for a `DerivedPath::Opaque`. */ - virtual GoalPtr makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) = 0; + virtual std::pair> + makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) = 0; }; // elaborate hoax to let goals access factory methods while hiding them from the public @@ -94,13 +97,27 @@ private: */ WeakGoals awake; + template + struct CachedGoal + { + std::weak_ptr goal; + kj::Own> promise; + kj::Own> fulfiller; + + CachedGoal() + { + auto pf = kj::newPromiseAndFulfiller(); + promise = kj::heap(pf.promise.fork()); + fulfiller = std::move(pf.fulfiller); + } + }; /** * Maps used to prevent multiple instantiations of a goal for the * same derivation / path. */ - std::map> derivationGoals; - std::map> substitutionGoals; - std::map> drvOutputSubstitutionGoals; + std::map> derivationGoals; + std::map> substitutionGoals; + std::map> drvOutputSubstitutionGoals; /** * Cache for pathContentsGood(). @@ -226,21 +243,31 @@ public: * @ref DerivationGoal "derivation goal" */ private: - std::shared_ptr makeDerivationGoalCommon( + std::pair, kj::Promise> makeDerivationGoalCommon( const StorePath & drvPath, const OutputsSpec & wantedOutputs, std::function()> mkDrvGoal); - std::shared_ptr makeDerivationGoal( + std::pair, kj::Promise> makeDerivationGoal( const StorePath & drvPath, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override; - std::shared_ptr makeBasicDerivationGoal( + std::pair, kj::Promise> makeBasicDerivationGoal( const StorePath & drvPath, const BasicDerivation & drv, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal) override; /** * @ref SubstitutionGoal "substitution goal" */ - std::shared_ptr makePathSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair, std::optional ca = std::nullopt) override; - std::shared_ptr makeDrvOutputSubstitutionGoal(const DrvOutput & id, RepairFlag repair = NoRepair, std::optional ca = std::nullopt) override; + std::pair, kj::Promise> + makePathSubstitutionGoal( + const StorePath & storePath, + RepairFlag repair = NoRepair, + std::optional ca = std::nullopt + ) override; + std::pair, kj::Promise> + makeDrvOutputSubstitutionGoal( + const DrvOutput & id, + RepairFlag repair = NoRepair, + std::optional ca = std::nullopt + ) override; /** * Make a goal corresponding to the `DerivedPath`. @@ -248,13 +275,16 @@ private: * It will be a `DerivationGoal` for a `DerivedPath::Built` or * a `SubstitutionGoal` for a `DerivedPath::Opaque`. */ - GoalPtr makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) override; + std::pair> + makeGoal(const DerivedPath & req, BuildMode buildMode = bmNormal) override; public: + using Targets = std::map>; + /** * Loop until the specified top-level goals have finished. */ - Goals run(std::function req); + std::vector run(std::function req); /*** * The exit status in case of failure. -- cgit v1.2.3