aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-10-29 15:42:21 +0200
committerUlf Hermann <ulf.hermann@qt.io>2021-11-01 09:20:59 +0100
commit891072f3f5f8f988d4da6c39ab654b605e25dda7 (patch)
treef28b1623cbaa1e017e591775be13755a3ef76847 /src
parentd00c76171de0c76794eb70a7284326332c0b3c66 (diff)
QQmlComponent: Make it harder to leak deferred states
The previous pointer wrangling was ripe with foot guns. Let's just use a vector of unique_ptr to keep track of the states. Change-Id: I3ae225b3ab8644aa690d506d0a5de0bfb9ecce23 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlcomponent.cpp18
-rw-r--r--src/qml/qml/qqmlcomponent_p.h20
-rw-r--r--src/quicktemplates2/qquickdeferredexecute.cpp16
3 files changed, 20 insertions, 34 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 8293f17e7f..2b0e9ee31a 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1006,30 +1006,30 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
QQmlData *ddata = QQmlData::get(object);
Q_ASSERT(!ddata->deferredData.isEmpty());
- deferredState->constructionStates.reserve(ddata->deferredData.size());
+ deferredState->reserve(ddata->deferredData.size());
for (QQmlData::DeferredData *deferredData : qAsConst(ddata->deferredData)) {
enginePriv->inProgressCreations++;
- ConstructionState *state = new ConstructionState;
- state->completePending = true;
+ ConstructionState state;
+ state.completePending = true;
- state->creator.reset(new QQmlObjectCreator(
+ state.creator.reset(new QQmlObjectCreator(
deferredData->context->parent(), deferredData->compilationUnit,
QQmlRefPointer<QQmlContextData>()));
- if (!state->creator->populateDeferredProperties(object, deferredData))
- state->errors << state->creator->errors;
+ if (!state.creator->populateDeferredProperties(object, deferredData))
+ state.errors << state.creator->errors;
deferredData->bindings.clear();
- deferredState->constructionStates += state;
+ deferredState->push_back(std::move(state));
}
}
void QQmlComponentPrivate::completeDeferred(QQmlEnginePrivate *enginePriv, QQmlComponentPrivate::DeferredState *deferredState)
{
- for (ConstructionState *state : qAsConst(deferredState->constructionStates))
- complete(enginePriv, state);
+ for (ConstructionState &state : *deferredState)
+ complete(enginePriv, &state);
}
void QQmlComponentPrivate::complete(QQmlEnginePrivate *enginePriv, ConstructionState *state)
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 59ef47f2c3..f95e83f15e 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -112,27 +112,13 @@ public:
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
struct ConstructionState {
- ConstructionState()
- : completePending(false)
- {}
- ~ConstructionState()
- {
- }
-
- QScopedPointer<QQmlObjectCreator> creator;
+ std::unique_ptr<QQmlObjectCreator> creator;
QList<QQmlError> errors;
- bool completePending;
+ bool completePending = false;
};
ConstructionState state;
- struct DeferredState {
- ~DeferredState() {
- qDeleteAll(constructionStates);
- constructionStates.clear();
- }
- QVector<ConstructionState *> constructionStates;
- };
-
+ using DeferredState = std::vector<ConstructionState>;
static void beginDeferred(QQmlEnginePrivate *enginePriv, QObject *object, DeferredState* deferredState);
static void completeDeferred(QQmlEnginePrivate *enginePriv, DeferredState *deferredState);
diff --git a/src/quicktemplates2/qquickdeferredexecute.cpp b/src/quicktemplates2/qquickdeferredexecute.cpp
index 817415c492..8fb566a998 100644
--- a/src/quicktemplates2/qquickdeferredexecute.cpp
+++ b/src/quicktemplates2/qquickdeferredexecute.cpp
@@ -83,23 +83,23 @@ static bool beginDeferred(QQmlEnginePrivate *enginePriv, const QQmlProperty &pro
if (range.first == bindings.end())
continue;
- QQmlComponentPrivate::ConstructionState *state = new QQmlComponentPrivate::ConstructionState;
- state->completePending = true;
+ QQmlComponentPrivate::ConstructionState state;
+ state.completePending = true;
QQmlContextData *creationContext = nullptr;
- state->creator.reset(new QQmlObjectCreator(deferData->context->parent(), deferData->compilationUnit, creationContext));
+ state.creator.reset(new QQmlObjectCreator(deferData->context->parent(), deferData->compilationUnit, creationContext));
enginePriv->inProgressCreations++;
std::deque<const QV4::CompiledData::Binding *> reversedBindings;
std::copy(range.first, range.second, std::front_inserter(reversedBindings));
- state->creator->beginPopulateDeferred(deferData->context);
+ state.creator->beginPopulateDeferred(deferData->context);
for (const QV4::CompiledData::Binding *binding : reversedBindings)
- state->creator->populateDeferredBinding(property, deferData->deferredIdx, binding);
- state->creator->finalizePopulateDeferred();
- state->errors << state->creator->errors;
+ state.creator->populateDeferredBinding(property, deferData->deferredIdx, binding);
+ state.creator->finalizePopulateDeferred();
+ state.errors << state.creator->errors;
- deferredState->constructionStates += state;
+ deferredState->push_back(std::move(state));
// Cleanup any remaining deferred bindings for this property, also in inner contexts,
// to avoid executing them later and overriding the property that was just populated.