From f6f8d8b2ee72216adccdb3aaf0ba90bd046e6093 Mon Sep 17 00:00:00 2001 From: Aaron Seigo Date: Tue, 22 Nov 2011 12:17:06 +0100 Subject: [PATCH] when setAllowedRunners is called, call loadRunners, which now also allows for being called while a search is in progress loadRunners intelligently only unloads those runners with are no longer to be loaded, so this is a performance win. it now also checks to see if there are pending jobs for the runners to be deleted (if any) and if so it creates a delayed deleter for them -> no crashes --- private/runnerjobs.cpp | 14 ++++++++++---- private/runnerjobs_p.h | 5 +++-- runnermanager.cpp | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/private/runnerjobs.cpp b/private/runnerjobs.cpp index 67bb501fe..6a8a7710f 100644 --- a/private/runnerjobs.cpp +++ b/private/runnerjobs.cpp @@ -170,10 +170,11 @@ Plasma::AbstractRunner* FindMatchesJob::runner() const return m_runner; } -DelayedJobCleaner::DelayedJobCleaner(QSet jobs, ThreadWeaver::WeaverInterface *weaver) - : QObject(weaver), - m_weaver(weaver), - m_jobs(jobs) +DelayedJobCleaner::DelayedJobCleaner(const QSet &jobs, const QSet &runners) + : QObject(Weaver::instance()), + m_weaver(Weaver::instance()), + m_jobs(jobs), + m_runners(runners) { connect(m_weaver, SIGNAL(finished()), this, SLOT(checkIfFinished())); @@ -182,6 +183,11 @@ DelayedJobCleaner::DelayedJobCleaner(QSet jobs, ThreadWeaver::W } } +DelayedJobCleaner::~DelayedJobCleaner() +{ + qDeleteAll(m_runners); +} + void DelayedJobCleaner::jobDone(ThreadWeaver::Job *job) { FindMatchesJob *runJob = dynamic_cast(job); diff --git a/private/runnerjobs_p.h b/private/runnerjobs_p.h index 19c0f1efa..0f400983e 100644 --- a/private/runnerjobs_p.h +++ b/private/runnerjobs_p.h @@ -126,16 +126,17 @@ private: class DelayedJobCleaner : public QObject { public: - DelayedJobCleaner(QSet jobs, ThreadWeaver::WeaverInterface *weaver); + DelayedJobCleaner(const QSet &jobs, const QSet &runners = QSet()); + ~DelayedJobCleaner(); private Q_SLOTS: void jobDone(ThreadWeaver::Job*); void checkIfFinished(); - //connect(ThreadWeaver::instance(), SIGNAL(finished()), this, SLOT(checkIfFinished())); private: ThreadWeaver::WeaverInterface *m_weaver; QSet m_jobs; + QSet m_runners; }; } diff --git a/runnermanager.cpp b/runnermanager.cpp index 7c24fee8b..0baece10e 100644 --- a/runnermanager.cpp +++ b/runnermanager.cpp @@ -188,6 +188,7 @@ public: advertiseSingleRunnerIds.clear(); + QSet deadRunners; QMutableListIterator it(offers); while (it.hasNext()) { KPluginInfo &description = it.next(); @@ -223,9 +224,32 @@ public: } } else if (loaded) { //Remove runner - AbstractRunner *runner = runners.take(runnerName); + deadRunners.insert(runners.take(runnerName)); kDebug() << "Removing runner: " << runnerName; - delete runner; + } + } + + if (!deadRunners.isEmpty()) { + QSet deadJobs; + foreach (FindMatchesJob *job, searchJobs) { + if (deadRunners.contains(job->runner())) { + QObject::disconnect(job, SIGNAL(done(ThreadWeaver::Job*)), q, SLOT(jobDone(ThreadWeaver::Job*))); + 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 { + new DelayedJobCleaner(deadJobs, deadRunners); } } @@ -429,7 +453,7 @@ RunnerManager::RunnerManager(KConfigGroup &c, QObject *parent) RunnerManager::~RunnerManager() { if (!qApp->closingDown() && (!d->searchJobs.isEmpty() || !d->oldSearchJobs.isEmpty())) { - new DelayedJobCleaner(d->searchJobs + d->oldSearchJobs, Weaver::instance()); + new DelayedJobCleaner(d->searchJobs + d->oldSearchJobs); } delete d; @@ -443,11 +467,13 @@ void RunnerManager::reloadConfiguration() void RunnerManager::setAllowedRunners(const QStringList &runners) { - qDeleteAll(d->runners); - d->runners.clear(); - KConfigGroup config = d->configGroup(); config.writeEntry("pluginWhiteList", runners); + + if (!d->runners.isEmpty()) { + // this has been called with runners already created. so let's do an instant reload + d->loadRunners(); + } } QStringList RunnerManager::allowedRunners() const