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()
{
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)

View File

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

View File

@ -3,7 +3,6 @@
#include <QList>
#include <QMutex>
#include <QSemaphore>
#define QUEUE_SIZE 10000
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))
{
Logger::info() << "Received cancel request" << Qt::endl;
this->results.clear();
emit finished();
return;
}

View File

@ -1,10 +1,12 @@
#include "filescanworker.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->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();
}

View File

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

View File

@ -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<QString> 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<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::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();
}

View File

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

View File

@ -31,13 +31,14 @@ void ParallelDirScanner::setPaths(QVector<QString> 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();