diff options
author | Dave Andrews <jetdog330@hotmail.com> | 2016-08-22 22:34:06 -0400 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2016-09-29 15:03:56 +0000 |
commit | e354bdc5cbe33621def2b200f01d6376291570fc (patch) | |
tree | 7e16e831f0a2ec9e90909ee3db522a03daa16db6 /src/webchannel | |
parent | 3b28a6956cb3cab087481312dc82a907b118e0de (diff) | |
download | qtwebchannel-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/webchannel')
-rw-r--r-- | src/webchannel/qmetaobjectpublisher.cpp | 24 |
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; } |