From 45de97d8fba46c32ec79e598785f23a95e17da42 Mon Sep 17 00:00:00 2001 From: Albert S Date: Fri, 15 Apr 2022 21:06:19 +0200 Subject: [PATCH] gui: Begin cancellation of Indexer --- gui/mainwindow.cpp | 13 +++++++++++++ gui/mainwindow.h | 1 + shared/concurrentqueue.h | 1 - shared/dirscanworker.cpp | 3 +++ shared/filescanworker.cpp | 9 ++++++++- shared/filescanworker.h | 3 ++- shared/indexer.cpp | 19 +++++++++++++++++-- shared/indexer.h | 6 +++++- shared/paralleldirscanner.cpp | 7 ++++--- 9 files changed, 53 insertions(+), 9 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 7c1ae3a..78b3e3d 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -129,6 +129,16 @@ void MainWindow::spinPreviewPageValueChanged(int val) void MainWindow::startIndexing() { + if(this->indexer->isRunning()) + { + ui->btnStartIndexing->setEnabled(false); + ui->btnStartIndexing->setText("Start indexing"); + this->indexer->requestCancellation(); + return; + } + + ui->previewsTab->setEnabled(false); + ui->resultsTab->setEnabled(false); ui->txtPathScanAdd->setEnabled(false); ui->txtSearch->setEnabled(false); ui->previewProcessBar->setValue(0); @@ -140,6 +150,7 @@ void MainWindow::startIndexing() } this->indexer->setTargetPaths(paths); this->indexer->beginIndexing(); + ui->btnStartIndexing->setText("Stop indexing"); } void MainWindow::finishIndexing() @@ -151,6 +162,8 @@ void MainWindow::finishIndexing() ui->lblFailedValue->setText(QString::number(result.erroredPaths)); ui->lblSkippedValue->setText(QString::number(result.skippedPaths)); ui->lblAddedValue->setText(QString::number(result.addedPaths)); + ui->btnStartIndexing->setEnabled(true); + ui->btnStartIndexing->setText("Start indexing"); } void MainWindow::comboScaleChanged(int i) diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 25449af..1693ac8 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -66,6 +66,7 @@ class MainWindow : public QMainWindow void spinPreviewPageValueChanged(int val); void startIndexing(); void finishIndexing(); + void addPathToIndex(); }; #endif // MAINWINDOW_H diff --git a/shared/concurrentqueue.h b/shared/concurrentqueue.h index 821eb1a..00034db 100644 --- a/shared/concurrentqueue.h +++ b/shared/concurrentqueue.h @@ -3,7 +3,6 @@ #include #include #include - #define QUEUE_SIZE 10000 template class ConcurrentQueue : protected QList { diff --git a/shared/dirscanworker.cpp b/shared/dirscanworker.cpp index 16bb316..1ab97c1 100644 --- a/shared/dirscanworker.cpp +++ b/shared/dirscanworker.cpp @@ -33,6 +33,9 @@ void DirScanWorker::run() { if(this->stopToken->load(std::memory_order_relaxed)) { + Logger::info() << "Received cancel request" << Qt::endl; + this->results.clear(); + emit finished(); return; } diff --git a/shared/filescanworker.cpp b/shared/filescanworker.cpp index a4fb25d..2a23bde 100644 --- a/shared/filescanworker.cpp +++ b/shared/filescanworker.cpp @@ -1,10 +1,12 @@ #include "filescanworker.h" #include "logger.h" -FileScanWorker::FileScanWorker(SqliteDbService &db, ConcurrentQueue &queue, int batchsize) +FileScanWorker::FileScanWorker(SqliteDbService &db, ConcurrentQueue &queue, int batchsize, + std::atomic &stopToken) { this->dbService = &db; this->queue = &queue; this->batchsize = batchsize; + this->stopToken = &stopToken; } void FileScanWorker::run() @@ -24,6 +26,11 @@ void FileScanWorker::run() sfr = PROCESSFAIL; // well... } emit result({path, sfr}); + if(stopToken->load(std::memory_order_relaxed)) // TODO: relaxed should suffice here, but recheck + { + emit finished(); + return; + } } emit finished(); } diff --git a/shared/filescanworker.h b/shared/filescanworker.h index 58ec691..b7559d2 100644 --- a/shared/filescanworker.h +++ b/shared/filescanworker.h @@ -16,9 +16,10 @@ class FileScanWorker : public QObject, public QRunnable SqliteDbService *dbService; ConcurrentQueue *queue; int batchsize; + std::atomic *stopToken; public: - FileScanWorker(SqliteDbService &db, ConcurrentQueue &queue, int batchsize); + FileScanWorker(SqliteDbService &db, ConcurrentQueue &queue, int batchsize, std::atomic &stopToken); void run() override; signals: void result(FileScanResult); diff --git a/shared/indexer.cpp b/shared/indexer.cpp index 3dc49bc..107156b 100644 --- a/shared/indexer.cpp +++ b/shared/indexer.cpp @@ -34,6 +34,7 @@ void Indexer::beginIndexing() this->dirScanner->scan(); + this->workerCancellationToken.store(false, std::memory_order_seq_cst); launchWorker(this->filePathTargetsQueue, this->filePathTargetsQueue.remaining()); } @@ -47,6 +48,12 @@ void Indexer::setTargetPaths(QVector pathsToScan) this->pathsToScan = pathsToScan; } +void Indexer::requestCancellation() +{ + this->dirScanner->cancel(); + this->workerCancellationToken.store(true, std::memory_order_release); +} + IndexResult Indexer::getResult() { return this->currentIndexResult; @@ -55,11 +62,15 @@ IndexResult Indexer::getResult() void Indexer::dirScanFinished() { Logger::info() << "Dir scan finished"; + if(!isRunning()) + { + emit finished(); + } } void Indexer::launchWorker(ConcurrentQueue &queue, int batchsize) { - FileScanWorker *runnable = new FileScanWorker(*this->db, queue, batchsize); + FileScanWorker *runnable = new FileScanWorker(*this->db, queue, batchsize, this->workerCancellationToken); connect(runnable, &FileScanWorker::result, this, &Indexer::processFileScanResult); connect(runnable, &FileScanWorker::finished, this, &Indexer::processFinishedWorker); ++this->runningWorkers; @@ -107,10 +118,14 @@ void Indexer::processFileScanResult(FileScanResult result) } } +bool Indexer::isRunning() +{ + return this->runningWorkers > 0 || this->dirScanner->isRunning(); +} void Indexer::processFinishedWorker() { --this->runningWorkers; - if(this->runningWorkers == 0 && !this->dirScanner->isRunning()) + if(!isRunning()) { emit finished(); } diff --git a/shared/indexer.h b/shared/indexer.h index 374543e..ccd88f3 100644 --- a/shared/indexer.h +++ b/shared/indexer.h @@ -51,21 +51,25 @@ class Indexer : public QObject QVector pathsToScan; QSharedPointer dirScanner; - QSharedPointer fileScanner; QStringList ignorePattern; /* Those path pointing to files not directories */ ConcurrentQueue filePathTargetsQueue; + std::atomic workerCancellationToken; IndexResult currentIndexResult; void launchWorker(ConcurrentQueue &queue, int batchsize); public: + bool isRunning(); + void beginIndexing(); void setIgnorePattern(QStringList ignorePattern); void setTargetPaths(QVector pathsToScan); + void requestCancellation(); + Indexer(SqliteDbService &db); IndexResult getResult(); diff --git a/shared/paralleldirscanner.cpp b/shared/paralleldirscanner.cpp index a82f902..5427f72 100644 --- a/shared/paralleldirscanner.cpp +++ b/shared/paralleldirscanner.cpp @@ -31,13 +31,14 @@ void ParallelDirScanner::setPaths(QVector paths) void ParallelDirScanner::cancel() { - this->stopToken.store(true, std::memory_order_relaxed); + this->stopToken.store(true, std::memory_order_seq_cst); } void ParallelDirScanner::handleWorkersProgress(unsigned int progress) { this->processedPaths += progress; - emit this->progress(progress, this->processedPaths); + if(!this->stopToken.load(std::memory_order_seq_cst)) + emit this->progress(progress, this->processedPaths); } void ParallelDirScanner::handleWorkersFinish() @@ -45,7 +46,7 @@ void ParallelDirScanner::handleWorkersFinish() Logger::info() << "Worker finished"; // no mutexes required due to queued connection ++finishedWorkers; - if(finishedWorkers == getThreadsNum()) + if(this->stopToken.load(std::memory_order_seq_cst) || finishedWorkers == getThreadsNum()) { running = false; emit scanComplete();