summaryrefslogtreecommitdiff
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2013-09-19 10:16:14 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-21 18:39:13 +0200
commit6611f04879f226d1a90c49e6e11a1e5a897246ad (patch)
tree52b63495018a814fba8774b3c46862df55248d0d /src/corelib/thread
parent4cebef621bb108c76f3cc8bfd0fdf77174b6499d (diff)
downloadqtbase-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.cpp17
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