[libcalamaresui] Switch requirementschecking to threaded mode
- Use QFuture and QFutureWatcher to spawn threads that do the actual checking of the requirements; collect results and report on them as they come in.
This commit is contained in:
parent
c678cd80b4
commit
6090a464f8
@ -23,15 +23,32 @@
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
void
|
||||
check( Module * const &m, RequirementsChecker *c )
|
||||
{
|
||||
RequirementsList l = m->checkRequirements();
|
||||
if ( l.count() > 0 )
|
||||
c->addCheckedRequirements( l );
|
||||
c->requirementsProgress( QObject::tr( "Requirements checking for module %1 is complete." ).arg( m->name() ) );
|
||||
}
|
||||
|
||||
RequirementsChecker::RequirementsChecker( QVector< Module* > modules, QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_modules( std::move( modules ) )
|
||||
{
|
||||
m_watchers.reserve( m_modules.count() );
|
||||
m_collectedRequirements.reserve( m_modules.count() );
|
||||
}
|
||||
|
||||
RequirementsChecker::~RequirementsChecker()
|
||||
@ -41,19 +58,25 @@ RequirementsChecker::~RequirementsChecker()
|
||||
void
|
||||
RequirementsChecker::run()
|
||||
{
|
||||
bool acceptable = true;
|
||||
|
||||
for (const auto& module : m_modules )
|
||||
{
|
||||
RequirementsList l = module->checkRequirements();
|
||||
if ( l.length() > 0 )
|
||||
{
|
||||
cDebug() << " .." << module->name() << "has" << l.length() << "requirements";
|
||||
emit requirementsResult( l );
|
||||
}
|
||||
Watcher *watcher = new Watcher( this );
|
||||
watcher->setFuture( QtConcurrent::run( check, module, this ) );
|
||||
m_watchers.append( watcher );
|
||||
connect( watcher, &Watcher::finished, this, &RequirementsChecker::finished );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsChecker::finished()
|
||||
{
|
||||
if ( std::all_of( m_watchers.cbegin(), m_watchers.cend(), []( const Watcher *w ) { return w && w->isFinished(); } ) )
|
||||
{
|
||||
cDebug() << "All requirements have been checked.";
|
||||
|
||||
bool acceptable = true;
|
||||
int count = 0;
|
||||
for (const auto& r : l)
|
||||
for ( const auto& r : m_collectedRequirements )
|
||||
{
|
||||
if ( r.mandatory && !r.satisfied )
|
||||
{
|
||||
@ -62,12 +85,22 @@ RequirementsChecker::run()
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
emit requirementsComplete( acceptable );
|
||||
QTimer::singleShot(0, this, &RequirementsChecker::done );
|
||||
}
|
||||
|
||||
emit requirementsComplete( acceptable );
|
||||
|
||||
QTimer::singleShot(0, this, &RequirementsChecker::done );
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsChecker::addCheckedRequirements( RequirementsList l )
|
||||
{
|
||||
static QMutex addMutex;
|
||||
{
|
||||
QMutexLocker lock( &addMutex );
|
||||
m_collectedRequirements.append( l );
|
||||
}
|
||||
cDebug() << "Added" << l.count() << "requirement results";
|
||||
emit requirementsResult( l );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#ifndef CALAMARES_REQUIREMENTSCHECKER_H
|
||||
#define CALAMARES_REQUIREMENTSCHECKER_H
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
@ -44,6 +45,10 @@ public:
|
||||
public slots:
|
||||
void run();
|
||||
|
||||
void addCheckedRequirements( RequirementsList );
|
||||
|
||||
void finished();
|
||||
|
||||
signals:
|
||||
/// @brief Human-readable progress message
|
||||
void requirementsProgress( const QString& );
|
||||
@ -59,6 +64,11 @@ signals:
|
||||
|
||||
private:
|
||||
QVector< Module* > m_modules;
|
||||
|
||||
using Watcher = QFutureWatcher< void >;
|
||||
QVector< Watcher* > m_watchers;
|
||||
|
||||
RequirementsList m_collectedRequirements;
|
||||
} ;
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user