Merge pull request #7155 from jherico/script_engine_crash

Fix a number of crashes / hangs on exit
This commit is contained in:
Clément Brisset 2016-02-22 16:17:33 -08:00
commit 965d6bb006
4 changed files with 28 additions and 7 deletions

View file

@ -260,10 +260,22 @@ QNetworkReply* OBJReader::request(QUrl& url, bool isTest) {
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkRequest netRequest(url);
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
QObject::connect(netReply, SIGNAL(finished()), &loop, SLOT(quit()));
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.
}

View file

@ -315,6 +315,8 @@ OffscreenQmlSurface::OffscreenQmlSurface() {
}
OffscreenQmlSurface::~OffscreenQmlSurface() {
QObject::disconnect(&_updateTimer);
QObject::disconnect(qApp);
_renderer->stop();
delete _rootItem;
delete _renderer;
@ -322,6 +324,10 @@ OffscreenQmlSurface::~OffscreenQmlSurface() {
delete _qmlEngine;
}
void OffscreenQmlSurface::onAboutToQuit() {
QObject::disconnect(&_updateTimer);
}
void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
_renderer = new OffscreenQmlRenderer(this, shareContext);
_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,
// a timer with a small interval is used to get better performance.
_updateTimer.setInterval(MIN_TIMER_MS);
connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
QObject::connect(qApp, &QCoreApplication::aboutToQuit, [this]{
disconnect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
});
QObject::connect(&_updateTimer, &QTimer::timeout, this, &OffscreenQmlSurface::updateQuick);
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &OffscreenQmlSurface::onAboutToQuit);
_updateTimer.start();
_qmlComponent = new QQmlComponent(_qmlEngine);
_qmlEngine->rootContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
}

View file

@ -74,6 +74,7 @@ signals:
public slots:
void requestUpdate();
void requestRender();
void onAboutToQuit();
private:
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);

View file

@ -144,7 +144,12 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
ScriptEngine::~ScriptEngine() {
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() {