aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2019-06-04 13:24:28 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-06-11 12:34:18 +0200
commit08215dd21ebefe41f30e43d630a68d644419d021 (patch)
tree7d09ea0510af4ab4b5f68a008d7fd22bc53cde0c /tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
parentab933b1c92ec4f39ce280fdf956a4c4a746cf4d9 (diff)
Allow destroying QJSValues from other threads
QVariants are commonly passed around between threads and QVariants can wrap QJSValues. Therefore we need to allow this. The persistent value is freed immediately if we're still in the same thread. Otherwise a message is passed to the QJSEngine that owns it. If there is no QJSEngine we assume that we can free the value immediately. As such a thing can only happen via private API we can make sure this assumption holds. Fixes: QTBUG-75939 Change-Id: I14c09fd5d6ef7ba689f66656f2bcbb5c88bacf89 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'tests/auto/qml/qjsvalue/tst_qjsvalue.cpp')
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index f9718e3699..ebbc9f7e0a 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -27,7 +27,14 @@
****************************************************************************/
#include "tst_qjsvalue.h"
+
+#include <private/qv4engine_p.h>
+#include <private/qjsvalue_p.h>
+
#include <QtWidgets/QPushButton>
+#include <QtCore/qthread.h>
+
+#include <memory>
tst_QJSValue::tst_QJSValue()
: engine(nullptr)
@@ -2610,4 +2617,34 @@ void tst_QJSValue::nestedObjectToVariant()
QCOMPARE(o.toVariant(), expected);
}
+void tst_QJSValue::deleteFromDifferentThread()
+{
+#if !QT_CONFIG(thread)
+ QSKIP("Need thread support to destroy QJSValues from different threads");
+#else
+ QV4::PersistentValueStorage storage(engine->handle());
+ QCOMPARE(storage.firstPage, nullptr);
+ QJSValue jsval;
+ QJSValuePrivate::setRawValue(&jsval, storage.allocate());
+ QVERIFY(storage.firstPage != nullptr);
+
+ QMutex mutex;
+ QWaitCondition condition;
+
+ std::unique_ptr<QThread> thread(QThread::create([&]() {
+ QMutexLocker locker(&mutex);
+ QJSValuePrivate::free(&jsval);
+ QJSValuePrivate::setRawValue(&jsval, nullptr);
+ QVERIFY(storage.firstPage != nullptr);
+ condition.wakeOne();
+ }));
+
+ QMutexLocker locker(&mutex);
+ thread->start();
+ condition.wait(&mutex);
+ QTRY_VERIFY(thread->isFinished());
+ QTRY_COMPARE(storage.firstPage, nullptr);
+#endif
+}
+
QTEST_MAIN(tst_QJSValue)