aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsapi
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 /src/qml/jsapi
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 'src/qml/jsapi')
-rw-r--r--src/qml/jsapi/qjsvalue_p.h21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
index bcf0a9d12d..2faffffbae 100644
--- a/src/qml/jsapi/qjsvalue_p.h
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -60,6 +60,8 @@
#include <private/qv4mm_p.h>
#include <private/qv4persistent_p.h>
+#include <QtCore/qthread.h>
+
QT_BEGIN_NAMESPACE
class Q_AUTOTEST_EXPORT QJSValuePrivate
@@ -79,6 +81,11 @@ public:
return nullptr;
}
+ static inline void setRawValue(QJSValue *jsval, QV4::Value *v)
+ {
+ jsval->d = reinterpret_cast<quintptr>(v);
+ }
+
static inline void setVariant(QJSValue *jsval, const QVariant &v) {
QVariant *val = new QVariant(v);
jsval->d = reinterpret_cast<quintptr>(val) | 1;
@@ -169,10 +176,20 @@ public:
}
static inline void free(QJSValue *jsval) {
- if (QV4::Value *v = QJSValuePrivate::getValue(jsval))
+ if (QV4::Value *v = QJSValuePrivate::getValue(jsval)) {
+ if (QV4::ExecutionEngine *e = engine(jsval)) {
+ if (QJSEngine *jsEngine = e->jsEngine()) {
+ if (jsEngine->thread() != QThread::currentThread()) {
+ QMetaObject::invokeMethod(
+ jsEngine, [v](){ QV4::PersistentValueStorage::free(v); });
+ return;
+ }
+ }
+ }
QV4::PersistentValueStorage::free(v);
- else if (QVariant *v = QJSValuePrivate::getVariant(jsval))
+ } else if (QVariant *v = QJSValuePrivate::getVariant(jsval)) {
delete v;
+ }
}
};