diff options
author | Thomas McGuire <thomas.mcguire.qnx@kdab.com> | 2012-08-15 07:50:47 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-09-14 11:33:45 (GMT) |
commit | ecc432a5b7ae269220f86c6f0b3dd364f8643191 (patch) | |
tree | 66c9f0ecc280d9b71e677266f533ce9edafa0f94 /src/script | |
parent | 3414828ccc91da0d94f3b160f29766b9273357ad (diff) | |
download | Qt-ecc432a5b7ae269220f86c6f0b3dd364f8643191.zip Qt-ecc432a5b7ae269220f86c6f0b3dd364f8643191.tar.gz Qt-ecc432a5b7ae269220f86c6f0b3dd364f8643191.tar.bz2 |
Delete JS-owned QML objects right away in the engine dtor.
This prevents memory leaks when the engine is destroyed after exec()
has already finished. In most cases this happens during application
shutdown, at which point the event loop is never entered again.
Task-number: QTBUG-20377
Change-Id: I65564ed3e56314d656d92fd66f11ae67d4eb932b
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/api/qscriptengine.cpp | 3 | ||||
-rw-r--r-- | src/script/api/qscriptengine_p.h | 1 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeclass_p.h | 9 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeobject.cpp | 5 |
4 files changed, 16 insertions, 2 deletions
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index d821084..cebbe0e 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -962,7 +962,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() qobjectPrototype(0), qmetaobjectPrototype(0), variantPrototype(0), activeAgent(0), agentLineNumber(-1), registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0), - registeredScriptStrings(0), processEventsInterval(-1), inEval(false) + registeredScriptStrings(0), processEventsInterval(-1), inEval(false), inDestructor(false) { qMetaTypeId<QScriptValue>(); qMetaTypeId<QList<int> >(); @@ -1015,6 +1015,7 @@ QScriptEnginePrivate::QScriptEnginePrivate() QScriptEnginePrivate::~QScriptEnginePrivate() { + inDestructor = true; QScript::APIShim shim(this); //disconnect all loadedScripts and generate all jsc::debugger::scriptUnload events diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 6a023d7..8a7037b 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -382,6 +382,7 @@ public: int processEventsInterval; QScriptValue abortResult; bool inEval; + bool inDestructor; JSC::UString cachedTranslationUrl; JSC::UString cachedTranslationContext; diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index c8c35bf..c67d23d 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -77,7 +77,14 @@ public: typedef void* Identifier; - struct Object { virtual ~Object() {} }; + struct Object { + // Like the destructor, frees resources associated with this object. The difference is that + // the destructor might delay resource freeing with deleteLater(), while disposeNow() always + // deletes the resource straigt away. + virtual void disposeNow() {} + + virtual ~Object() {} + }; static QScriptValue newObject(QScriptEngine *, QScriptDeclarativeClass *, Object *); static Value newObjectValue(QScriptEngine *, QScriptDeclarativeClass *, Object *); diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index 927309a..a9cd87d 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -53,6 +53,11 @@ DeclarativeObjectDelegate::DeclarativeObjectDelegate(QScriptDeclarativeClass *c, DeclarativeObjectDelegate::~DeclarativeObjectDelegate() { + // When the engine is being destructed, delete the object now, instead of using deleteLater(), + // to not have memory leaks on exit. + if (m_class->engine() && QScriptEnginePrivate::get(m_class->engine())->inDestructor) + m_object->disposeNow(); + delete m_object; } |