summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDave Andrews <jetdog330@hotmail.com>2016-08-22 22:34:06 -0400
committerMilian Wolff <milian.wolff@kdab.com>2016-09-29 15:03:56 +0000
commite354bdc5cbe33621def2b200f01d6376291570fc (patch)
tree7e16e831f0a2ec9e90909ee3db522a03daa16db6 /src
parent3b28a6956cb3cab087481312dc82a907b118e0de (diff)
downloadqtwebchannel-e354bdc5cbe33621def2b200f01d6376291570fc.tar.gz
Fix asynchronous method calls on QObjects in different threads
Use QMetaMethod::invoke without a return for void method calls, which allows making asynchronous method calls onto QObjects in different affinities than the QWebChannel that's emitting them. Also adds a unit test called testAsyncObject that intentionally places a QObject in a different affinity and then tests calls into it from the QWebChannel's synchronous publisher. Task-number: QTBUG-47678 Change-Id: I6c35ee54f764c0fc1b0431fb0774aa7e75039abf Reviewed-by: Dave Andrews <jetdog330@hotmail.com> Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index cd6ad70..85a9b35 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -368,22 +368,26 @@ QVariant QMetaObjectPublisher::invokeMethod(QObject *const object, const int met
for (int i = 0; i < qMin(args.size(), method.parameterCount()); ++i) {
arguments[i].value = toVariant(args.at(i), method.parameterType(i));
}
-
// construct QGenericReturnArgument
QVariant returnValue;
- if (method.returnType() != qMetaTypeId<QVariant>() && method.returnType() != qMetaTypeId<void>()) {
+ if (method.returnType() == QMetaType::Void) {
+ // Skip return for void methods (prevents runtime warnings inside Qt), and allows
+ // QMetaMethod to invoke void-returning methods on QObjects in a different thread.
+ method.invoke(object,
+ arguments[0], arguments[1], arguments[2], arguments[3], arguments[4],
+ arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]);
+ } else {
+ QGenericReturnArgument returnArgument(method.typeName(), returnValue.data());
+
// Only init variant with return type if its not a variant itself, which would
// lead to nested variants which is not what we want.
- // Also, skip void-return types for obvious reasons (and to prevent a runtime warning inside Qt).
- returnValue = QVariant(method.returnType(), 0);
- }
- QGenericReturnArgument returnArgument(method.typeName(), returnValue.data());
-
- // now we can call the method
- method.invoke(object, returnArgument,
+ if (method.returnType() != QMetaType::QVariant)
+ returnValue = QVariant(method.returnType(), 0);
+ method.invoke(object, returnArgument,
arguments[0], arguments[1], arguments[2], arguments[3], arguments[4],
arguments[5], arguments[6], arguments[7], arguments[8], arguments[9]);
-
+ }
+ // now we can call the method
return returnValue;
}