From 8eaf73700ecd0cd1f30b9973cb8b2ae0bc4bc52c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Feb 2023 12:05:18 +0100 Subject: [PATCH] TaskTree: Don't call storage done handlers from TaskTree's d'tor Change-Id: Ie2b04d433be3452f9e668efd3341dedfcb154290 Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/utils/tasktree.cpp | 12 ++++++++++- tests/auto/utils/tasktree/tst_tasktree.cpp | 24 +++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/tasktree.cpp b/src/libs/utils/tasktree.cpp index f99b20d7612..90e4073e033 100644 --- a/src/libs/utils/tasktree.cpp +++ b/src/libs/utils/tasktree.cpp @@ -175,6 +175,7 @@ public: ~RuntimeData(); static QList createStorages(const TaskContainer::ConstData &constData); + void callStorageDoneHandlers(); bool updateSuccessBit(bool success); int currentLimit() const; @@ -384,6 +385,15 @@ QList TaskContainer::RuntimeData::createStorages(const TaskContainer::Const return storageIdList; } +void TaskContainer::RuntimeData::callStorageDoneHandlers() +{ + for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order + const TreeStorageBase storage = m_constData.m_storageList[i]; + const int storageId = m_storageIdList.value(i); + m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); + } +} + TaskContainer::RuntimeData::RuntimeData(const ConstData &constData) : m_constData(constData) , m_storageIdList(createStorages(constData)) @@ -397,7 +407,6 @@ TaskContainer::RuntimeData::~RuntimeData() for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order const TreeStorageBase storage = m_constData.m_storageList[i]; const int storageId = m_storageIdList.value(i); - m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); storage.deleteStorage(storageId); } } @@ -527,6 +536,7 @@ void TaskContainer::invokeEndHandler() invokeHandler(this, groupHandler.m_doneHandler); else if (!m_runtimeData->m_successBit && groupHandler.m_errorHandler) invokeHandler(this, groupHandler.m_errorHandler); + m_runtimeData->callStorageDoneHandlers(); m_runtimeData.reset(); } diff --git a/tests/auto/utils/tasktree/tst_tasktree.cpp b/tests/auto/utils/tasktree/tst_tasktree.cpp index 3e5c67050f5..43bf0468c5d 100644 --- a/tests/auto/utils/tasktree/tst_tasktree.cpp +++ b/tests/auto/utils/tasktree/tst_tasktree.cpp @@ -1054,26 +1054,40 @@ void tst_TaskTree::storageOperators() } // This test checks whether a running task tree may be safely destructed. -// It also checks whether destructor of task tree deletes properly the storage created -// while starting the task tree. +// It also checks whether the destructor of a task tree deletes properly the storage created +// while starting the task tree. When running task tree is destructed, the storage done +// handler shouldn't be invoked. void tst_TaskTree::storageDestructor() { + bool setupCalled = false; + const auto setupHandler = [&setupCalled](CustomStorage *) { + setupCalled = true; + }; + bool doneCalled = false; + const auto doneHandler = [&doneCalled](CustomStorage *) { + doneCalled = true; + }; QCOMPARE(CustomStorage::instanceCount(), 0); { + TreeStorage storage; const auto setupProcess = [testAppPath = m_testAppPath](QtcProcess &process) { process.setCommand(CommandLine(testAppPath, {"-sleep", "1000"})); }; const Group root { - Storage(TreeStorage()), + Storage(storage), Process(setupProcess) }; - TaskTree processTree(root); + TaskTree taskTree(root); QCOMPARE(CustomStorage::instanceCount(), 0); - processTree.start(); + taskTree.onStorageSetup(storage, setupHandler); + taskTree.onStorageDone(storage, doneHandler); + taskTree.start(); QCOMPARE(CustomStorage::instanceCount(), 1); } QCOMPARE(CustomStorage::instanceCount(), 0); + QVERIFY(setupCalled); + QVERIFY(!doneCalled); } QTEST_GUILESS_MAIN(tst_TaskTree)