Details
-
Bug
-
Resolution: Unresolved
-
P1: Critical
-
None
-
6.5.2
-
None
Description
Hi,
I have found out, that if you use QtFuture::whenAny with a QtFuture::connect QFuture, the continuation for the whenAny QFuture gets called, if you delete the original object (the one you called QtFuture::connect on). Here's an example:
#include <QCoreApplication> #include <QFuture> #include <QTimer> int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QTimer::singleShot(0, [] { auto timer = new QTimer(); QtFuture::whenAny( QtFuture::connect(timer, &QTimer::timeout).then([] { return 1; })).then([] (const std::variant<QFuture<int>>& result) { std::get<0>(result).result(); }); delete timer; }); return QCoreApplication::exec(); }
The second .then callback gets called. Additionally, the `result` QFuture is invalid and calling .result() gives me a null-deref error, which is ok, according to the doc. However, in my opinion, there's no reason it should be called in the first place, because the timer wasn't even started. If I remove the whenAny call, everything works fine again. Additionally, if I add a context object `timer` to either of the .then() calls (or both), I'll get this assertion:
ASSERT: "context" in file /usr/include/qt6/QtCore/qfuture_impl.h, line 598
Aborted (core dumped)
The context object issue is also present even when not using whenAny, so I'm not sure if they're related:
#include <QCoreApplication> #include <QFuture> #include <QTimer> int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QTimer::singleShot(0, [] { auto timer = new QTimer(); QtFuture::connect(timer, &QTimer::timeout).then(timer, [] (auto) {}); delete timer; }); return QCoreApplication::exec(); }
I have looked at other issues, and it seems to me, that https://bugreports.qt.io/browse/QTBUG-107541 might be related, but I'm not sure.