From 6611f04879f226d1a90c49e6e11a1e5a897246ad Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 19 Sep 2013 10:16:14 +0200 Subject: 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 --- src/corelib/thread/qfutureinterface.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src/corelib/thread') diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 2a79a501e3..ee3d113196 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -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 -- cgit v1.2.1