summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@qt.io>2016-08-18 11:44:45 +0200
committerChristian Stromme <christian.stromme@qt.io>2016-08-23 14:55:49 +0000
commit5e3f770ad5e47f296b4782c0b6c5b03162027500 (patch)
treeef38b8ec77b976edfb7cc28e41450a6e6df8fd3a
parent449390c3a5f3a91e3895cbba0a583386e93366b7 (diff)
Fix problem with exception reporting in QFuture::waitForResult()
This fixes a problem that occurs when a task, that is run synchronously, throws an exception. If that happened, then the exception would not be re-thrown, because of an early return. Task-number: QTBUG-54831 Change-Id: Ic70c5b810ec6adce6e62bfd6832ba9f170b13a7f Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com>
-rw-r--r--src/corelib/thread/qfutureinterface.cpp11
-rw-r--r--tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp37
2 files changed, 42 insertions, 6 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index 60155c96fd..2fe038165b 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -299,12 +299,11 @@ void QFutureInterfaceBase::waitForResult(int resultIndex)
lock.relock();
- if (!(d->state & Running))
- return;
-
- const int waitIndex = (resultIndex == -1) ? INT_MAX : resultIndex;
- while ((d->state & Running) && d->internal_isResultReadyAt(waitIndex) == false)
- d->waitCondition.wait(&d->m_mutex);
+ if (d->state & Running) {
+ const int waitIndex = (resultIndex == -1) ? INT_MAX : resultIndex;
+ while ((d->state & Running) && d->internal_isResultReadyAt(waitIndex) == false)
+ d->waitCondition.wait(&d->m_mutex);
+ }
d->m_exceptionStore.throwPossibleException();
}
diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
index 8ffe4d8dfe..7e057f3bcf 100644
--- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
+++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp
@@ -440,6 +440,19 @@ int throwFunctionReturn()
return 0;
}
+class SlowTask : public QRunnable
+{
+public:
+ static QAtomicInt cancel;
+ void run() Q_DECL_OVERRIDE {
+ int iter = 60;
+ while (--iter && !cancel.load())
+ QThread::currentThread()->msleep(25);
+ }
+};
+
+QAtomicInt SlowTask::cancel;
+
void tst_QtConcurrentRun::exceptions()
{
QThreadPool pool;
@@ -480,6 +493,30 @@ void tst_QtConcurrentRun::exceptions()
}
if (!caught)
QFAIL("did not get exception");
+
+ caught = false;
+ try {
+ QtConcurrent::run(&pool, throwFunctionReturn).result();
+ } catch (QException &) {
+ caught = true;
+ }
+ QVERIFY2(caught, "did not get exception");
+
+ // Force the task to be run on this thread.
+ caught = false;
+ QThreadPool shortPool;
+ shortPool.setMaxThreadCount(1);
+ SlowTask *st = new SlowTask();
+ try {
+ shortPool.start(st);
+ QtConcurrent::run(&shortPool, throwFunctionReturn).result();
+ } catch (QException &) {
+ caught = true;
+ }
+
+ SlowTask::cancel.store(true);
+
+ QVERIFY2(caught, "did not get exception");
}
#endif