From 6090a464f899c8859efcffae0d7b0ae12a46916c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 23 Feb 2019 11:12:55 -0500 Subject: [PATCH] [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. --- .../modulesystem/RequirementsChecker.cpp | 59 +++++++++++++++---- .../modulesystem/RequirementsChecker.h | 10 ++++ 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/libcalamaresui/modulesystem/RequirementsChecker.cpp b/src/libcalamaresui/modulesystem/RequirementsChecker.cpp index 2cd618b4b..74f07e142 100644 --- a/src/libcalamaresui/modulesystem/RequirementsChecker.cpp +++ b/src/libcalamaresui/modulesystem/RequirementsChecker.cpp @@ -23,15 +23,32 @@ #include "utils/Logger.h" +#include + +#include +#include +#include #include + 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 ); +} } diff --git a/src/libcalamaresui/modulesystem/RequirementsChecker.h b/src/libcalamaresui/modulesystem/RequirementsChecker.h index 61346e750..a3f0b9c3e 100644 --- a/src/libcalamaresui/modulesystem/RequirementsChecker.h +++ b/src/libcalamaresui/modulesystem/RequirementsChecker.h @@ -18,6 +18,7 @@ #ifndef CALAMARES_REQUIREMENTSCHECKER_H #define CALAMARES_REQUIREMENTSCHECKER_H +#include #include #include @@ -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; } ; }