forked from qt-creator/qt-creator
TaskTree: Fix For loop with empty body
Ensure the For loop iterates even when the loop's body is empty. Simplify internals a bit. Change-Id: I4a269d61fa324a9c36109e95e74a992e915a72b0 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -2185,13 +2185,6 @@ SetupResult TaskTreePrivate::start(RuntimeContainer *container)
|
||||
container->m_successBit = startAction == SetupResult::StopWithSuccess;
|
||||
}
|
||||
}
|
||||
if (startAction == SetupResult::Continue
|
||||
&& (containerNode.m_children.empty()
|
||||
|| (containerNode.m_loop && !invokeLoopHandler(container)))) {
|
||||
if (isProgressive(container))
|
||||
advanceProgress(containerNode.m_taskCount);
|
||||
startAction = toSetupResult(container->m_successBit);
|
||||
}
|
||||
return continueStart(container, startAction);
|
||||
}
|
||||
|
||||
@@ -2225,14 +2218,14 @@ SetupResult TaskTreePrivate::startChildren(RuntimeContainer *container)
|
||||
const int childCount = int(containerNode.m_children.size());
|
||||
|
||||
if (container->m_iterationCount == 0) {
|
||||
if (container->m_shouldIterate && !invokeLoopHandler(container)) {
|
||||
if (isProgressive(container))
|
||||
advanceProgress(containerNode.m_taskCount);
|
||||
return toSetupResult(container->m_successBit);
|
||||
}
|
||||
container->m_iterations.emplace_back(
|
||||
std::make_unique<RuntimeIteration>(container->m_iterationCount, container));
|
||||
++container->m_iterationCount;
|
||||
} else if (containerNode.m_parallelLimit == 0) {
|
||||
container->deleteFinishedIterations();
|
||||
if (container->m_iterations.empty())
|
||||
return toSetupResult(container->m_successBit);
|
||||
return SetupResult::Continue;
|
||||
}
|
||||
|
||||
GuardLocker locker(container->m_startGuard);
|
||||
@@ -2241,17 +2234,20 @@ SetupResult TaskTreePrivate::startChildren(RuntimeContainer *container)
|
||||
|| container->m_runningChildren < containerNode.m_parallelLimit) {
|
||||
container->deleteFinishedIterations();
|
||||
if (container->m_nextToStart == childCount) {
|
||||
if (container->m_shouldIterate && invokeLoopHandler(container)) {
|
||||
if (invokeLoopHandler(container)) {
|
||||
container->m_nextToStart = 0;
|
||||
container->m_iterations.emplace_back(
|
||||
std::make_unique<RuntimeIteration>(container->m_iterationCount, container));
|
||||
++container->m_iterationCount;
|
||||
} else if (container->m_iterations.empty()) {
|
||||
return toSetupResult(container->m_successBit);
|
||||
} else {
|
||||
if (container->m_iterations.empty())
|
||||
return toSetupResult(container->m_successBit);
|
||||
return SetupResult::Continue;
|
||||
}
|
||||
}
|
||||
if (containerNode.m_children.size() == 0) // Empty loop body.
|
||||
continue;
|
||||
|
||||
RuntimeIteration *iteration = container->m_iterations.back().get();
|
||||
RuntimeTask *newTask = new RuntimeTask{containerNode.m_children.at(container->m_nextToStart),
|
||||
iteration};
|
||||
|
@@ -43,7 +43,8 @@ enum class Handler {
|
||||
Sync,
|
||||
BarrierAdvance,
|
||||
Timeout,
|
||||
Storage
|
||||
Storage,
|
||||
Iteration
|
||||
};
|
||||
Q_ENUM_NS(Handler);
|
||||
|
||||
@@ -2971,6 +2972,27 @@ void tst_Tasking::testTree_data()
|
||||
<< TestData{storage, root, {}, 1, DoneWith::Success, 0};
|
||||
}
|
||||
|
||||
{
|
||||
// Check if LoopUntil is executed with empty loop body.
|
||||
const For root {
|
||||
LoopUntil([storage](int iteration) {
|
||||
storage->m_log.append({iteration, Handler::Iteration});
|
||||
return iteration < 3;
|
||||
}),
|
||||
storage
|
||||
};
|
||||
|
||||
const Log log {
|
||||
{0, Handler::Iteration},
|
||||
{1, Handler::Iteration},
|
||||
{2, Handler::Iteration},
|
||||
{3, Handler::Iteration} // The last iteration returns false
|
||||
};
|
||||
|
||||
QTest::newRow("EmptyLoopUntil")
|
||||
<< TestData{storage, root, log, 0, DoneWith::Success, 0};
|
||||
}
|
||||
|
||||
{
|
||||
// Check if task tree finishes with the right progress value when onGroupSetup(false).
|
||||
const Group root {
|
||||
|
Reference in New Issue
Block a user