gui: Begin cancellation of Indexer

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

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