diff --git a/src/collection/collection.cpp b/src/collection/collection.cpp index cda004092..d13ca5dc1 100644 --- a/src/collection/collection.cpp +++ b/src/collection/collection.cpp @@ -80,7 +80,7 @@ SCollection::SCollection(Application *app, QObject *parent) SCollection::~SCollection() { if (watcher_) { - watcher_->Stop(); + watcher_->Abort(); watcher_->deleteLater(); } if (watcher_thread_) { @@ -159,7 +159,7 @@ void SCollection::IncrementalScan() { watcher_->IncrementalScanAsync(); } void SCollection::FullScan() { watcher_->FullScanAsync(); } -void SCollection::AbortScan() { watcher_->Stop(); } +void SCollection::StopScan() { watcher_->Stop(); } void SCollection::Rescan(const SongList &songs) { diff --git a/src/collection/collection.h b/src/collection/collection.h index 52e975c61..62db686cb 100644 --- a/src/collection/collection.h +++ b/src/collection/collection.h @@ -71,7 +71,7 @@ class SCollection : public QObject { void ResumeWatcher(); void FullScan(); - void AbortScan(); + void StopScan(); void Rescan(const SongList &songs); void IncrementalScan(); diff --git a/src/collection/collectionwatcher.cpp b/src/collection/collectionwatcher.cpp index d0f4420d7..46a50fdd4 100644 --- a/src/collection/collectionwatcher.cpp +++ b/src/collection/collectionwatcher.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "core/filesystemwatcherinterface.h" @@ -135,13 +136,54 @@ void CollectionWatcher::Exit() { Q_ASSERT(QThread::currentThread() == thread()); - Stop(); + Abort(); if (backend_) backend_->Close(); moveToThread(original_thread_); emit ExitFinished(); } +void CollectionWatcher::Stop() { + + QMutexLocker l(&mutex_stop_); + stop_requested_ = true; + +} + +void CollectionWatcher::CancelStop() { + + QMutexLocker l(&mutex_stop_); + stop_requested_ = false; + +} + +bool CollectionWatcher::stop_requested() const { + + QMutexLocker l(&mutex_stop_); + return stop_requested_; + +} + +void CollectionWatcher::Abort() { + + QMutexLocker l(&mutex_abort_); + abort_requested_ = true; + +} + +bool CollectionWatcher::abort_requested() const { + + QMutexLocker l(&mutex_abort_); + return abort_requested_; + +} + +bool CollectionWatcher::stop_or_abort_requested() const { + + return stop_requested() || abort_requested(); + +} + void CollectionWatcher::ReloadSettingsAsync() { QMetaObject::invokeMethod(this, &CollectionWatcher::ReloadSettings, Qt::QueuedConnection); @@ -230,7 +272,7 @@ CollectionWatcher::ScanTransaction::ScanTransaction(CollectionWatcher *watcher, CollectionWatcher::ScanTransaction::~ScanTransaction() { // If we're stopping then don't commit the transaction - if (!watcher_->stop_requested_ && !watcher_->abort_requested_) { + if (!watcher_->stop_or_abort_requested()) { CommitNewOrUpdatedSongs(); } @@ -407,7 +449,7 @@ CollectionSubdirectoryList CollectionWatcher::ScanTransaction::GetAllSubdirs() { void CollectionWatcher::AddDirectory(const CollectionDirectory &dir, const CollectionSubdirectoryList &subdirs) { - stop_requested_ = false; + CancelStop(); watched_dirs_[dir.id] = dir; @@ -434,10 +476,10 @@ void CollectionWatcher::AddDirectory(const CollectionDirectory &dir, const Colle transaction.SetKnownSubdirs(subdirs); transaction.AddToProgressMax(files_count); for (const CollectionSubdirectory &subdir : subdirs) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; ScanSubdirectory(subdir.path, subdir, subdir_files_count[subdir.path], &transaction); } - if (!stop_requested_ && !abort_requested_) { + if (!stop_or_abort_requested()) { last_scan_time_ = QDateTime::currentSecsSinceEpoch(); } } @@ -497,7 +539,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); while (it.hasNext()) { - if (stop_requested_ || abort_requested_) return; + if (stop_or_abort_requested()) return; QString child(it.next()); QFileInfo child_info(child); @@ -532,7 +574,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu } } - if (stop_requested_ || abort_requested_) return; + if (stop_or_abort_requested()) return; // Ask the database for a list of files in this directory SongList songs_in_db = t->FindSongsInSubdirectory(path); @@ -543,7 +585,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu QStringList files_on_disk_copy = files_on_disk; for (const QString &file : files_on_disk_copy) { - if (stop_requested_ || abort_requested_) return; + if (stop_or_abort_requested()) return; // Associated CUE QString new_cue = CueParser::FindCueFilename(file); @@ -745,7 +787,7 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu // Recurse into the new subdirs that we found for (const CollectionSubdirectory &my_new_subdir : std::as_const(my_new_subdirs)) { - if (stop_requested_ || abort_requested_) return; + if (stop_or_abort_requested()) return; ScanSubdirectory(my_new_subdir.path, my_new_subdir, 0, t, true); } @@ -1086,7 +1128,7 @@ void CollectionWatcher::RescanPathsNow() { const QList dirs = rescan_queue_.keys(); for (const int dir : dirs) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; ScanTransaction transaction(this, dir, false, false, mark_songs_unavailable_); const QStringList paths = rescan_queue_[dir]; @@ -1099,7 +1141,7 @@ void CollectionWatcher::RescanPathsNow() { } for (const QString &path : paths) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; CollectionSubdirectory subdir; subdir.directory_id = dir; subdir.mtime = 0; @@ -1144,7 +1186,7 @@ QString CollectionWatcher::PickBestArt(const QStringList &art_automatic_list) { QString biggest_path; for (const QString &path : std::as_const(filtered)) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; QImage image(path); if (image.isNull()) continue; @@ -1220,11 +1262,11 @@ void CollectionWatcher::FullScanNow() { PerformScan(false, true); } void CollectionWatcher::PerformScan(const bool incremental, const bool ignore_mtimes) { - stop_requested_ = false; + CancelStop(); for (const CollectionDirectory &dir : std::as_const(watched_dirs_)) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; ScanTransaction transaction(this, dir.id, incremental, ignore_mtimes, mark_songs_unavailable_); CollectionSubdirectoryList subdirs = transaction.GetAllSubdirs(); @@ -1242,7 +1284,7 @@ void CollectionWatcher::PerformScan(const bool incremental, const bool ignore_mt transaction.AddToProgressMax(files_count); for (const CollectionSubdirectory &subdir : std::as_const(subdirs)) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; ScanSubdirectory(subdir.path, subdir, subdir_files_count[subdir.path], &transaction); } @@ -1260,7 +1302,7 @@ quint64 CollectionWatcher::FilesCountForPath(ScanTransaction *t, const QString & QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); while (it.hasNext()) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; QString child = it.next(); QFileInfo path_info(child); @@ -1294,7 +1336,7 @@ quint64 CollectionWatcher::FilesCountForSubdirs(ScanTransaction *t, const Collec quint64 i = 0; for (const CollectionSubdirectory &subdir : subdirs) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; const quint64 files_count = FilesCountForPath(t, subdir.path); subdir_files_count[subdir.path] = files_count; i += files_count; @@ -1312,17 +1354,17 @@ void CollectionWatcher::RescanSongsAsync(const SongList &songs) { void CollectionWatcher::RescanSongs(const SongList &songs) { - stop_requested_ = false; + CancelStop(); QStringList scanned_paths; for (const Song &song : songs) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; const QString song_path = song.url().toLocalFile().section(QLatin1Char('/'), 0, -2); if (scanned_paths.contains(song_path)) continue; ScanTransaction transaction(this, song.directory_id(), false, true, mark_songs_unavailable_); const CollectionSubdirectoryList subdirs = transaction.GetAllSubdirs(); for (const CollectionSubdirectory &subdir : subdirs) { - if (stop_requested_ || abort_requested_) break; + if (stop_or_abort_requested()) break; if (subdir.path != song_path) continue; qLog(Debug) << "Rescan for directory ID" << song.directory_id() << "directory" << subdir.path; quint64 files_count = FilesCountForPath(&transaction, subdir.path); diff --git a/src/collection/collectionwatcher.h b/src/collection/collectionwatcher.h index d276456f1..6cc41c6b0 100644 --- a/src/collection/collectionwatcher.h +++ b/src/collection/collectionwatcher.h @@ -33,6 +33,7 @@ #include #include #include +#include #include "collectiondirectory.h" #include "core/shared_ptr.h" @@ -64,8 +65,9 @@ class CollectionWatcher : public QObject { void SetRescanPausedAsync(const bool pause); void ReloadSettingsAsync(); - void Stop() { stop_requested_ = true; } - void Abort() { abort_requested_ = true; } + void Stop(); + void CancelStop(); + void Abort(); void ExitAsync(); @@ -178,6 +180,9 @@ class CollectionWatcher : public QObject { void RescanSongs(const SongList &songs); private: + bool stop_requested() const; + bool abort_requested() const; + bool stop_or_abort_requested() const; static bool FindSongsByPath(const SongList &songs, const QString &path, SongList *out); bool FindSongsByFingerprint(const QString &file, const QString &fingerprint, SongList *out); static bool FindSongsByFingerprint(const QString &file, const SongList &songs, const QString &fingerprint, SongList *out); @@ -231,7 +236,10 @@ class CollectionWatcher : public QObject { bool overwrite_playcount_; bool overwrite_rating_; + mutable QMutex mutex_stop_; bool stop_requested_; + + mutable QMutex mutex_abort_; bool abort_requested_; QMap watched_dirs_; diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index fd939ad8b..cbec27867 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -490,7 +490,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS ui_->action_transcoder->setIcon(IconLoader::Load(QStringLiteral("tools-wizard"))); ui_->action_update_collection->setIcon(IconLoader::Load(QStringLiteral("view-refresh"))); ui_->action_full_collection_scan->setIcon(IconLoader::Load(QStringLiteral("view-refresh"))); - ui_->action_abort_collection_scan->setIcon(IconLoader::Load(QStringLiteral("dialog-error"))); + ui_->action_stop_collection_scan->setIcon(IconLoader::Load(QStringLiteral("dialog-error"))); ui_->action_settings->setIcon(IconLoader::Load(QStringLiteral("configure"))); ui_->action_import_data_from_last_fm->setIcon(IconLoader::Load(QStringLiteral("scrobble"))); ui_->action_console->setIcon(IconLoader::Load(QStringLiteral("keyboard"))); @@ -556,7 +556,7 @@ MainWindow::MainWindow(Application *app, SharedPtr tray_icon, OS QObject::connect(ui_->action_jump, &QAction::triggered, ui_->playlist->view(), &PlaylistView::JumpToCurrentlyPlayingTrack); QObject::connect(ui_->action_update_collection, &QAction::triggered, &*app_->collection(), &SCollection::IncrementalScan); QObject::connect(ui_->action_full_collection_scan, &QAction::triggered, &*app_->collection(), &SCollection::FullScan); - QObject::connect(ui_->action_abort_collection_scan, &QAction::triggered, &*app_->collection(), &SCollection::AbortScan); + QObject::connect(ui_->action_stop_collection_scan, &QAction::triggered, &*app_->collection(), &SCollection::StopScan); #if defined(HAVE_GSTREAMER) QObject::connect(ui_->action_add_files_to_transcoder, &QAction::triggered, this, &MainWindow::AddFilesToTranscoder); ui_->action_add_files_to_transcoder->setIcon(IconLoader::Load(QStringLiteral("tools-wizard"))); diff --git a/src/core/mainwindow.ui b/src/core/mainwindow.ui index 826fdbe2d..345af71af 100644 --- a/src/core/mainwindow.ui +++ b/src/core/mainwindow.ui @@ -37,7 +37,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -77,7 +77,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -102,7 +102,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame @@ -167,7 +167,7 @@ - QToolButton::MenuButtonPopup + QToolButton::ToolButtonPopupMode::MenuButtonPopup true @@ -211,7 +211,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -237,7 +237,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -260,10 +260,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -276,7 +276,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -292,7 +292,7 @@ 100 - Qt::Horizontal + Qt::Orientation::Horizontal @@ -326,7 +326,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -380,7 +380,7 @@ - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter @@ -391,7 +391,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -401,7 +401,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -524,7 +524,7 @@ - + @@ -580,7 +580,7 @@ Ctrl+Q - QAction::QuitRole + QAction::MenuRole::QuitRole @@ -644,7 +644,7 @@ Ctrl+P - QAction::PreferencesRole + QAction::MenuRole::PreferencesRole @@ -659,7 +659,7 @@ F1 - QAction::AboutRole + QAction::MenuRole::AboutRole @@ -785,7 +785,7 @@ About &Qt - QAction::AboutQtRole + QAction::MenuRole::AboutQtRole @@ -804,9 +804,12 @@ &Do a full collection rescan - + - Abort collection scan + Stop collection scan + + + Stop collection scan diff --git a/src/device/filesystemdevice.cpp b/src/device/filesystemdevice.cpp index 16f717e6b..1ec26b790 100644 --- a/src/device/filesystemdevice.cpp +++ b/src/device/filesystemdevice.cpp @@ -70,7 +70,7 @@ FilesystemDevice::FilesystemDevice(const QUrl &url, DeviceLister *lister, const FilesystemDevice::~FilesystemDevice() { - watcher_->Stop(); + watcher_->Abort(); watcher_->deleteLater(); watcher_thread_->exit(); watcher_thread_->wait();