mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
plasma: use QThreadPool and QRunnable for even faster runners
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
5f025e2a91
commit
e7b9481e80
4 changed files with 40 additions and 122 deletions
|
@ -33,30 +33,22 @@ namespace Plasma {
|
|||
////////////////////
|
||||
|
||||
FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner *runner,
|
||||
Plasma::RunnerContext *context, QObject *parent)
|
||||
: QThread(parent),
|
||||
Plasma::RunnerContext *context)
|
||||
: QRunnable(),
|
||||
m_context(*context, 0),
|
||||
m_runner(runner)
|
||||
m_runner(runner),
|
||||
m_finished(false)
|
||||
{
|
||||
}
|
||||
|
||||
FindMatchesJob::~FindMatchesJob()
|
||||
{
|
||||
wait(3000);
|
||||
}
|
||||
|
||||
void FindMatchesJob::run()
|
||||
{
|
||||
m_finished = false;
|
||||
// kDebug() << "Running match for " << m_runner->objectName();
|
||||
if (m_context.isValid()) {
|
||||
m_runner->performMatch(m_context);
|
||||
emit done(this);
|
||||
}
|
||||
}
|
||||
|
||||
int FindMatchesJob::priority() const
|
||||
{
|
||||
return m_runner->priority();
|
||||
m_finished = true;
|
||||
}
|
||||
|
||||
Plasma::AbstractRunner* FindMatchesJob::runner() const
|
||||
|
@ -64,6 +56,11 @@ Plasma::AbstractRunner* FindMatchesJob::runner() const
|
|||
return m_runner;
|
||||
}
|
||||
|
||||
bool FindMatchesJob::isFinished()
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
#include "moc_runnerjobs_p.cpp"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <QHash>
|
||||
#include <QMutex>
|
||||
#include <QSet>
|
||||
#include <QThread>
|
||||
#include <QRunnable>
|
||||
|
||||
#include "abstractrunner.h"
|
||||
|
||||
|
@ -34,19 +34,14 @@ namespace Plasma {
|
|||
* FindMatchesJob class
|
||||
* Class to run queries in different threads
|
||||
*/
|
||||
class FindMatchesJob : public QThread
|
||||
class FindMatchesJob : public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FindMatchesJob(Plasma::AbstractRunner *runner,
|
||||
Plasma::RunnerContext *context, QObject *parent = 0);
|
||||
~FindMatchesJob();
|
||||
Plasma::RunnerContext *context);
|
||||
|
||||
int priority() const;
|
||||
Plasma::AbstractRunner* runner() const;
|
||||
|
||||
signals:
|
||||
void done(QThread *thread);
|
||||
bool isFinished();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
@ -54,6 +49,7 @@ protected:
|
|||
private:
|
||||
Plasma::RunnerContext m_context;
|
||||
Plasma::AbstractRunner *m_runner;
|
||||
bool m_finished;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QMutex>
|
||||
#include <QTimer>
|
||||
#include <QCoreApplication>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kplugininfo.h>
|
||||
|
@ -51,8 +52,8 @@ public:
|
|||
|
||||
RunnerManagerPrivate(RunnerManager *parent)
|
||||
: q(parent),
|
||||
deferredRun(0),
|
||||
currentSingleRunner(0),
|
||||
threadPool(0),
|
||||
prepped(false),
|
||||
allRunnersPrepped(false),
|
||||
singleRunnerPrepped(false),
|
||||
|
@ -60,6 +61,8 @@ public:
|
|||
singleMode(false),
|
||||
singleRunnerWasLoaded(false)
|
||||
{
|
||||
threadPool = new QThreadPool();
|
||||
|
||||
matchChangeTimer.setSingleShot(true);
|
||||
|
||||
QObject::connect(&matchChangeTimer, SIGNAL(timeout()), q, SLOT(matchesChanged()));
|
||||
|
@ -70,6 +73,10 @@ public:
|
|||
{
|
||||
KConfigGroup config = configGroup();
|
||||
context.save(config);
|
||||
|
||||
kDebug() << "waiting for runner jobs";
|
||||
threadPool->waitForDone();
|
||||
delete threadPool;
|
||||
}
|
||||
|
||||
void scheduleMatchesChanged()
|
||||
|
@ -86,9 +93,14 @@ public:
|
|||
{
|
||||
KConfigGroup config = configGroup();
|
||||
|
||||
// TODO: instead of that hard-limit use QThreadPool and QRunnable
|
||||
int idealThreads = QThread::idealThreadCount();
|
||||
if (idealThreads < 0) {
|
||||
idealThreads = 4;
|
||||
}
|
||||
const int maxThreads = config.readEntry("maxThreads", idealThreads);
|
||||
kDebug() << "limiting runner threads to" << maxThreads;
|
||||
//This entry allows to define a hard upper limit independent of the number of processors.
|
||||
maxThreads = config.readEntry("maxThreads", 32);
|
||||
threadPool->setMaxThreadCount(maxThreads);
|
||||
|
||||
context.restore(config);
|
||||
}
|
||||
|
@ -199,31 +211,7 @@ public:
|
|||
}
|
||||
|
||||
if (!deadRunners.isEmpty()) {
|
||||
QSet<FindMatchesJob *> deadJobs;
|
||||
foreach (FindMatchesJob *job, searchJobs) {
|
||||
if (deadRunners.contains(job->runner())) {
|
||||
QObject::disconnect(job, SIGNAL(done(QThread*)), q, SLOT(jobDone(QThread*)));
|
||||
searchJobs.remove(job);
|
||||
deadJobs.insert(job);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (FindMatchesJob *job, oldSearchJobs) {
|
||||
if (deadRunners.contains(job->runner())) {
|
||||
oldSearchJobs.remove(job);
|
||||
deadJobs.insert(job);
|
||||
}
|
||||
}
|
||||
|
||||
if (deadJobs.isEmpty()) {
|
||||
qDeleteAll(deadRunners);
|
||||
} else {
|
||||
// cleaner
|
||||
foreach (FindMatchesJob *job, deadJobs) {
|
||||
job->quit();
|
||||
}
|
||||
deadJobs.clear();
|
||||
}
|
||||
qDeleteAll(deadRunners);
|
||||
}
|
||||
|
||||
if (!singleRunnerWasLoaded) {
|
||||
|
@ -275,25 +263,8 @@ public:
|
|||
return runner;
|
||||
}
|
||||
|
||||
void jobDone(QThread *job)
|
||||
void jobDone()
|
||||
{
|
||||
FindMatchesJob *runJob = dynamic_cast<FindMatchesJob *>(job);
|
||||
|
||||
if (!runJob) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (deferredRun.isEnabled() && runJob->runner() == deferredRun.runner()) {
|
||||
//kDebug() << "job actually done, running now **************";
|
||||
QueryMatch tmpRun = deferredRun;
|
||||
deferredRun = QueryMatch(0);
|
||||
tmpRun.run(context);
|
||||
}
|
||||
|
||||
searchJobs.remove(runJob);
|
||||
oldSearchJobs.remove(runJob);
|
||||
runJob->deleteLater();
|
||||
|
||||
if (searchJobs.isEmpty() && context.matches().isEmpty()) {
|
||||
// we finished our run, and there are no valid matches, and so no
|
||||
// signal will have been sent out. so we need to emit the signal
|
||||
|
@ -306,13 +277,13 @@ public:
|
|||
|
||||
void checkTearDown()
|
||||
{
|
||||
//kDebug() << prepped << teardownRequested << searchJobs.count() << oldSearchJobs.count();
|
||||
//kDebug() << prepped << teardownRequested << searchJobs.count();
|
||||
|
||||
if (!prepped || !teardownRequested) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (searchJobs.isEmpty() && oldSearchJobs.isEmpty()) {
|
||||
if (searchJobs.isEmpty()) {
|
||||
if (allRunnersPrepped) {
|
||||
foreach (AbstractRunner *runner, runners) {
|
||||
emit runner->teardown();
|
||||
|
@ -352,26 +323,20 @@ public:
|
|||
void startJob(AbstractRunner *runner)
|
||||
{
|
||||
if ((runner->ignoredTypes() & context.type()) == 0) {
|
||||
if (searchJobs.count() >= maxThreads) {
|
||||
// kWarning() << "not starting a runner due to hard limit of" << maxThreads;
|
||||
return;
|
||||
}
|
||||
FindMatchesJob *job = new FindMatchesJob(runner, &context, q);
|
||||
QObject::connect(job, SIGNAL(done(QThread*)), q, SLOT(jobDone(QThread*)));
|
||||
job->start();
|
||||
FindMatchesJob *job = new FindMatchesJob(runner, &context);
|
||||
searchJobs.insert(job);
|
||||
threadPool->start(job);
|
||||
}
|
||||
}
|
||||
|
||||
RunnerManager *q;
|
||||
QueryMatch deferredRun;
|
||||
RunnerContext context;
|
||||
QTimer matchChangeTimer;
|
||||
QHash<QString, AbstractRunner*> runners;
|
||||
QHash<QString, QString> advertiseSingleRunnerIds;
|
||||
AbstractRunner* currentSingleRunner;
|
||||
QSet<FindMatchesJob*> searchJobs;
|
||||
QSet<FindMatchesJob*> oldSearchJobs;
|
||||
QThreadPool *threadPool;
|
||||
KConfigGroup conf;
|
||||
QString singleModeRunnerId;
|
||||
bool loadAll : 1;
|
||||
|
@ -381,7 +346,6 @@ public:
|
|||
bool teardownRequested : 1;
|
||||
bool singleMode : 1;
|
||||
bool singleRunnerWasLoaded : 1;
|
||||
int maxThreads;
|
||||
};
|
||||
|
||||
/*****************************************************
|
||||
|
@ -407,18 +371,6 @@ RunnerManager::RunnerManager(KConfigGroup &c, QObject *parent)
|
|||
|
||||
RunnerManager::~RunnerManager()
|
||||
{
|
||||
if (!qApp->closingDown() && (!d->searchJobs.isEmpty() || !d->oldSearchJobs.isEmpty())) {
|
||||
// cleaner
|
||||
foreach (FindMatchesJob *job, d->searchJobs) {
|
||||
job->quit();
|
||||
}
|
||||
d->searchJobs.clear();
|
||||
foreach (FindMatchesJob *job, d->oldSearchJobs) {
|
||||
job->quit();
|
||||
}
|
||||
d->searchJobs.clear();
|
||||
}
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
@ -559,22 +511,6 @@ void RunnerManager::run(const QueryMatch &match)
|
|||
if (!match.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: this function is not const as it may be used for learning
|
||||
AbstractRunner *runner = match.runner();
|
||||
|
||||
foreach (FindMatchesJob *job, d->searchJobs) {
|
||||
if (job->runner() == runner && !job->isFinished()) {
|
||||
kDebug() << "deferred run";
|
||||
d->deferredRun = match;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (d->deferredRun.isValid()) {
|
||||
d->deferredRun = QueryMatch(0);
|
||||
}
|
||||
|
||||
d->context.run(match);
|
||||
}
|
||||
|
||||
|
@ -766,20 +702,9 @@ QString RunnerManager::query() const
|
|||
|
||||
void RunnerManager::reset()
|
||||
{
|
||||
Q_FOREACH(FindMatchesJob *job, d->searchJobs) {
|
||||
job->terminate();
|
||||
}
|
||||
d->oldSearchJobs += d->searchJobs;
|
||||
|
||||
d->threadPool->waitForDone(3000);
|
||||
d->searchJobs.clear();
|
||||
|
||||
if (d->deferredRun.isEnabled()) {
|
||||
//kDebug() << "job actually done, running now **************";
|
||||
QueryMatch tmpRun = d->deferredRun;
|
||||
d->deferredRun = QueryMatch(0);
|
||||
tmpRun.run(d->context);
|
||||
}
|
||||
|
||||
d->context.reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ class PLASMA_EXPORT RunnerManager : public QObject
|
|||
private:
|
||||
Q_PRIVATE_SLOT(d, void scheduleMatchesChanged())
|
||||
Q_PRIVATE_SLOT(d, void matchesChanged())
|
||||
Q_PRIVATE_SLOT(d, void jobDone(QThread*))
|
||||
Q_PRIVATE_SLOT(d, void jobDone())
|
||||
Q_PRIVATE_SLOT(d, void runnerMatchingSuspended(bool))
|
||||
|
||||
RunnerManagerPrivate * const d;
|
||||
|
|
Loading…
Add table
Reference in a new issue