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>
This commit is contained in:
Christian Strømme 2016-08-18 11:44:45 +02:00 committed by Christian Stromme
parent 449390c3a5
commit 5e3f770ad5
2 changed files with 42 additions and 6 deletions

View File

@ -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();
}

View File

@ -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