summaryrefslogtreecommitdiffstats
path: root/src/script
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire.qnx@kdab.com>2012-08-15 07:50:47 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-09-14 11:33:45 (GMT)
commitecc432a5b7ae269220f86c6f0b3dd364f8643191 (patch)
tree66c9f0ecc280d9b71e677266f533ce9edafa0f94 /src/script
parent3414828ccc91da0d94f3b160f29766b9273357ad (diff)
downloadQt-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.cpp3
-rw-r--r--src/script/api/qscriptengine_p.h1
-rw-r--r--src/script/bridge/qscriptdeclarativeclass_p.h9
-rw-r--r--src/script/bridge/qscriptdeclarativeobject.cpp5
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;
}