forked from qt-creator/qt-creator
TaskTree: Fix continuation when synchronous stop appeared
It may potentially crash when continuation unwinds on
synchronous stop. It's a similar fix to
567216bb49
, this time it
fixes the continuation when not directly coming from
TaskTree::start().
The follow up commit adds a test for crashing case.
Change-Id: Idd936e42b567ff4bddab717267c62f0104bf3b62
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -154,9 +154,10 @@ public:
|
|||||||
int currentLimit() const;
|
int currentLimit() const;
|
||||||
TaskAction childDone(bool success);
|
TaskAction childDone(bool success);
|
||||||
void groupDone(bool success);
|
void groupDone(bool success);
|
||||||
|
void treeDone(bool success);
|
||||||
void invokeEndHandler(bool success);
|
void invokeEndHandler(bool success);
|
||||||
void resetSuccessBit();
|
void resetSuccessBit(); // only on start
|
||||||
void updateSuccessBit(bool success);
|
void updateSuccessBit(bool success); // only on childDone
|
||||||
|
|
||||||
void createStorages();
|
void createStorages();
|
||||||
void deleteStorages();
|
void deleteStorages();
|
||||||
@@ -233,11 +234,7 @@ public:
|
|||||||
QTC_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't "
|
QTC_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't "
|
||||||
"exist in task tree. Its handlers will never be called."));
|
"exist in task tree. Its handlers will never be called."));
|
||||||
}
|
}
|
||||||
const TaskAction action = m_root->start();
|
m_root->start();
|
||||||
if (action == TaskAction::StopWithDone)
|
|
||||||
emitDone();
|
|
||||||
else if (action == TaskAction::StopWithError)
|
|
||||||
emitError();
|
|
||||||
}
|
}
|
||||||
void stop() {
|
void stop() {
|
||||||
QTC_ASSERT(m_root, return);
|
QTC_ASSERT(m_root, return);
|
||||||
@@ -366,17 +363,17 @@ TaskAction TaskContainer::start()
|
|||||||
const bool success = groupAction == TaskAction::StopWithDone;
|
const bool success = groupAction == TaskAction::StopWithDone;
|
||||||
m_taskTreePrivate->advanceProgress(m_taskCount);
|
m_taskTreePrivate->advanceProgress(m_taskCount);
|
||||||
invokeEndHandler(success);
|
invokeEndHandler(success);
|
||||||
|
groupDone(success);
|
||||||
return groupAction;
|
return groupAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetSuccessBit();
|
resetSuccessBit();
|
||||||
|
|
||||||
GuardLocker locker(m_startGuard);
|
|
||||||
return startChildren(0);
|
return startChildren(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskAction TaskContainer::startChildren(int nextChild)
|
TaskAction TaskContainer::startChildren(int nextChild)
|
||||||
{
|
{
|
||||||
|
GuardLocker locker(m_startGuard);
|
||||||
const int childCount = m_children.size();
|
const int childCount = m_children.size();
|
||||||
for (int i = nextChild; i < childCount; ++i) {
|
for (int i = nextChild; i < childCount; ++i) {
|
||||||
const int limit = currentLimit();
|
const int limit = currentLimit();
|
||||||
@@ -396,6 +393,7 @@ TaskAction TaskContainer::startChildren(int nextChild)
|
|||||||
for (int j = i + 1; j < limit; ++j)
|
for (int j = i + 1; j < limit; ++j)
|
||||||
skippedTaskCount += m_children.at(j)->taskCount();
|
skippedTaskCount += m_children.at(j)->taskCount();
|
||||||
m_taskTreePrivate->advanceProgress(skippedTaskCount);
|
m_taskTreePrivate->advanceProgress(skippedTaskCount);
|
||||||
|
treeDone(finalizeAction == TaskAction::StopWithDone);
|
||||||
|
|
||||||
return finalizeAction;
|
return finalizeAction;
|
||||||
}
|
}
|
||||||
@@ -458,13 +456,19 @@ TaskAction TaskContainer::childDone(bool success)
|
|||||||
|
|
||||||
void TaskContainer::groupDone(bool success)
|
void TaskContainer::groupDone(bool success)
|
||||||
{
|
{
|
||||||
if (isStarting())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_parentContainer) {
|
if (m_parentContainer) {
|
||||||
|
if (!m_parentContainer->isStarting())
|
||||||
m_parentContainer->childDone(success);
|
m_parentContainer->childDone(success);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!isStarting())
|
||||||
|
treeDone(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskContainer::treeDone(bool success)
|
||||||
|
{
|
||||||
|
if (m_parentContainer)
|
||||||
|
return;
|
||||||
if (success)
|
if (success)
|
||||||
m_taskTreePrivate->emitDone();
|
m_taskTreePrivate->emitDone();
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user