QFutureInterface: wrap a pair of {release,reserve}Thread() calls with RAII

Rationale: a wait on a condition-variable is usually a cancellation point.
On Posix, and probably in C++ at some point, a thread cancellation is
done by (a kind of) exception unwinding the stack. To ensure that
we call reserveThread() in all cases, wrap the function pair in a RAII
class. Even if we currently don't seem to support exceptions in QtCore,
this is low-hanging fruit, and no worse than what we had before.

Change-Id: Ifb0f428ea50f9ac12be14e620615f46e00d3dd91
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
This commit is contained in:
Marc Mutz 2013-09-19 10:16:14 +02:00 committed by The Qt Project
parent 4cebef621b
commit 6611f04879

View File

@ -57,6 +57,19 @@ enum {
MaxProgressEmitsPerSecond = 25
};
namespace {
class ThreadPoolThreadReleaser {
QThreadPool *m_pool;
public:
explicit ThreadPoolThreadReleaser(QThreadPool *pool)
: m_pool(pool)
{ if (pool) pool->releaseThread(); }
~ThreadPoolThreadReleaser()
{ if (m_pool) m_pool->reserveThread(); }
};
} // unnamed namespace
QFutureInterfaceBase::QFutureInterfaceBase(State initialState)
: d(new QFutureInterfaceBasePrivate(initialState))
{ }
@ -182,11 +195,9 @@ void QFutureInterfaceBase::waitForResume()
return;
// decrease active thread count since this thread will wait.
QThreadPool::globalInstance()->releaseThread();
const ThreadPoolThreadReleaser releaser(QThreadPool::globalInstance());
d->pausedWaitCondition.wait(&d->m_mutex);
QThreadPool::globalInstance()->reserveThread();
}
int QFutureInterfaceBase::progressValue() const