From c7d351f68ad65c78f035e8608952394d6d5b586e Mon Sep 17 00:00:00 2001 From: David Sansome Date: Wed, 2 Jun 2010 14:22:40 +0000 Subject: [PATCH] Make it possible to wait for a background thread to start --- src/core/backgroundthread.cpp | 18 ++++++++++++++++++ src/core/backgroundthread.h | 21 ++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/core/backgroundthread.cpp b/src/core/backgroundthread.cpp index 9c4193720..bdb2aa531 100644 --- a/src/core/backgroundthread.cpp +++ b/src/core/backgroundthread.cpp @@ -35,3 +35,21 @@ int BackgroundThreadBase::gettid() { return 0; #endif } + +void BackgroundThreadBase::Start(bool block) { + if (!block) { + // Just start the thread and return immediately + QThread::start(cpu_priority_); + return; + } + + // Lock the mutex so the new thread won't try to wake us up before we start + // waiting. + QMutexLocker l(&started_wait_condition_mutex_); + + // Start the thread. + QThread::start(cpu_priority_); + + // Wait for the thread to initalise. + started_wait_condition_.wait(l.mutex()); +} diff --git a/src/core/backgroundthread.h b/src/core/backgroundthread.h index 4312578fa..3a032cfb7 100644 --- a/src/core/backgroundthread.h +++ b/src/core/backgroundthread.h @@ -19,6 +19,8 @@ #include #include +#include +#include #include @@ -67,7 +69,7 @@ class BackgroundThreadBase : public QThread { void set_io_priority(IoPriority priority) { io_priority_ = priority; } void set_cpu_priority(QThread::Priority priority) { cpu_priority_ = priority; } - virtual void Start() { QThread::start(cpu_priority_); } + virtual void Start(bool block = false); signals: void Initialised(); @@ -85,6 +87,9 @@ class BackgroundThreadBase : public QThread { IoPriority io_priority_; QThread::Priority cpu_priority_; + + QWaitCondition started_wait_condition_; + QMutex started_wait_condition_mutex_; }; // This is the templated class that stores and returns the worker object. @@ -161,14 +166,20 @@ BackgroundThreadImplementation:: template void BackgroundThreadImplementation::run() { - BackgroundThreadBase::SetIOPriority(); + this->SetIOPriority(); - BackgroundThread::worker_.reset(new DerivedType); + this->worker_.reset(new DerivedType); - emit BackgroundThreadBase::Initialised(); + { + // Tell the calling thread that we've initialised the worker. + QMutexLocker l(&this->started_wait_condition_mutex_); + this->started_wait_condition_.wakeAll(); + } + + emit this->Initialised(); QThread::exec(); - BackgroundThread::worker_.reset(); + this->worker_.reset(); }