aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/worker.hh
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-09-01 01:37:10 +0200
committereldritch horrors <pennae@lix.systems>2024-09-27 16:38:16 +0200
commit0478949c72310b9749d5b959adad8bdf5c2c0841 (patch)
treed3a12528ee1e2632b4c9457a42d82315e5e6e25d /src/libstore/build/worker.hh
parent14dc84ed03f1b7e5a41bb6fdce00916faab32b60 (diff)
libstore: turn builder output processing into event loop
this removes the rather janky did-you-mean-async poll loop we had so far. sadly kj does not play well with pty file descriptors, so we do have to add our own async input stream that does not eat pty EIO and turns it into an exception. that's still a *lot* better than the old code, and using a real even loop makes everything else easier later. Change-Id: Idd7e0428c59758602cc530bcad224cd2fed4c15e
Diffstat (limited to 'src/libstore/build/worker.hh')
-rw-r--r--src/libstore/build/worker.hh42
1 files changed, 13 insertions, 29 deletions
diff --git a/src/libstore/build/worker.hh b/src/libstore/build/worker.hh
index 6735ea0b9..37d80ba7b 100644
--- a/src/libstore/build/worker.hh
+++ b/src/libstore/build/worker.hh
@@ -21,24 +21,6 @@ class DrvOutputSubstitutionGoal;
typedef std::chrono::time_point<std::chrono::steady_clock> steady_time_point;
-/**
- * A mapping used to remember for each child process to what goal it
- * belongs, and file descriptors for receiving log data and output
- * path creation commands.
- */
-struct Child
-{
- WeakGoalPtr goal;
- Goal * goal2; // ugly hackery
- std::set<int> fds;
- bool inBuildSlot;
- /**
- * Time we last got output on stdout/stderr
- */
- steady_time_point lastOutput;
- steady_time_point timeStarted;
-};
-
/* Forward definition. */
struct HookInstance;
@@ -117,11 +99,6 @@ private:
WeakGoals wantingToBuild;
/**
- * Child processes currently running.
- */
- std::list<Child> children;
-
- /**
* Number of build slots occupied. This includes local builds but does not
* include substitutions or remote builds via the build hook.
*/
@@ -179,6 +156,8 @@ private:
void goalFinished(GoalPtr goal, Goal::Finished & f);
void handleWorkResult(GoalPtr goal, Goal::WorkResult how);
+ kj::Own<kj::PromiseFulfiller<void>> childFinished;
+
/**
* Put `goal` to sleep until a build slot becomes available (which
* might be right away).
@@ -212,10 +191,15 @@ private:
* Registers a running child process. `inBuildSlot` means that
* the process counts towards the jobs limit.
*/
- void childStarted(GoalPtr goal, const std::set<int> & fds,
+ void childStarted(GoalPtr goal, kj::Promise<Outcome<void, Goal::Finished>> promise,
bool inBuildSlot);
/**
+ * Unregisters a running child process.
+ */
+ void childTerminated(GoalPtr goal, bool inBuildSlot);
+
+ /**
* Pass current stats counters to the logger for progress bar updates.
*/
void updateStatistics();
@@ -240,6 +224,11 @@ public:
Store & evalStore;
kj::AsyncIoContext & aio;
+private:
+ kj::TaskSet children;
+ std::exception_ptr childException;
+
+public:
struct HookState {
std::unique_ptr<HookInstance> instance;
@@ -303,11 +292,6 @@ private:
public:
/**
- * Unregisters a running child process.
- */
- void childTerminated(Goal * goal);
-
- /**
* Loop until the specified top-level goals have finished.
*/
Goals run(std::function<Goals (GoalFactory &)> req);