forked from lix-project/lix
libstore: remove Worker::wakeUp()
Worker::run() is now entirely based on the kj event loop and promises,
so we need not handle awakeness of goals manually any more. every goal
can instead, once it has finished a partial work call, defer itself to
being called again in the next iteration of the loop. same end effect.
Change-Id: I320eee2fa60bcebaabd74d1323fa96d1402c1d15
This commit is contained in:
parent
d5db0b1abc
commit
732de75f67
|
@ -44,7 +44,6 @@ Worker::~Worker()
|
||||||
are in trouble, since goals may call childTerminated() etc. in
|
are in trouble, since goals may call childTerminated() etc. in
|
||||||
their destructors). */
|
their destructors). */
|
||||||
topGoals.clear();
|
topGoals.clear();
|
||||||
awake.clear();
|
|
||||||
children.clear();
|
children.clear();
|
||||||
|
|
||||||
assert(expectedSubstitutions == 0);
|
assert(expectedSubstitutions == 0);
|
||||||
|
@ -68,7 +67,10 @@ std::pair<std::shared_ptr<G>, kj::Promise<void>> Worker::makeGoalCommon(
|
||||||
goal = create();
|
goal = create();
|
||||||
goal->notify = std::move(goal_weak.fulfiller);
|
goal->notify = std::move(goal_weak.fulfiller);
|
||||||
goal_weak.goal = goal;
|
goal_weak.goal = goal;
|
||||||
wakeUp(goal);
|
// do not start working immediately, this round of the event loop
|
||||||
|
// may have more calls to this function lined up that'll also run
|
||||||
|
// modify(). starting early can then cause the goals to misbehave
|
||||||
|
childStarted(goal, kj::evalLater([goal] { return goal->work(); }));
|
||||||
} else {
|
} else {
|
||||||
modify(*goal);
|
modify(*goal);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +203,9 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
|
||||||
{
|
{
|
||||||
std::visit(
|
std::visit(
|
||||||
overloaded{
|
overloaded{
|
||||||
[&](Goal::StillAlive) { wakeUp(goal); },
|
[&](Goal::StillAlive) {
|
||||||
|
childStarted(goal, kj::evalLater([goal] { return goal->work(); }));
|
||||||
|
},
|
||||||
[&](Goal::Finished & f) { goalFinished(goal, f); },
|
[&](Goal::Finished & f) { goalFinished(goal, f); },
|
||||||
},
|
},
|
||||||
how
|
how
|
||||||
|
@ -230,13 +234,6 @@ void Worker::removeGoal(GoalPtr goal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::wakeUp(GoalPtr goal)
|
|
||||||
{
|
|
||||||
goal->trace("woken up");
|
|
||||||
awake.insert(goal);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Worker::childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> promise)
|
void Worker::childStarted(GoalPtr goal, kj::Promise<Result<Goal::WorkResult>> promise)
|
||||||
{
|
{
|
||||||
children.add(promise
|
children.add(promise
|
||||||
|
@ -322,26 +319,11 @@ try {
|
||||||
|
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
/* Call every wake goal (in the ordering established by
|
|
||||||
CompareGoalPtrs). */
|
|
||||||
while (!awake.empty() && !topGoals.empty()) {
|
|
||||||
Goals awake2 = std::move(awake);
|
|
||||||
for (auto & goal : awake2) {
|
|
||||||
checkInterrupt();
|
|
||||||
childStarted(goal, goal->work());
|
|
||||||
|
|
||||||
if (topGoals.empty()) break; // stuff may have been cancelled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topGoals.empty()) break;
|
if (topGoals.empty()) break;
|
||||||
|
|
||||||
/* Wait for input. */
|
/* Wait for input. */
|
||||||
if (!children.isEmpty())
|
if (!children.isEmpty())
|
||||||
(co_await waitForInput()).value();
|
(co_await waitForInput()).value();
|
||||||
else {
|
|
||||||
assert(!awake.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (childException) {
|
if (childException) {
|
||||||
std::rethrow_exception(childException);
|
std::rethrow_exception(childException);
|
||||||
|
@ -351,7 +333,6 @@ try {
|
||||||
/* If --keep-going is not set, it's possible that the main goal
|
/* If --keep-going is not set, it's possible that the main goal
|
||||||
exited while some of its subgoals were still active. But if
|
exited while some of its subgoals were still active. But if
|
||||||
--keep-going *is* set, then they must all be finished now. */
|
--keep-going *is* set, then they must all be finished now. */
|
||||||
assert(!settings.keepGoing || awake.empty());
|
|
||||||
assert(!settings.keepGoing || children.isEmpty());
|
assert(!settings.keepGoing || children.isEmpty());
|
||||||
|
|
||||||
co_return result::success();
|
co_return result::success();
|
||||||
|
|
|
@ -91,11 +91,6 @@ private:
|
||||||
*/
|
*/
|
||||||
Goals topGoals;
|
Goals topGoals;
|
||||||
|
|
||||||
/**
|
|
||||||
* Goals that are ready to do some work.
|
|
||||||
*/
|
|
||||||
Goals awake;
|
|
||||||
|
|
||||||
template<typename G>
|
template<typename G>
|
||||||
struct CachedGoal
|
struct CachedGoal
|
||||||
{
|
{
|
||||||
|
@ -149,11 +144,6 @@ private:
|
||||||
|
|
||||||
kj::Own<kj::PromiseFulfiller<void>> childFinished;
|
kj::Own<kj::PromiseFulfiller<void>> childFinished;
|
||||||
|
|
||||||
/**
|
|
||||||
* Wake up a goal (i.e., there is something for it to do).
|
|
||||||
*/
|
|
||||||
void wakeUp(GoalPtr goal);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for input to become available.
|
* Wait for input to become available.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue