gui: Begin cancellation of Indexer

This commit is contained in:
Albert S. 2022-04-15 21:06:19 +02:00
parent 622916db04
commit 45de97d8fb
9 changed files with 53 additions and 9 deletions

View File

@ -129,6 +129,16 @@ void MainWindow::spinPreviewPageValueChanged(int val)
void MainWindow::startIndexing() 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->txtPathScanAdd->setEnabled(false);
ui->txtSearch->setEnabled(false); ui->txtSearch->setEnabled(false);
ui->previewProcessBar->setValue(0); ui->previewProcessBar->setValue(0);
@ -140,6 +150,7 @@ void MainWindow::startIndexing()
} }
this->indexer->setTargetPaths(paths); this->indexer->setTargetPaths(paths);
this->indexer->beginIndexing(); this->indexer->beginIndexing();
ui->btnStartIndexing->setText("Stop indexing");
} }
void MainWindow::finishIndexing() void MainWindow::finishIndexing()
@ -151,6 +162,8 @@ void MainWindow::finishIndexing()
ui->lblFailedValue->setText(QString::number(result.erroredPaths)); ui->lblFailedValue->setText(QString::number(result.erroredPaths));
ui->lblSkippedValue->setText(QString::number(result.skippedPaths)); ui->lblSkippedValue->setText(QString::number(result.skippedPaths));
ui->lblAddedValue->setText(QString::number(result.addedPaths)); ui->lblAddedValue->setText(QString::number(result.addedPaths));
ui->btnStartIndexing->setEnabled(true);
ui->btnStartIndexing->setText("Start indexing");
} }
void MainWindow::comboScaleChanged(int i) void MainWindow::comboScaleChanged(int i)

View File

@ -66,6 +66,7 @@ class MainWindow : public QMainWindow
void spinPreviewPageValueChanged(int val); void spinPreviewPageValueChanged(int val);
void startIndexing(); void startIndexing();
void finishIndexing(); void finishIndexing();
void addPathToIndex();
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -3,7 +3,6 @@
#include <QList> #include <QList>
#include <QMutex> #include <QMutex>
#include <QSemaphore> #include <QSemaphore>
#define QUEUE_SIZE 10000 #define QUEUE_SIZE 10000
template <class T> class ConcurrentQueue : protected QList<T> template <class T> class ConcurrentQueue : protected QList<T>
{ {

View File

@ -33,6 +33,9 @@ void DirScanWorker::run()
{ {
if(this->stopToken->load(std::memory_order_relaxed)) if(this->stopToken->load(std::memory_order_relaxed))
{ {
Logger::info() << "Received cancel request" << Qt::endl;
this->results.clear();
emit finished();
return; return;
} }

View File

@ -1,10 +1,12 @@
#include "filescanworker.h" #include "filescanworker.h"
#include "logger.h" #include "logger.h"
FileScanWorker::FileScanWorker(SqliteDbService &db, ConcurrentQueue<QString> &queue, int batchsize) FileScanWorker::FileScanWorker(SqliteDbService &db, ConcurrentQueue<QString> &queue, int batchsize,
std::atomic<bool> &stopToken)
{ {
this->dbService = &db; this->dbService = &db;
this->queue = &queue; this->queue = &queue;
this->batchsize = batchsize; this->batchsize = batchsize;
this->stopToken = &stopToken;
} }
void FileScanWorker::run() void FileScanWorker::run()
@ -24,6 +26,11 @@ void FileScanWorker::run()
sfr = PROCESSFAIL; // well... sfr = PROCESSFAIL; // well...
} }
emit result({path, sfr}); emit result({path, sfr});
if(stopToken->load(std::memory_order_relaxed)) // TODO: relaxed should suffice here, but recheck
{
emit finished();
return;
}
} }
emit finished(); emit finished();
} }

View File

@ -16,9 +16,10 @@ class FileScanWorker : public QObject, public QRunnable
SqliteDbService *dbService; SqliteDbService *dbService;
ConcurrentQueue<QString> *queue; ConcurrentQueue<QString> *queue;
int batchsize; int batchsize;
std::atomic<bool> *stopToken;
public: public:
FileScanWorker(SqliteDbService &db, ConcurrentQueue<QString> &queue, int batchsize); FileScanWorker(SqliteDbService &db, ConcurrentQueue<QString> &queue, int batchsize, std::atomic<bool> &stopToken);
void run() override; void run() override;
signals: signals:
void result(FileScanResult); void result(FileScanResult);

View File

@ -34,6 +34,7 @@ void Indexer::beginIndexing()
this->dirScanner->scan(); this->dirScanner->scan();
this->workerCancellationToken.store(false, std::memory_order_seq_cst);
launchWorker(this->filePathTargetsQueue, this->filePathTargetsQueue.remaining()); launchWorker(this->filePathTargetsQueue, this->filePathTargetsQueue.remaining());
} }
@ -47,6 +48,12 @@ void Indexer::setTargetPaths(QVector<QString> pathsToScan)
this->pathsToScan = pathsToScan; this->pathsToScan = pathsToScan;
} }
void Indexer::requestCancellation()
{
this->dirScanner->cancel();
this->workerCancellationToken.store(true, std::memory_order_release);
}
IndexResult Indexer::getResult() IndexResult Indexer::getResult()
{ {
return this->currentIndexResult; return this->currentIndexResult;
@ -55,11 +62,15 @@ IndexResult Indexer::getResult()
void Indexer::dirScanFinished() void Indexer::dirScanFinished()
{ {
Logger::info() << "Dir scan finished"; Logger::info() << "Dir scan finished";
if(!isRunning())
{
emit finished();
}
} }
void Indexer::launchWorker(ConcurrentQueue<QString> &queue, int batchsize) void Indexer::launchWorker(ConcurrentQueue<QString> &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::result, this, &Indexer::processFileScanResult);
connect(runnable, &FileScanWorker::finished, this, &Indexer::processFinishedWorker); connect(runnable, &FileScanWorker::finished, this, &Indexer::processFinishedWorker);
++this->runningWorkers; ++this->runningWorkers;
@ -107,10 +118,14 @@ void Indexer::processFileScanResult(FileScanResult result)
} }
} }
bool Indexer::isRunning()
{
return this->runningWorkers > 0 || this->dirScanner->isRunning();
}
void Indexer::processFinishedWorker() void Indexer::processFinishedWorker()
{ {
--this->runningWorkers; --this->runningWorkers;
if(this->runningWorkers == 0 && !this->dirScanner->isRunning()) if(!isRunning())
{ {
emit finished(); emit finished();
} }

View File

@ -51,21 +51,25 @@ class Indexer : public QObject
QVector<QString> pathsToScan; QVector<QString> pathsToScan;
QSharedPointer<ParallelDirScanner> dirScanner; QSharedPointer<ParallelDirScanner> dirScanner;
QSharedPointer<FileScanWorker> fileScanner;
QStringList ignorePattern; QStringList ignorePattern;
/* Those path pointing to files not directories */ /* Those path pointing to files not directories */
ConcurrentQueue<QString> filePathTargetsQueue; ConcurrentQueue<QString> filePathTargetsQueue;
std::atomic<bool> workerCancellationToken;
IndexResult currentIndexResult; IndexResult currentIndexResult;
void launchWorker(ConcurrentQueue<QString> &queue, int batchsize); void launchWorker(ConcurrentQueue<QString> &queue, int batchsize);
public: public:
bool isRunning();
void beginIndexing(); void beginIndexing();
void setIgnorePattern(QStringList ignorePattern); void setIgnorePattern(QStringList ignorePattern);
void setTargetPaths(QVector<QString> pathsToScan); void setTargetPaths(QVector<QString> pathsToScan);
void requestCancellation();
Indexer(SqliteDbService &db); Indexer(SqliteDbService &db);
IndexResult getResult(); IndexResult getResult();

View File

@ -31,13 +31,14 @@ void ParallelDirScanner::setPaths(QVector<QString> paths)
void ParallelDirScanner::cancel() 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) void ParallelDirScanner::handleWorkersProgress(unsigned int progress)
{ {
this->processedPaths += 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() void ParallelDirScanner::handleWorkersFinish()
@ -45,7 +46,7 @@ void ParallelDirScanner::handleWorkersFinish()
Logger::info() << "Worker finished"; Logger::info() << "Worker finished";
// no mutexes required due to queued connection // no mutexes required due to queued connection
++finishedWorkers; ++finishedWorkers;
if(finishedWorkers == getThreadsNum()) if(this->stopToken.load(std::memory_order_seq_cst) || finishedWorkers == getThreadsNum())
{ {
running = false; running = false;
emit scanComplete(); emit scanComplete();