Fix crashes in devices

This commit is contained in:
Jonas Kvinge
2019-01-05 23:11:16 +01:00
parent d5fffc3641
commit a06de35aa5
9 changed files with 44 additions and 19 deletions

View File

@@ -68,7 +68,9 @@ ConnectedDevice::ConnectedDevice(const QUrl &url, DeviceLister *lister, const QS
} }
ConnectedDevice::~ConnectedDevice() { backend_->deleteLater(); } ConnectedDevice::~ConnectedDevice() {
backend_->deleteLater();
}
void ConnectedDevice::InitBackendDirectory(const QString &mount_point, bool first_time, bool rewrite_path) { void ConnectedDevice::InitBackendDirectory(const QString &mount_point, bool first_time, bool rewrite_path) {

View File

@@ -35,6 +35,8 @@
#include "devicelister.h" #include "devicelister.h"
#include "core/logging.h"
DeviceLister::DeviceLister() : thread_(nullptr) {} DeviceLister::DeviceLister() : thread_(nullptr) {}
DeviceLister::~DeviceLister() { DeviceLister::~DeviceLister() {

View File

@@ -75,7 +75,7 @@ class DeviceLister : public QObject {
virtual void UpdateDeviceFreeSpace(const QString &id) = 0; virtual void UpdateDeviceFreeSpace(const QString &id) = 0;
virtual void ShutDown() {} virtual void ShutDown() {}
signals: signals:
void DeviceAdded(const QString &id); void DeviceAdded(const QString &id);
void DeviceRemoved(const QString &id); void DeviceRemoved(const QString &id);
void DeviceChanged(const QString &id); void DeviceChanged(const QString &id);

View File

@@ -108,7 +108,7 @@ DeviceManager::DeviceManager(Application *app, QObject *parent)
backend_->moveToThread(app_->database()->thread()); backend_->moveToThread(app_->database()->thread());
backend_->Init(app_->database()); backend_->Init(app_->database());
// This reads from the database and contends on the database mutex, which can be very slow on startup. // This reads from the database and contents on the database mutex, which can be very slow on startup.
ConcurrentRun::Run<void>(&thread_pool_, bind(&DeviceManager::LoadAllDevices, this)); ConcurrentRun::Run<void>(&thread_pool_, bind(&DeviceManager::LoadAllDevices, this));
// This proxy model only shows connected devices // This proxy model only shows connected devices
@@ -179,13 +179,14 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
if (!index.isValid() || index.column() != 0) return QVariant(); if (!index.isValid() || index.column() != 0) return QVariant();
const DeviceInfo *info = IndexToItem(index); const DeviceInfo *info = IndexToItem(index);
if (!info) return QVariant();
switch (role) { switch (role) {
case Qt::DisplayRole: { case Qt::DisplayRole: {
QString text; QString text;
if (!info->friendly_name_.isEmpty()) if (!info->friendly_name_.isEmpty())
text = info->friendly_name_; text = info->friendly_name_;
else else if (info->BestBackend())
text = info->BestBackend()->unique_id_; text = info->BestBackend()->unique_id_;
if (info->size_) if (info->size_)
@@ -210,6 +211,7 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
return info->friendly_name_; return info->friendly_name_;
case Role_UniqueId: case Role_UniqueId:
if (!info->BestBackend()) return QString();
return info->BestBackend()->unique_id_; return info->BestBackend()->unique_id_;
case Role_IconName: case Role_IconName:
@@ -221,11 +223,11 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
case Role_FreeSpace: case Role_FreeSpace:
case MusicStorage::Role_FreeSpace: case MusicStorage::Role_FreeSpace:
return info->BestBackend()->lister_ ? info->BestBackend()->lister_->DeviceFreeSpace(info->BestBackend()->unique_id_) : QVariant(); return ((info->BestBackend() && info->BestBackend()->lister_) ? info->BestBackend()->lister_->DeviceFreeSpace(info->BestBackend()->unique_id_) : QVariant());
case Role_State: case Role_State:
if (info->device_) return State_Connected; if (info->device_) return State_Connected;
if (info->BestBackend()->lister_) { if (info->BestBackend() && info->BestBackend()->lister_) {
if (info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) return State_NotMounted; if (info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) return State_NotMounted;
return State_NotConnected; return State_NotConnected;
} }
@@ -243,9 +245,9 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
case MusicStorage::Role_StorageForceConnect: case MusicStorage::Role_StorageForceConnect:
if (!info->device_) { if (!info->device_) {
if (info->database_id_ == -1 && !info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) { if (info->database_id_ == -1 && info->BestBackend() && !info->BestBackend()->lister_->DeviceNeedsMount(info->BestBackend()->unique_id_)) {
if (info->BestBackend()->lister_->AskForScan(info->BestBackend()->unique_id_)) { if (info->BestBackend() && info->BestBackend()->lister_->AskForScan(info->BestBackend()->unique_id_)) {
std::unique_ptr<QMessageBox> dialog(new QMessageBox(QMessageBox::Information, tr("Connect device"), tr("This is the first time you have connected this device. Strawberry will now scan the device to find music files - this may take some time."), QMessageBox::Cancel)); std::unique_ptr<QMessageBox> dialog(new QMessageBox(QMessageBox::Information, tr("Connect device"), tr("This is the first time you have connected this device. Strawberry will now scan the device to find music files - this may take some time."), QMessageBox::Cancel));
QPushButton *connect = dialog->addButton(tr("Connect device"), QMessageBox::AcceptRole); QPushButton *connect = dialog->addButton(tr("Connect device"), QMessageBox::AcceptRole);
dialog->exec(); dialog->exec();
@@ -282,6 +284,7 @@ QVariant DeviceManager::data(const QModelIndex &index, int role) const {
default: default:
return QVariant(); return QVariant();
} }
} }
void DeviceManager::AddLister(DeviceLister *lister) { void DeviceManager::AddLister(DeviceLister *lister) {
@@ -329,8 +332,9 @@ int DeviceManager::FindDeviceByUrl(const QList<QUrl> &urls) const {
void DeviceManager::PhysicalDeviceAdded(const QString &id) { void DeviceManager::PhysicalDeviceAdded(const QString &id) {
DeviceLister *lister = qobject_cast<DeviceLister*>(sender()); DeviceLister *lister = qobject_cast<DeviceLister*>(sender());
if (!lister) return;
qLog(Info) << "Device added:" << id; qLog(Info) << "Device added:" << id << lister->DeviceUniqueIDs();
// Do we have this device already? // Do we have this device already?
int i = FindDeviceById(id); int i = FindDeviceById(id);
@@ -562,12 +566,15 @@ DeviceLister *DeviceManager::GetLister(int row) const {
void DeviceManager::Disconnect(int row) { void DeviceManager::Disconnect(int row) {
DeviceInfo *info = devices_[row]; DeviceInfo *info = devices_[row];
if (!info->device_) // Already disconnected if (!info || !info->device_)
return; return;
info->device_.reset(); info->device_.reset();
emit DeviceDisconnected(row); emit DeviceDisconnected(row);
QModelIndex index = ItemToIndex(info); QModelIndex index = ItemToIndex(info);
if (!index.isValid()) return;
emit dataChanged(index, index); emit dataChanged(index, index);
} }
@@ -700,6 +707,8 @@ void DeviceManager::DeviceSongCountUpdated(int count) {
if (row == -1) return; if (row == -1) return;
QModelIndex index = ItemToIndex(devices_[row]); QModelIndex index = ItemToIndex(devices_[row]);
if (!index.isValid()) return;
emit dataChanged(index, index); emit dataChanged(index, index);
} }
@@ -716,8 +725,14 @@ DeviceInfo *DeviceManager::ItemFromRow(int row) {
QString DeviceManager::DeviceNameByID(QString unique_id) { QString DeviceManager::DeviceNameByID(QString unique_id) {
int row = FindDeviceById(unique_id); int row = FindDeviceById(unique_id);
if (row == -1) return QString();
DeviceInfo *info = devices_[row]; DeviceInfo *info = devices_[row];
if (!info) return QString();
QModelIndex index = ItemToIndex(info); QModelIndex index = ItemToIndex(info);
if (!index.isValid()) return QString();
return data(index, DeviceManager::Role_FriendlyName).toString(); return data(index, DeviceManager::Role_FriendlyName).toString();
} }

View File

@@ -324,6 +324,7 @@ void DeviceView::DeviceConnected(int row) {
void DeviceView::DeviceDisconnected(int row) { void DeviceView::DeviceDisconnected(int row) {
DeviceInfo *info = app_->device_manager()->ItemFromRow(row); DeviceInfo *info = app_->device_manager()->ItemFromRow(row);
if (!info) return;
QModelIndex index = app_->device_manager()->ItemToIndex(info); QModelIndex index = app_->device_manager()->ItemToIndex(info);
merged_model_->RemoveSubModel(sort_model_->mapFromSource(index)); merged_model_->RemoveSubModel(sort_model_->mapFromSource(index));
} }

View File

@@ -26,6 +26,8 @@
#include <QUrl> #include <QUrl>
#include "core/application.h" #include "core/application.h"
#include "core/logging.h"
#include "collection/collectionbackend.h" #include "collection/collectionbackend.h"
#include "collection/collectionmodel.h" #include "collection/collectionmodel.h"
#include "collection/collectionwatcher.h" #include "collection/collectionwatcher.h"
@@ -42,6 +44,7 @@ FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const
watcher_->moveToThread(watcher_thread_); watcher_->moveToThread(watcher_thread_);
watcher_thread_->start(QThread::IdlePriority); watcher_thread_->start(QThread::IdlePriority);
qLog(Debug) << __PRETTY_FUNCTION__ << unique_id;
watcher_->set_device_name(manager->DeviceNameByID(unique_id)); watcher_->set_device_name(manager->DeviceNameByID(unique_id));
watcher_->set_backend(backend_); watcher_->set_backend(backend_);
watcher_->set_task_manager(app_->task_manager()); watcher_->set_task_manager(app_->task_manager());

View File

@@ -62,11 +62,7 @@ bool GioLister::DeviceInfo::is_suitable() const {
if (filesystem_type.isEmpty()) return true; if (filesystem_type.isEmpty()) return true;
return filesystem_type != "udf" && return filesystem_type != "udf" && filesystem_type != "smb" && filesystem_type != "cifs" && filesystem_type != "ssh" && filesystem_type != "isofs";
filesystem_type != "smb" &&
filesystem_type != "cifs" &&
filesystem_type != "ssh" &&
filesystem_type != "isofs";
} }
@@ -336,9 +332,8 @@ void GioLister::MountAdded(GMount *mount) {
if (!old_id.isEmpty()) if (!old_id.isEmpty())
emit DeviceChanged(old_id); emit DeviceChanged(old_id);
else { else
emit DeviceAdded(info.unique_id()); emit DeviceAdded(info.unique_id());
}
} }
@@ -527,6 +522,7 @@ void GioLister::UnmountDevice(const QString &id) {
return; return;
} }
} }
else return;
if (g_mount_can_eject(info.mount)) { if (g_mount_can_eject(info.mount)) {
g_mount_eject_with_operation(info.mount, G_MOUNT_UNMOUNT_NONE, nullptr, nullptr, (GAsyncReadyCallback)MountEjectFinished, nullptr); g_mount_eject_with_operation(info.mount, G_MOUNT_UNMOUNT_NONE, nullptr, nullptr, (GAsyncReadyCallback)MountEjectFinished, nullptr);

View File

@@ -77,6 +77,13 @@ void GPodDevice::LoadFinished(Itdb_iTunesDB *db) {
db_ = db; db_ = db;
db_wait_cond_.wakeAll(); db_wait_cond_.wakeAll();
if (loader_thread_) {
loader_thread_->quit();
loader_thread_->wait(1000);
loader_thread_->deleteLater();
loader_thread_ = nullptr;
}
loader_->deleteLater(); loader_->deleteLater();
loader_ = nullptr; loader_ = nullptr;

View File

@@ -120,8 +120,7 @@ QString Udisks2Lister::MakeFriendlyName(const QString &id) {
QList<QUrl> Udisks2Lister::MakeDeviceUrls(const QString &id) { QList<QUrl> Udisks2Lister::MakeDeviceUrls(const QString &id) {
QReadLocker locker(&device_data_lock_); QReadLocker locker(&device_data_lock_);
if (!device_data_.contains(id)) return QList<QUrl>(); if (!device_data_.contains(id)) return QList<QUrl>();
return QList<QUrl>() << QUrl::fromLocalFile( return QList<QUrl>() << QUrl::fromLocalFile(device_data_[id].mount_paths.at(0));
device_data_[id].mount_paths.at(0));
} }
void Udisks2Lister::UnmountDevice(const QString &id) { void Udisks2Lister::UnmountDevice(const QString &id) {