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 Pick-to: 6.2 6.3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>bb10
parent
440438092b
commit
5089db0303
|
|
@ -880,6 +880,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>();
|
||||
|
|
@ -910,6 +915,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);
|
||||
|
|
|
|||
|
|
@ -3768,6 +3768,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…
Reference in New Issue