diff --git a/runnercontext.cpp b/runnercontext.cpp index 7a654e215..6eb8e35dc 100644 --- a/runnercontext.cpp +++ b/runnercontext.cpp @@ -142,8 +142,15 @@ void RunnerContext::reset() { // We will detach if we are a copy of someone. But we will reset // if we are the 'main' context others copied from. Resetting - // one RunnerContext makes all the copies oneobsolete. + // one RunnerContext makes all the copies obsolete. + + d->q = 0; //we need to mark the q pointer of the detached RunnerContextPrivate + //as dirty on detach to avoid receiving results for old queries + d.detach(); + + d->q = this; //now that we detached the d pointer we need to mark its q pointer as + //this to receive the signals // we still have to remove all the matches, since if the // ref count was 1 (e.g. only the RunnerContext is using @@ -151,7 +158,7 @@ void RunnerContext::reset() if (!d->matches.isEmpty()) { d->matchesById.clear(); d->matches.clear(); - emit d->q->matchesChanged(); + emit matchesChanged(); } d->term.clear(); @@ -194,7 +201,7 @@ bool RunnerContext::addMatches(const QString &term, const QList &mat { Q_UNUSED(term) - if (matches.isEmpty()) { + if (matches.isEmpty() || (!d->q)) { //Bail out if the query is empty or the qptr is dirty return false; } @@ -214,6 +221,7 @@ bool RunnerContext::addMatches(const QString &term, const QList &mat // we always want to sent the signal of the object that created // the d pointer emit d->q->matchesChanged(); + return true; } @@ -221,12 +229,17 @@ bool RunnerContext::addMatch(const QString &term, const QueryMatch &match) { Q_UNUSED(term) + if (!d->q) { // Bail out if the qptr is dirty + return false; + } + LOCK_FOR_WRITE(this) d->matches.append(match); d->matchesById.insert(match.id(), &d->matches.at(d->matches.size() - 1)); UNLOCK(this); //kDebug()<< "added match" << match->text(); - emit d->q->matchesChanged(); + emit d->q->matchesChanged(); + return true; } diff --git a/runnermanager.cpp b/runnermanager.cpp index f81d4c1b1..b9dc8a961 100644 --- a/runnermanager.cpp +++ b/runnermanager.cpp @@ -138,19 +138,23 @@ public: int priority() const; Plasma::AbstractRunner *runner() const; + void setStale(); + bool isStale() const; protected: void run(); private: Plasma::RunnerContext *m_context; Plasma::AbstractRunner *m_runner; + bool m_stale; }; FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner *runner, Plasma::RunnerContext *context, QObject *parent) : ThreadWeaver::Job(parent), m_context(context), - m_runner(runner) + m_runner(runner), + m_stale(false) { if (runner->speed() == Plasma::AbstractRunner::SlowSpeed) { assignQueuePolicy(&RunnerRestrictionPolicy::instance()); @@ -174,6 +178,16 @@ Plasma::AbstractRunner *FindMatchesJob::runner() const return m_runner; } +void FindMatchesJob::setStale() +{ + m_stale = true; +} + +bool FindMatchesJob::isStale() const +{ + return m_stale; +} + /***************************************************** * RunnerManager::Private class * @@ -376,8 +390,8 @@ void RunnerManager::run(const QueryMatch &match) AbstractRunner *runner = match.runner(); foreach (FindMatchesJob *job, d->searchJobs) { - if (job->runner() == runner && !job->isFinished()) { - //kDebug() << "!!!!!!!!!!!!!!!!!!! uh oh!"; + if (job->runner() == runner && !job->isFinished() && !job->isStale()) { + kDebug() << "!!!!!!!!!!!!!!!!!!! uh oh!"; d->deferredRun = match; return; } @@ -385,11 +399,12 @@ void RunnerManager::run(const QueryMatch &match) if (d->deferredRun.isValid()) { d->deferredRun = QueryMatch(0); - + } + match.run(d->context); - } + } QList RunnerManager::actionsForMatch(const QueryMatch &match) @@ -506,6 +521,11 @@ void RunnerManager::reset() d->searchJobs.clear(); } else { Weaver::instance()->dequeue(); + // Since we cannot safely delete the jobs, mark them as stale + // TODO: delete them eventually? + foreach (FindMatchesJob *job, d->searchJobs) { + job->setStale(); + } } if (d->deferredRun.isEnabled()) {