gui: Begin cancellation of Indexer
Этот коммит содержится в:
родитель
622916db04
Коммит
45de97d8fb
@ -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)
|
||||
|
@ -66,6 +66,7 @@ class MainWindow : public QMainWindow
|
||||
void spinPreviewPageValueChanged(int val);
|
||||
void startIndexing();
|
||||
void finishIndexing();
|
||||
void addPathToIndex();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <QList>
|
||||
#include <QMutex>
|
||||
#include <QSemaphore>
|
||||
|
||||
#define QUEUE_SIZE 10000
|
||||
template <class T> class ConcurrentQueue : protected QList<T>
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user