QFuture: fix QtFuture::connect corner-cases
Connecting to nullptr, or connecting to a non-signal PMF, would result in a QFuture which would never finish. Catch these cases and handle them. Windows+MSVC for some reason fails the test. I can't entirely understand why, so I've marked it as XFAIL, with QTBUG-101761 to track it. Change-Id: I314980e7e9b7156d8cddd3b33d5cbf1d0bcd6116 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> (cherry picked from commit 5089db0303f4ee0ca0d7c6814e06beff119d8500) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
7c0e2c19dd
commit
c08842daea
@ -832,6 +832,11 @@ static QFuture<ArgsType<Signal>> connect(Sender *sender, Signal signal)
|
||||
using ArgsType = ArgsType<Signal>;
|
||||
QFutureInterface<ArgsType> promise;
|
||||
promise.reportStarted();
|
||||
if (!sender) {
|
||||
promise.reportCanceled();
|
||||
promise.reportFinished();
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
using Connections = std::pair<QMetaObject::Connection, QMetaObject::Connection>;
|
||||
auto connections = std::make_shared<Connections>();
|
||||
@ -862,6 +867,12 @@ static QFuture<ArgsType<Signal>> connect(Sender *sender, Signal signal)
|
||||
});
|
||||
}
|
||||
|
||||
if (!connections->first) {
|
||||
promise.reportCanceled();
|
||||
promise.reportFinished();
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
connections->second =
|
||||
QObject::connect(sender, &QObject::destroyed, sender, [promise, connections]() mutable {
|
||||
QObject::disconnect(connections->first);
|
||||
|
@ -3667,6 +3667,36 @@ void tst_QFuture::signalConnect()
|
||||
QVERIFY(!future.isCanceled());
|
||||
QVERIFY(future.isValid());
|
||||
}
|
||||
|
||||
// Connect to nullptr
|
||||
{
|
||||
SenderObject *sender = nullptr;
|
||||
auto future = QtFuture::connect(sender, &SenderObject::intArgSignal);
|
||||
QVERIFY(future.isFinished());
|
||||
QVERIFY(future.isCanceled());
|
||||
QVERIFY(!future.isValid());
|
||||
}
|
||||
|
||||
// Connect to non-signal
|
||||
{
|
||||
SenderObject sender;
|
||||
|
||||
#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
|
||||
#define EXPECT_FUTURE_CONNECT_FAIL() QEXPECT_FAIL("", "QTBUG-101761, test fails on Windows/MSVC", Continue)
|
||||
#else
|
||||
QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in SenderObject");
|
||||
#define EXPECT_FUTURE_CONNECT_FAIL()
|
||||
#endif
|
||||
|
||||
auto future = QtFuture::connect(&sender, &SenderObject::emitNoArg);
|
||||
EXPECT_FUTURE_CONNECT_FAIL();
|
||||
QVERIFY(future.isFinished());
|
||||
EXPECT_FUTURE_CONNECT_FAIL();
|
||||
QVERIFY(future.isCanceled());
|
||||
EXPECT_FUTURE_CONNECT_FAIL();
|
||||
QVERIFY(!future.isValid());
|
||||
#undef EXPECT_FUTURE_CONNECT_FAIL
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFuture::waitForFinished()
|
||||
|
Loading…
x
Reference in New Issue
Block a user