aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-08-26 13:54:00 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-06 08:29:53 +0200
commit08e829e3a9dae0230678a8471275cebb4c8fb54e (patch)
treefdbbc6b718ef026cac7c929ca710277478a4739c /tests/auto/declarative/qdeclarativeecmascript/testtypes.h
parent0c0f03e2b9756afb4e868a76734cc90102218f0a (diff)
Add garbage collector prologue callback to qv8engine
This commit provides a generic way to manage persistent handles created by QML so that circular references don't cause leaks, by utilising v8's garbage collector callbacks. Change-Id: Ia898197fdf5d86b90915b835ce3e532f7d400de4 Reviewed-on: http://codereview.qt.nokia.com/3688 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'tests/auto/declarative/qdeclarativeecmascript/testtypes.h')
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index 2738ee3d60..52b74affa8 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -57,6 +57,9 @@
#include <QtDeclarative/qdeclarativescriptstring.h>
#include <QtDeclarative/qdeclarativecomponent.h>
+#include <private/qv8gccallback_p.h>
+#include <private/qdeclarativeengine_p.h>
+
class MyQmlAttachedObject : public QObject
{
Q_OBJECT
@@ -966,6 +969,108 @@ private:
int m_methodCallCount;
};
+class CircularReferenceObject : public QObject,
+ public QV8GCCallback::Node
+{
+ Q_OBJECT
+
+public:
+ CircularReferenceObject(QObject *parent = 0)
+ : QObject(parent), QV8GCCallback::Node(callback), m_referenced(0), m_dtorCount(0)
+ {
+ QV8GCCallback::addGcCallbackNode(this);
+ }
+
+ ~CircularReferenceObject()
+ {
+ if (m_dtorCount) *m_dtorCount = *m_dtorCount + 1;
+ }
+
+ Q_INVOKABLE void setDtorCount(int *dtorCount)
+ {
+ m_dtorCount = dtorCount;
+ }
+
+ Q_INVOKABLE CircularReferenceObject *generate(QObject *parent = 0)
+ {
+ CircularReferenceObject *retn = new CircularReferenceObject(parent);
+ retn->m_dtorCount = m_dtorCount;
+ return retn;
+ }
+
+ Q_INVOKABLE void addReference(QObject *other)
+ {
+ m_referenced = other;
+ }
+
+ static void callback(QV8GCCallback::Referencer *r, QV8GCCallback::Node *n)
+ {
+ CircularReferenceObject *cro = static_cast<CircularReferenceObject*>(n);
+ if (cro->m_referenced) {
+ r->addRelationship(cro, cro->m_referenced);
+ }
+ }
+
+private:
+ QObject *m_referenced;
+ int *m_dtorCount;
+};
+Q_DECLARE_METATYPE(CircularReferenceObject*)
+
+class CircularReferenceHandle : public QObject,
+ public QV8GCCallback::Node
+{
+ Q_OBJECT
+
+public:
+ CircularReferenceHandle(QObject *parent = 0)
+ : QObject(parent), QV8GCCallback::Node(gccallback), m_dtorCount(0)
+ {
+ QV8GCCallback::addGcCallbackNode(this);
+ }
+
+ ~CircularReferenceHandle()
+ {
+ if (m_dtorCount) *m_dtorCount = *m_dtorCount + 1;
+ }
+
+ Q_INVOKABLE void setDtorCount(int *dtorCount)
+ {
+ m_dtorCount = dtorCount;
+ }
+
+ Q_INVOKABLE CircularReferenceHandle *generate(QObject *parent = 0)
+ {
+ CircularReferenceHandle *retn = new CircularReferenceHandle(parent);
+ retn->m_dtorCount = m_dtorCount;
+ return retn;
+ }
+
+ Q_INVOKABLE void addReference(v8::Persistent<v8::Value> handle)
+ {
+ m_referenced = qPersistentNew(handle);
+ m_referenced.MakeWeak(static_cast<void*>(this), wrcallback);
+ }
+
+ static void wrcallback(v8::Persistent<v8::Value> handle, void *params)
+ {
+ CircularReferenceHandle *crh = static_cast<CircularReferenceHandle*>(params);
+ qPersistentDispose(handle);
+ crh->m_referenced.Clear();
+ }
+
+ static void gccallback(QV8GCCallback::Referencer *r, QV8GCCallback::Node *n)
+ {
+ CircularReferenceHandle *crh = static_cast<CircularReferenceHandle*>(n);
+ r->addRelationship(crh, crh->m_referenced);
+ }
+
+private:
+ v8::Persistent<v8::Value> m_referenced;
+ int *m_dtorCount;
+};
+Q_DECLARE_METATYPE(CircularReferenceHandle*)
+
void registerTypes();
#endif // TESTTYPES_H