Skip to content

Commit 9c92105

Browse files
committed
core/reloader: fix incubator warnings
1 parent 8882f7c commit 9c92105

File tree

2 files changed

+55
-49
lines changed

2 files changed

+55
-49
lines changed

src/core/generation.cpp

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ void EngineGeneration::onReload(EngineGeneration* old) {
117117
if (old != nullptr) {
118118
// if the old generation holds the window incubation controller as the
119119
// new generation acquires it then incubators will hang intermittently
120-
old->incubationControllers.clear();
120+
qCDebug(logIncubator) << "Locking incubation controllers of old generation" << old;
121+
old->incubationControllersLocked = true;
121122
old->assignIncubationController();
122123
}
123124

@@ -200,27 +201,25 @@ void EngineGeneration::onDirectoryChanged() {
200201
}
201202

202203
void EngineGeneration::registerIncubationController(QQmlIncubationController* controller) {
203-
auto* obj = dynamic_cast<QObject*>(controller);
204-
205204
// We only want controllers that we can swap out if destroyed.
206205
// This happens if the window owning the active controller dies.
207-
if (obj == nullptr) {
208-
qCDebug(logIncubator) << "Could not register incubation controller as it is not a QObject"
209-
<< controller;
206+
if (auto* obj = dynamic_cast<QObject*>(controller)) {
207+
QObject::connect(
208+
obj,
209+
&QObject::destroyed,
210+
this,
211+
&EngineGeneration::incubationControllerDestroyed
212+
);
213+
} else {
214+
qCWarning(logIncubator) << "Could not register incubation controller as it is not a QObject"
215+
<< controller;
210216

211217
return;
212218
}
213219

214-
this->incubationControllers.push_back({controller, obj});
215-
216-
QObject::connect(
217-
obj,
218-
&QObject::destroyed,
219-
this,
220-
&EngineGeneration::incubationControllerDestroyed
221-
);
222-
223-
qCDebug(logIncubator) << "Registered incubation controller" << controller;
220+
this->incubationControllers.push_back(controller);
221+
qCDebug(logIncubator) << "Registered incubation controller" << controller << "to generation"
222+
<< this;
224223

225224
// This function can run during destruction.
226225
if (this->engine == nullptr) return;
@@ -231,22 +230,20 @@ void EngineGeneration::registerIncubationController(QQmlIncubationController* co
231230
}
232231

233232
void EngineGeneration::deregisterIncubationController(QQmlIncubationController* controller) {
234-
QObject* obj = nullptr;
235-
this->incubationControllers.removeIf([&](QPair<QQmlIncubationController*, QObject*> other) {
236-
if (controller == other.first) {
237-
obj = other.second;
238-
return true;
239-
} else return false;
240-
});
241-
242-
if (obj == nullptr) {
243-
qCWarning(logIncubator) << "Failed to deregister incubation controller" << controller
244-
<< "as it was not registered to begin with";
245-
qCWarning(logIncubator) << "Current registered incuabation controllers"
246-
<< this->incubationControllers;
247-
} else {
233+
if (auto* obj = dynamic_cast<QObject*>(controller)) {
248234
QObject::disconnect(obj, nullptr, this, nullptr);
249-
qCDebug(logIncubator) << "Deregistered incubation controller" << controller;
235+
} else {
236+
qCCritical(logIncubator) << "Deregistering incubation controller which is not a QObject, "
237+
"however only QObject controllers should be registered.";
238+
}
239+
240+
if (!this->incubationControllers.removeOne(controller)) {
241+
qCCritical(logIncubator) << "Failed to deregister incubation controller" << controller << "from"
242+
<< this << "as it was not registered to begin with";
243+
qCCritical(logIncubator) << "Current registered incuabation controllers"
244+
<< this->incubationControllers;
245+
} else {
246+
qCDebug(logIncubator) << "Deregistered incubation controller" << controller << "from" << this;
250247
}
251248

252249
// This function can run during destruction.
@@ -261,22 +258,25 @@ void EngineGeneration::deregisterIncubationController(QQmlIncubationController*
261258

262259
void EngineGeneration::incubationControllerDestroyed() {
263260
auto* sender = this->sender();
264-
QQmlIncubationController* controller = nullptr;
265-
266-
this->incubationControllers.removeIf([&](QPair<QQmlIncubationController*, QObject*> other) {
267-
if (sender == other.second) {
268-
controller = other.first;
269-
return true;
270-
} else return false;
271-
});
261+
auto* controller = dynamic_cast<QQmlIncubationController*>(sender);
272262

273263
if (controller == nullptr) {
274-
qCCritical(logIncubator) << "Destroyed incubation controller" << this->sender()
275-
<< "could not be identified, this may cause memory corruption";
264+
qCCritical(logIncubator) << "Destroyed incubation controller" << sender
265+
<< "is not known to" << this << ", this may cause memory corruption";
276266
qCCritical(logIncubator) << "Current registered incuabation controllers"
277267
<< this->incubationControllers;
268+
269+
return;
270+
}
271+
272+
if (this->incubationControllers.removeOne(controller)) {
273+
qCDebug(logIncubator) << "Destroyed incubation controller" << controller << "deregistered from"
274+
<< this;
278275
} else {
279-
qCDebug(logIncubator) << "Destroyed incubation controller" << controller << "deregistered";
276+
qCCritical(logIncubator) << "Destroyed incubation controller" << controller
277+
<< "was not registered, but its destruction was observed by" << this;
278+
279+
return;
280280
}
281281

282282
// This function can run during destruction.
@@ -314,11 +314,16 @@ void EngineGeneration::exit(int code) {
314314

315315
void EngineGeneration::assignIncubationController() {
316316
QQmlIncubationController* controller = nullptr;
317-
if (this->incubationControllers.isEmpty()) controller = &this->delayedIncubationController;
318-
else controller = this->incubationControllers.first().first;
319317

320-
qCDebug(logIncubator) << "Assigning incubation controller to engine:" << controller
321-
<< "fallback:" << (controller == &this->delayedIncubationController);
318+
if (this->incubationControllersLocked || this->incubationControllers.isEmpty()) {
319+
controller = &this->delayedIncubationController;
320+
} else {
321+
controller = this->incubationControllers.first();
322+
}
323+
324+
qCDebug(logIncubator) << "Assigning incubation controller" << controller << "to generation"
325+
<< this
326+
<< "fallback:" << (controller == &this->delayedIncubationController);
322327

323328
this->engine->setIncubationController(controller);
324329
}
@@ -334,7 +339,8 @@ EngineGeneration* EngineGeneration::findEngineGeneration(const QQmlEngine* engin
334339
}
335340

336341
EngineGeneration* EngineGeneration::findObjectGeneration(const QObject* object) {
337-
if (g_generations.size() == 1) return EngineGeneration::currentGeneration();
342+
// Objects can still attempt to find their generation after it has been destroyed.
343+
// if (g_generations.size() == 1) return EngineGeneration::currentGeneration();
338344

339345
while (object != nullptr) {
340346
auto* context = QQmlEngine::contextForObject(object);

src/core/generation.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <qfilesystemwatcher.h>
66
#include <qhash.h>
77
#include <qobject.h>
8-
#include <qpair.h>
98
#include <qqmlengine.h>
109
#include <qqmlincubator.h>
1110
#include <qtclasshelpermacros.h>
@@ -84,7 +83,8 @@ private slots:
8483
private:
8584
void postReload();
8685
void assignIncubationController();
87-
QVector<QPair<QQmlIncubationController*, QObject*>> incubationControllers;
86+
QVector<QQmlIncubationController*> incubationControllers;
87+
bool incubationControllersLocked = false;
8888
QHash<const void*, EngineGenerationExt*> extensions;
8989

9090
bool destroying = false;

0 commit comments

Comments
 (0)