From 87b93c29be02f0a7ff9424b5e2b6431e20bd4c40 Mon Sep 17 00:00:00 2001 From: Tianlu Shao Date: Fri, 17 Dec 2021 10:27:55 +0800 Subject: [PATCH] QtConcurrent::run crashes on program exit When an application is about to be closed and all the destructors are called, if there isQtConcurrent::run on the way, it crashes as the internal threadpool pointer is nullptr. Fixes: QTBUG-98901 Pick-to: 6.2 6.3 Change-Id: Idd84d1518fc6a225263e6666a0f1de2ccef79c82 Reviewed-by: Sona Kurazyan --- src/concurrent/qtconcurrentrunbase.h | 8 +++++++- .../qtconcurrentrun/tst_qtconcurrentrun.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/concurrent/qtconcurrentrunbase.h b/src/concurrent/qtconcurrentrunbase.h index 6038d0e60cb..48703621469 100644 --- a/src/concurrent/qtconcurrentrunbase.h +++ b/src/concurrent/qtconcurrentrunbase.h @@ -93,7 +93,13 @@ public: promise.setRunnable(this); promise.reportStarted(); QFuture theFuture = promise.future(); - parameters.threadPool->start(this, parameters.priority); + + if (parameters.threadPool) { + parameters.threadPool->start(this, parameters.priority); + } else { + promise.reportCanceled(); + promise.reportFinished(); + } return theFuture; } diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index 235ffca0fcc..0ff98c42f5b 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -65,6 +65,7 @@ private slots: void crefFunction(); void customPromise(); void nonDefaultConstructibleValue(); + void nullThreadPool(); }; void light() @@ -1577,5 +1578,16 @@ void tst_QtConcurrentRun::nonDefaultConstructibleValue() QCOMPARE(future.result().value, 42); } +// QTBUG-98901 +void tst_QtConcurrentRun::nullThreadPool() +{ + QThreadPool *pool = nullptr; + std::atomic isInvoked = false; + auto future = run(pool, [&] { isInvoked = true; }); + future.waitForFinished(); + QVERIFY(future.isCanceled()); + QVERIFY(!isInvoked); +} + QTEST_MAIN(tst_QtConcurrentRun) #include "tst_qtconcurrentrun.moc"