summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2011-11-29 01:44:18 +0100
committerQt by Nokia <qt-info@nokia.com>2011-11-30 01:04:12 +0100
commit55b974faa158a36cb0ab39fd9cfd11b2f6c186ba (patch)
treefde69f585180dc7ef8b70563abba2a10c9620eb5
parentfa7f690178d2f74db168a23064a688fe421cb1e6 (diff)
Fix Qt::QueuedConnection when signal has a return value
For queued connections, the args[0] is set to null as it make no sens to forward the return value to the signal. So we need to check in the operator, that the pointer is not null. (container.data is args[0]) Change-Id: I80bde66f1ec19de0f4962c80e5b2797d2819075c Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
-rw-r--r--src/corelib/kernel/qobject_impl.h6
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp57
2 files changed, 61 insertions, 2 deletions
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index 9918b1f1c2..d34b81ceaf 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -96,12 +96,14 @@ namespace QtPrivate {
};
template<typename T, typename U>
void operator,(const T &value, const ApplyReturnValue<U> &container) {
- *reinterpret_cast<U*>(container.data) = value;
+ if (container.data)
+ *reinterpret_cast<U*>(container.data) = value;
}
#ifdef Q_COMPILER_RVALUE_REFS
template<typename T, typename U>
void operator,(T &&value, const ApplyReturnValue<U> &container) {
- *reinterpret_cast<U*>(container.data) = value;
+ if (container.data)
+ *reinterpret_cast<U*>(container.data) = value;
}
#endif
template<typename T>
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 5e69a14ba8..511eb73d9d 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -4978,6 +4978,29 @@ void tst_QObject::returnValue()
QVERIFY(connect(&r, &ReturnValue::returnCustomType, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
}
+ if (!isBlockingQueued) {
+ // queued connection should not forward the return value
+ CheckInstanceCount checker;
+ ReturnValue r;
+ QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnVariantSlot, Qt::QueuedConnection));
+ QCOMPARE(emit r.returnVariant(45), QVariant());
+ QVERIFY(connect(&r, &ReturnValue::returnString, &receiver, &ReturnValue::returnStringSlot, Qt::QueuedConnection));
+ QCOMPARE(emit r.returnString(45), QString());
+ QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::returnIntSlot, Qt::QueuedConnection));
+ QCOMPARE(emit r.returnInt(45), int());
+ QVERIFY(connect(&r, &ReturnValue::returnCustomType, &receiver, &ReturnValue::returnCustomTypeSlot, Qt::QueuedConnection));
+ QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
+ QCoreApplication::processEvents();
+
+ QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnStringSlot, Qt::QueuedConnection));
+ QCOMPARE(emit r.returnVariant(48), QVariant());
+ QVERIFY(connect(&r, &ReturnValue::returnCustomType, &receiver, &ReturnValue::returnIntSlot, Qt::QueuedConnection));
+ QCOMPARE((emit r.returnCustomType(48)).value(), CustomType().value());
+ QVERIFY(connect(&r, &ReturnValue::returnVoid, &receiver, &ReturnValue::returnCustomTypeSlot, Qt::QueuedConnection));
+ emit r.returnVoid(48);
+ QCoreApplication::processEvents();
+ }
+
{ // connected to many slots
ReturnValue::VoidFunctor voidFunctor;
ReturnValue::IntFunctor intFunctor;
@@ -4994,6 +5017,8 @@ void tst_QObject::returnValue()
QCOMPARE(emit r.returnVariant(45), QVariant(QStringLiteral("hello")));
QVERIFY(connect(&r, &ReturnValue::returnVariant, intFunctor));
QCOMPARE(emit r.returnVariant(45), QVariant(45));
+ QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::return23, Qt::QueuedConnection));
+ QCOMPARE(emit r.returnVariant(45), QVariant(45));
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::returnVoidSlot, type));
@@ -5006,7 +5031,12 @@ void tst_QObject::returnValue()
QCOMPARE(emit r.returnInt(45), int(23));
QVERIFY(connect(&r, &ReturnValue::returnInt, intFunctor));
QCOMPARE(emit r.returnInt(45), int(45));
+ QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::return23, Qt::QueuedConnection));
+ QCOMPARE(emit r.returnInt(45), int(45));
+
+ QCoreApplication::processEvents();
}
+
if (isBlockingQueued) {
thread.quit();
thread.wait();
@@ -5055,6 +5085,29 @@ void tst_QObject::returnValue2()
QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
}
+ if (!isBlockingQueued) {
+ // queued connection should not forward the return value
+ CheckInstanceCount checker;
+ ReturnValue r;
+ QVERIFY(connect(&r, SIGNAL(returnVariant(int)), &receiver, SLOT(returnVariantSlot(int)), Qt::QueuedConnection));
+ QCOMPARE(emit r.returnVariant(45), QVariant());
+ QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnStringSlot(int)), Qt::QueuedConnection));
+ QCOMPARE(emit r.returnString(45), QString());
+ QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnIntSlot(int)), Qt::QueuedConnection));
+ QCOMPARE(emit r.returnInt(45), int());
+ QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnCustomTypeSlot(int)), Qt::QueuedConnection));
+ QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
+ QCoreApplication::processEvents();
+
+ //Queued conneciton with different return type should be safe
+ QVERIFY(connect(&r, SIGNAL(returnVariant(int)), &receiver, SLOT(returnStringSlot(int)), Qt::QueuedConnection));
+ QCOMPARE(emit r.returnVariant(48), QVariant());
+ QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnIntSlot(int)), Qt::QueuedConnection));
+ QCOMPARE((emit r.returnCustomType(48)).value(), CustomType().value());
+ QVERIFY(connect(&r, SIGNAL(returnVoid(int)), &receiver, SLOT(returnCustomTypeSlot(int)), Qt::QueuedConnection));
+ emit r.returnVoid(48);
+ QCoreApplication::processEvents();
+ }
{ // connected to many slots
ReturnValue r;
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnIntSlot(int)), type));
@@ -5063,6 +5116,8 @@ void tst_QObject::returnValue2()
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(return23()), type));
QCOMPARE(emit r.returnInt(45), int(23));
+ QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnIntSlot(int)), Qt::QueuedConnection));
+ QCOMPARE(emit r.returnInt(45), int(23));
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnStringSlot(int)), type));
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("45")));
@@ -5070,6 +5125,8 @@ void tst_QObject::returnValue2()
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("45")));
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnHello()), type));
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("hello")));
+ QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnStringSlot(int)), Qt::QueuedConnection));
+ QCOMPARE(emit r.returnString(45), QString(QStringLiteral("hello")));
}
if (isBlockingQueued) {
thread.quit();