From c0279bc3e2638fc15e6211d51838c6746c670474 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Fri, 9 May 2008 17:19:27 +0000 Subject: [PATCH] * factor having a runner into QueryMatch::isEnabled * only run a match when the job is actually done, in case people write runners that don't like to have both match and run entered simultaneously (high likliehood of that happening); lets them write runners with fewer threading concerns svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=805919 --- querymatch.cpp | 3 +- runnermanager.cpp | 75 +++++++++++++++++++++++++++++++++++++---------- runnermanager.h | 6 ++++ 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/querymatch.cpp b/querymatch.cpp index b3a61a563..1102c12e7 100644 --- a/querymatch.cpp +++ b/querymatch.cpp @@ -169,7 +169,7 @@ void QueryMatch::setEnabled( bool enabled ) bool QueryMatch::isEnabled() const { - return d->enabled; + return d->enabled && d->runner; } bool QueryMatch::operator<(const QueryMatch& other) const @@ -190,7 +190,6 @@ void QueryMatch::run(const RunnerContext &context) const { //kDebug() << "we run the term" << context->query() << "whose type is" << context->mimetype(); if (d->runner) { - //TODO: this could be dangerous if the runner is deleted behind our backs. d->runner->run(context, *this); } } diff --git a/runnermanager.cpp b/runnermanager.cpp index eabd8e5e9..00a07cdb1 100644 --- a/runnermanager.cpp +++ b/runnermanager.cpp @@ -143,22 +143,21 @@ void RunnerRestrictionPolicy::destructed(Job* job) class FindMatchesJob : public Job { public: - FindMatchesJob(const QString& term, Plasma::AbstractRunner* runner, Plasma::RunnerContext* context, QObject* parent = 0); + FindMatchesJob(Plasma::AbstractRunner* runner, Plasma::RunnerContext* context, QObject* parent = 0); int priority() const; + Plasma::AbstractRunner* runner() const; protected: void run(); private: - QString m_term; Plasma::RunnerContext* m_context; Plasma::AbstractRunner* m_runner; }; -FindMatchesJob::FindMatchesJob( const QString& term, Plasma::AbstractRunner* runner, - Plasma::RunnerContext* context, QObject* parent ) +FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner* runner, + Plasma::RunnerContext* context, QObject* parent) : ThreadWeaver::Job(parent), - m_term(term), m_context(context), m_runner(runner) { @@ -178,6 +177,10 @@ int FindMatchesJob::priority() const return m_runner->priority(); } +Plasma::AbstractRunner* FindMatchesJob::runner() const +{ + return m_runner; +} /***************************************************** * RunnerManager::Private class @@ -188,7 +191,8 @@ class RunnerManager::Private public: Private(RunnerManager *parent) - : q(parent) + : q(parent), + deferredRun(0) { matchChangeTimer.setSingleShot(true); connect(&matchChangeTimer, SIGNAL(timeout()), q, SLOT(scheduleMatchesChanged())); @@ -273,11 +277,24 @@ public: //kDebug() << "All runners loaded, total:" << runners.count(); } + void jobDone(ThreadWeaver::Job* job) + { + FindMatchesJob *runJob = static_cast(job); + if (deferredRun.isEnabled() && runJob->runner() == deferredRun.runner()) { + //kDebug() << "job actually done, running now **************"; + deferredRun.run(context); + deferredRun = QueryMatch(0); + } + searchJobs.removeAll(runJob); + delete runJob; + } + RunnerManager *q; + QueryMatch deferredRun; RunnerContext context; QTimer matchChangeTimer; AbstractRunner::List runners; - QList searchJobs; + QList searchJobs; QStringList prioritylist; QStringList blacklist; KConfigGroup config; @@ -341,11 +358,29 @@ QList RunnerManager::matches() const 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() << "!!!!!!!!!!!!!!!!!!! uh oh!"; + d->deferredRun = match; + return; + } + } + match.run(d->context); + + if (d->deferredRun.isValid()) { + d->deferredRun = QueryMatch(0); + } } -void RunnerManager::launchQuery (const QString & term, const QString & runnerName) +void RunnerManager::launchQuery(const QString & term, const QString & runnerName) { if (term.isEmpty()) { reset(); @@ -370,14 +405,13 @@ void RunnerManager::launchQuery (const QString & term, const QString & runnerNam runable = d->runners; } - bool jobsLaunched=false; foreach (Plasma::AbstractRunner* r, runable) { if ((r->ignoredTypes() & d->context.type()) == 0) { // kDebug() << "launching" << r->name(); - jobsLaunched=true; - Job *job = new FindMatchesJob(term, r, &d->context, this); - Weaver::instance()->enqueue( job ); - d->searchJobs.append( job ); + FindMatchesJob *job = new FindMatchesJob(r, &d->context, this); + connect(job, SIGNAL(done(ThreadWeaver::Job*)), this, SLOT(jobDone(ThreadWeaver::Job*))); + Weaver::instance()->enqueue(job); + d->searchJobs.append(job); } } } @@ -416,6 +450,11 @@ bool RunnerManager::execQuery(const QString &term, const QString &runnerName) return true; } +QString RunnerManager::query() const +{ + return d->context.query(); +} + void RunnerManager::reset() { // If ThreadWeaver is idle, it is safe to clear previous jobs @@ -425,6 +464,13 @@ void RunnerManager::reset() } else { Weaver::instance()->dequeue(); } + + if (d->deferredRun.isEnabled()) { + //kDebug() << "job actually done, running now **************"; + d->deferredRun.run(d->context); + d->deferredRun = QueryMatch(0); + } + d->context.reset(); //FIXME: if the weaver is not idle we have a number of jobs that @@ -433,7 +479,6 @@ void RunnerManager::reset() // or discard results } - -} +} // Plasma namespace #include "runnermanager.moc" diff --git a/runnermanager.h b/runnermanager.h index 2de3423ec..20cc7d635 100644 --- a/runnermanager.h +++ b/runnermanager.h @@ -95,6 +95,11 @@ class PLASMA_EXPORT RunnerManager : public QObject */ bool execQuery(const QString &term, const QString & runnerName); + /** + * @return the current query term + */ + QString query() const; + /** * Reset the current data and stops the query */ @@ -109,6 +114,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(ThreadWeaver::Job*)) class Private; Private * const d;