Move loading of devices from the database onto a different thread.

This commit is contained in:
John Maguire 2012-06-29 16:56:17 +02:00
parent 70429217c6
commit 58a3a6831a
5 changed files with 52 additions and 6 deletions

View File

@ -5,6 +5,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src)
set(SOURCES
core/closure.cpp
core/concurrentrun.cpp
core/encoding.cpp
core/logging.cpp
core/messagehandler.cpp

View File

@ -0,0 +1,11 @@
#include "concurrentrun.h"
namespace ConcurrentRun {
void Run(
QThreadPool* threadpool,
std::tr1::function<void ()> function) {
(new ThreadFunctorVoid(function))->Start(threadpool);
}
} // namespace ConcurrentRun

View File

@ -72,6 +72,22 @@ class ThreadFunctorBase : public QFutureInterface<ReturnType>, public QRunnable
ReturnType result_;
};
// Use bool as a placeholder result.
class ThreadFunctorVoid : public ThreadFunctorBase<bool> {
public:
ThreadFunctorVoid(std::tr1::function<void ()> function)
: function_(function)
{ }
void run() {
function_();
ThreadFunctorBase<bool>::End();
}
private:
std::tr1::function<void ()> function_;
};
template<typename ReturnType, typename Arg>
class ThreadFunctor1 : public ThreadFunctorBase<ReturnType> {
public:
@ -113,6 +129,9 @@ private:
};
namespace ConcurrentRun {
void Run(
QThreadPool* threadpool,
std::tr1::function<void ()> function);
template<typename ReturnType, typename Arg>
QFuture<ReturnType> Run(

View File

@ -22,6 +22,7 @@
#include "devicestatefiltermodel.h"
#include "filesystemdevice.h"
#include "core/application.h"
#include "core/concurrentrun.h"
#include "core/database.h"
#include "core/logging.h"
#include "core/musicstorage.h"
@ -65,6 +66,9 @@
#include <QSortFilterProxyModel>
#include <QUrl>
#include <tr1/functional>
using std::tr1::bind;
const int DeviceManager::kDeviceIconSize = 32;
const int DeviceManager::kDeviceIconOverlaySize = 16;
@ -179,12 +183,9 @@ DeviceManager::DeviceManager(Application* app, QObject *parent)
backend_->moveToThread(app_->database()->thread());
backend_->Init(app_->database());
DeviceDatabaseBackend::DeviceList devices = backend_->GetAllDevices();
foreach (const DeviceDatabaseBackend::Device& device, devices) {
DeviceInfo info;
info.InitFromDb(device);
devices_ << info;
}
// This reads from the database and contends on the database mutex, which can
// be very slow on startup.
ConcurrentRun::Run(&thread_pool_, bind(&DeviceManager::LoadAllDevices, this));
// This proxy model only shows connected devices
connected_devices_model_ = new DeviceStateFilterModel(this);
@ -236,6 +237,16 @@ DeviceManager::~DeviceManager() {
backend_->deleteLater();
}
void DeviceManager::LoadAllDevices() {
Q_ASSERT(QThread::currentThread() != qApp->thread());
DeviceDatabaseBackend::DeviceList devices = backend_->GetAllDevices();
foreach (const DeviceDatabaseBackend::Device& device, devices) {
DeviceInfo info;
info.InitFromDb(device);
devices_ << info;
}
}
int DeviceManager::rowCount(const QModelIndex&) const {
return devices_.count();
}

View File

@ -23,6 +23,7 @@
#include <QAbstractListModel>
#include <QIcon>
#include <QThreadPool>
#include <boost/shared_ptr.hpp>
@ -104,6 +105,7 @@ private slots:
void DeviceTaskStarted(int id);
void TasksChanged();
void DeviceSongCountUpdated(int count);
void LoadAllDevices();
private:
// Devices can be in three different states:
@ -176,6 +178,8 @@ private:
// Map of task ID to device index
QMap<int, QPersistentModelIndex> active_tasks_;
QThreadPool thread_pool_;
};