diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2013-09-19 10:16:14 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-21 18:39:13 +0200 |
commit | 6611f04879f226d1a90c49e6e11a1e5a897246ad (patch) | |
tree | 52b63495018a814fba8774b3c46862df55248d0d /src/corelib/thread | |
parent | 4cebef621bb108c76f3cc8bfd0fdf77174b6499d (diff) | |
download | qtbase-6611f04879f226d1a90c49e6e11a1e5a897246ad.tar.gz |
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>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qfutureinterface.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
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 |