summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2022-03-23 09:30:23 +0100
committerSona Kurazyan <sona.kurazyan@qt.io>2022-03-25 08:05:12 +0100
commit76a1c060ac76a9249febdb32e71fcddaf7fb2414 (patch)
treeccc35d91b646b1a03754cf151dd56b52babff5b2
parent837bfd6f145402c94570d1df4fb3446664cb7828 (diff)
Always cancel unfinished QPromises on destruction
If the QPromise is being destroyed, we should signal the associated futures to stop waiting. No matter in which state the promise is, if it's not finished, we should always cancel to avoid infinite waits. This is also what docs state: "The promise implicitly transitions to a canceled state on destruction unless finish() is called beforehand by the user." Fixes: QTBUG-101284 Pick-to: 6.3 6.2 Change-Id: I65ebfefe03b79b41afacda78a4f49938c54d8b37 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r--src/corelib/thread/qpromise.h10
-rw-r--r--tests/auto/corelib/thread/qpromise/tst_qpromise.cpp14
2 files changed, 16 insertions, 8 deletions
diff --git a/src/corelib/thread/qpromise.h b/src/corelib/thread/qpromise.h
index f7abf8babc..0fd7680314 100644
--- a/src/corelib/thread/qpromise.h
+++ b/src/corelib/thread/qpromise.h
@@ -71,15 +71,9 @@ public:
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QPromise)
~QPromise()
{
- const int state = d.loadState();
- // If QFutureInterface has no state, there is nothing to be done
- if (state == static_cast<int>(QFutureInterfaceBase::State::NoState)) {
- d.cleanContinuation();
- return;
- }
- // Otherwise, if computation is not finished at this point, cancel
+ // If computation is not finished at this point, cancel
// potential waits
- if (!(state & QFutureInterfaceBase::State::Finished)) {
+ if (d.d && !(d.loadState() & QFutureInterfaceBase::State::Finished)) {
d.cancelAndFinish(); // cancel and finalize the state
d.cleanContinuation();
}
diff --git a/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp b/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp
index 52f4daa24a..5c20287e89 100644
--- a/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp
+++ b/tests/auto/corelib/thread/qpromise/tst_qpromise.cpp
@@ -64,6 +64,7 @@ private slots:
void cancelWhenDestroyed();
#endif
void cancelWhenReassigned();
+ void cancelWhenDestroyedWithoutStarting();
void finishWhenSwapped();
void cancelWhenMoved();
void waitUntilResumed();
@@ -505,6 +506,19 @@ void tst_QPromise::cancelWhenReassigned()
#endif
}
+void tst_QPromise::cancelWhenDestroyedWithoutStarting()
+{
+ QFuture<void> future;
+ {
+ QPromise<void> promise;
+ future = promise.future();
+ }
+ future.waitForFinished();
+ QVERIFY(!future.isStarted());
+ QVERIFY(future.isCanceled());
+ QVERIFY(future.isFinished());
+}
+
void tst_QPromise::finishWhenSwapped()
{
#if !QT_CONFIG(cxx11_future)