Merge pull request #6299 from jbroadus/fix-threading-issues

Fix threading issues
This commit is contained in:
John Maguire 2019-03-03 16:22:39 +00:00 committed by GitHub
commit efdd65b8f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 8 deletions

View File

@ -58,14 +58,9 @@ void DeviceInfo::InitFromDb(const DeviceDatabaseBackend::Device& dev) {
size_ = dev.size_;
transcode_mode_ = dev.transcode_mode_;
transcode_format_ = dev.transcode_format_;
QStringList icon_names = dev.icon_name_.split(',');
QVariantList icons;
for (const QString& icon_name : icon_names) {
icons << icon_name;
}
LoadIcon(icons, friendly_name_);
// Store the raw value for now. If it's a comma delimited list, it will be
// sorted out later.
icon_name_ = dev.icon_name_;
QStringList unique_ids = dev.unique_id_.split(',');
for (const QString& id : unique_ids) {

View File

@ -83,6 +83,8 @@ DeviceManager::DeviceManager(Application* app, QObject* parent)
backend_->moveToThread(app_->database()->thread());
backend_->Init(app_->database());
connect(this, SIGNAL(DeviceCreatedFromDb(DeviceInfo*)),
SLOT(AddDeviceFromDb(DeviceInfo*)));
// This reads from the database and contends on the database mutex, which can
// be very slow on startup.
ConcurrentRun::Run<void>(&thread_pool_,
@ -140,7 +142,34 @@ void DeviceManager::LoadAllDevices() {
for (const DeviceDatabaseBackend::Device& device : devices) {
DeviceInfo* info = new DeviceInfo(DeviceInfo::Type_Device, root_);
info->InitFromDb(device);
// Use of QPixMap and device insertion should only be done on the main
// thread. Send a signal to finish the device addition.
emit DeviceCreatedFromDb(info);
}
}
void DeviceManager::AddDeviceFromDb(DeviceInfo* info) {
// At this point, icon_name_ contains the value from the database where the
// value is allowed to be a comma delimited list.
QStringList icon_names = info->icon_name_.split(',');
QVariantList icons;
for (const QString& icon_name : icon_names) {
icons << icon_name;
}
info->LoadIcon(icons, info->friendly_name_);
DeviceInfo* existing = FindEquivalentDevice(info);
if (existing) {
qLog(Info) << "Found existing device: " << info->friendly_name_;
// Update user configuration from the database.
existing->icon_name_ = info->icon_name_;
existing->icon_ = info->icon_;
QModelIndex idx = ItemToIndex(existing);
if (idx.isValid()) emit dataChanged(idx, idx);
// Discard the info loaded from the database.
delete info;
} else {
qLog(Info) << "Device added from database: " << info->friendly_name_;
beginInsertRows(ItemToIndex(root_), devices_.count(), devices_.count());
devices_ << info;
endInsertRows();
@ -312,6 +341,14 @@ DeviceInfo* DeviceManager::FindDeviceByUrl(const QList<QUrl>& urls) const {
return nullptr;
}
DeviceInfo* DeviceManager::FindEquivalentDevice(DeviceInfo* info) const {
for (const DeviceInfo::Backend& backend : info->backends_) {
DeviceInfo* match = FindDeviceById(backend.unique_id_);
if (match) return match;
}
return nullptr;
}
void DeviceManager::PhysicalDeviceAdded(const QString& id) {
DeviceLister* lister = qobject_cast<DeviceLister*>(sender());

View File

@ -79,6 +79,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
DeviceInfo* FindDeviceById(const QString& id) const;
DeviceInfo* FindDeviceByUrl(const QList<QUrl>& url) const;
DeviceInfo* FindEquivalentDevice(DeviceInfo* info) const;
// Actions on devices
std::shared_ptr<ConnectedDevice> Connect(DeviceInfo* info);
@ -101,6 +102,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
signals:
void DeviceConnected(QModelIndex idx);
void DeviceDisconnected(QModelIndex idx);
void DeviceCreatedFromDb(DeviceInfo* info);
private slots:
void PhysicalDeviceAdded(const QString& id);
@ -111,6 +113,7 @@ class DeviceManager : public SimpleTreeModel<DeviceInfo> {
void DeviceSongCountUpdated(int count);
void LoadAllDevices();
void DeviceConnectFinished(const QString& id, bool success);
void AddDeviceFromDb(DeviceInfo* info);
protected:
void LazyPopulate(DeviceInfo* item) { LazyPopulate(item, true); }