diff --git a/src/libs/utils/tasktree.cpp b/src/libs/utils/tasktree.cpp index eb2a91d560f..f3531a9e8d8 100644 --- a/src/libs/utils/tasktree.cpp +++ b/src/libs/utils/tasktree.cpp @@ -147,7 +147,7 @@ public: const TaskItem &task); ~TaskContainer(); TaskAction start(); - TaskAction startChildren(); + TaskAction startChildren(int nextChild); void stop(); bool isRunning() const; int taskCount() const; @@ -370,13 +370,13 @@ TaskAction TaskContainer::start() resetSuccessBit(); GuardLocker locker(m_startGuard); - return startChildren(); + return startChildren(0); } -TaskAction TaskContainer::startChildren() +TaskAction TaskContainer::startChildren(int nextChild) { const int childCount = m_children.size(); - for (int i = m_doneCount; i < childCount; ++i) { + for (int i = nextChild; i < childCount; ++i) { const int limit = currentLimit(); if (i >= limit) break; @@ -432,7 +432,7 @@ int TaskContainer::taskCount() const int TaskContainer::currentLimit() const { const int childCount = m_children.size(); - return m_parallelLimit ? qMin(m_doneCount + m_parallelLimit, childCount) : childCount; + return m_parallelLimit ? qMin(m_doneCount + m_parallelLimit, childCount) : childCount; } TaskAction TaskContainer::childDone(bool success) @@ -445,6 +445,7 @@ TaskAction TaskContainer::childDone(bool success) return toTaskAction(success); } + const int limit = currentLimit(); ++m_doneCount; updateSuccessBit(success); @@ -460,7 +461,10 @@ TaskAction TaskContainer::childDone(bool success) if (m_startGuard.isLocked()) return TaskAction::Continue; - return startChildren(); + if (limit >= m_children.size()) + return TaskAction::Continue; + + return startChildren(limit); } void TaskContainer::groupDone(bool success) @@ -563,6 +567,7 @@ void TaskContainer::deactivateStorages() TaskAction TaskNode::start() { + QTC_CHECK(!isRunning()); if (!isTask()) return m_container.start(); diff --git a/tests/auto/utils/tasktree/tst_tasktree.cpp b/tests/auto/utils/tasktree/tst_tasktree.cpp index 64a5a1120a8..4680c5e745c 100644 --- a/tests/auto/utils/tasktree/tst_tasktree.cpp +++ b/tests/auto/utils/tasktree/tst_tasktree.cpp @@ -565,6 +565,53 @@ void tst_TaskTree::processTree_data() {-1, Handler::GroupDone}}; QTest::newRow("DynamicSetupContinue") << dynamicSetupContinueRoot << storage << dynamicSetupContinueLog << true << true << 4; + + const Group nestedParallelRoot { + ParallelLimit(2), + Storage(storage), + Group { + Storage(TreeStorage()), + OnGroupSetup(std::bind(groupSetup, 1)), + Group { + parallel, + Process(std::bind(setupProcess, _1, 1)), + } + }, + Group { + Storage(TreeStorage()), + OnGroupSetup(std::bind(groupSetup, 2)), + Group { + parallel, + Process(std::bind(setupProcess, _1, 2)), + } + }, + Group { + Storage(TreeStorage()), + OnGroupSetup(std::bind(groupSetup, 3)), + Group { + parallel, + Process(std::bind(setupProcess, _1, 3)), + } + }, + Group { + Storage(TreeStorage()), + OnGroupSetup(std::bind(groupSetup, 4)), + Group { + parallel, + Process(std::bind(setupProcess, _1, 4)), + } + }, + }; + const Log nestedParallelLog{{1, Handler::GroupSetup}, + {1, Handler::Setup}, + {2, Handler::GroupSetup}, + {2, Handler::Setup}, + {3, Handler::GroupSetup}, + {3, Handler::Setup}, + {4, Handler::GroupSetup}, + {4, Handler::Setup}}; + QTest::newRow("NestedParallel") << nestedParallelRoot << storage << nestedParallelLog + << true << true << 4; } void tst_TaskTree::processTree()