mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 05:17:24 +02:00
Merge pull request #7155 from jherico/script_engine_crash
Fix a number of crashes / hangs on exit
This commit is contained in:
commit
965d6bb006
4 changed files with 28 additions and 7 deletions
|
@ -260,10 +260,22 @@ QNetworkReply* OBJReader::request(QUrl& url, bool isTest) {
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
QNetworkRequest netRequest(url);
|
QNetworkRequest netRequest(url);
|
||||||
QNetworkReply* netReply = isTest ? networkAccessManager.head(netRequest) : networkAccessManager.get(netRequest);
|
QNetworkReply* netReply = isTest ? networkAccessManager.head(netRequest) : networkAccessManager.get(netRequest);
|
||||||
|
if (!qApp) {
|
||||||
|
return netReply;
|
||||||
|
}
|
||||||
QEventLoop loop; // Create an event loop that will quit when we get the finished signal
|
QEventLoop loop; // Create an event loop that will quit when we get the finished signal
|
||||||
QObject::connect(netReply, SIGNAL(finished()), &loop, SLOT(quit()));
|
QObject::connect(netReply, SIGNAL(finished()), &loop, SLOT(quit()));
|
||||||
loop.exec(); // Nothing is going to happen on this whole run thread until we get this
|
loop.exec(); // Nothing is going to happen on this whole run thread until we get this
|
||||||
netReply->waitForReadyRead(-1); // so we might as well block this thread waiting for the response, rather than
|
|
||||||
|
bool aboutToQuit { false };
|
||||||
|
auto connection = QObject::connect(qApp, &QCoreApplication::aboutToQuit, [&] {
|
||||||
|
aboutToQuit = true;
|
||||||
|
});
|
||||||
|
static const int WAIT_TIMEOUT_MS = 500;
|
||||||
|
while (qApp && !aboutToQuit && !netReply->isReadable()) {
|
||||||
|
netReply->waitForReadyRead(WAIT_TIMEOUT_MS); // so we might as well block this thread waiting for the response, rather than
|
||||||
|
}
|
||||||
|
QObject::disconnect(connection);
|
||||||
return netReply; // trying to sync later on.
|
return netReply; // trying to sync later on.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,8 @@ OffscreenQmlSurface::OffscreenQmlSurface() {
|
||||||
}
|
}
|
||||||
|
|
||||||
OffscreenQmlSurface::~OffscreenQmlSurface() {
|
OffscreenQmlSurface::~OffscreenQmlSurface() {
|
||||||
|
QObject::disconnect(&_updateTimer);
|
||||||
|
QObject::disconnect(qApp);
|
||||||
_renderer->stop();
|
_renderer->stop();
|
||||||
delete _rootItem;
|
delete _rootItem;
|
||||||
delete _renderer;
|
delete _renderer;
|
||||||
|
@ -322,6 +324,10 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
|
||||||
delete _qmlEngine;
|
delete _qmlEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::onAboutToQuit() {
|
||||||
|
QObject::disconnect(&_updateTimer);
|
||||||
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
||||||
_renderer = new OffscreenQmlRenderer(this, shareContext);
|
_renderer = new OffscreenQmlRenderer(this, shareContext);
|
||||||
_renderer->_renderControl->_renderWindow = _proxyWindow;
|
_renderer->_renderControl->_renderWindow = _proxyWindow;
|
||||||
|
@ -334,12 +340,9 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
||||||
// When Quick says there is a need to render, we will not render immediately. Instead,
|
// When Quick says there is a need to render, we will not render immediately. Instead,
|
||||||
// a timer with a small interval is used to get better performance.
|
// a timer with a small interval is used to get better performance.
|
||||||
_updateTimer.setInterval(MIN_TIMER_MS);
|
_updateTimer.setInterval(MIN_TIMER_MS);
|
||||||
connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
|
QObject::connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
|
||||||
QObject::connect(qApp, &QCoreApplication::aboutToQuit, [this]{
|
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &OffscreenQmlSurface::onAboutToQuit);
|
||||||
disconnect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
|
|
||||||
});
|
|
||||||
_updateTimer.start();
|
_updateTimer.start();
|
||||||
|
|
||||||
_qmlComponent = new QQmlComponent(_qmlEngine);
|
_qmlComponent = new QQmlComponent(_qmlEngine);
|
||||||
_qmlEngine->rootContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
_qmlEngine->rootContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
void requestUpdate();
|
void requestUpdate();
|
||||||
void requestRender();
|
void requestRender();
|
||||||
|
void onAboutToQuit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);
|
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);
|
||||||
|
|
|
@ -144,7 +144,12 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
ScriptEngine::~ScriptEngine() {
|
ScriptEngine::~ScriptEngine() {
|
||||||
qCDebug(scriptengine) << "Script Engine shutting down (destructor) for script:" << getFilename();
|
qCDebug(scriptengine) << "Script Engine shutting down (destructor) for script:" << getFilename();
|
||||||
|
|
||||||
DependencyManager::get<ScriptEngines>()->removeScriptEngine(this);
|
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||||
|
if (scriptEngines) {
|
||||||
|
scriptEngines->removeScriptEngine(this);
|
||||||
|
} else {
|
||||||
|
qCWarning(scriptengine) << "Script destroyed after ScriptEngines!";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEngine::disconnectNonEssentialSignals() {
|
void ScriptEngine::disconnectNonEssentialSignals() {
|
||||||
|
|
Loading…
Reference in a new issue