allow runners to signal that matching should be suspended for them

svn path=/trunk/KDE/kdelibs/; revision=1171157
This commit is contained in:
Aaron J. Seigo 2010-09-02 22:18:03 +00:00
parent 6307f8248f
commit 99b57b9c65
5 changed files with 80 additions and 14 deletions

View File

@ -125,6 +125,10 @@ void AbstractRunner::performMatch(Plasma::RunnerContext &localContext)
static const int reasonableRunTime = 1500;
static const int fastEnoughTime = 250;
if (d->suspendMatching) {
return;
}
QTime time;
time.restart();
@ -360,6 +364,21 @@ DataEngine *AbstractRunner::dataEngine(const QString &name) const
return d->dataEngine(name);
}
bool AbstractRunner::isMatchingSuspended() const
{
return d->suspendMatching;
}
void AbstractRunner::suspendMatching(bool suspend)
{
if (d->suspendMatching == suspend) {
return;
}
d->suspendMatching = suspend;
emit matchingSuspended(suspend);
}
AbstractRunnerPrivate::AbstractRunnerPrivate(AbstractRunner *r)
: priority(AbstractRunner::NormalPriority),
speed(AbstractRunner::NormalSpeed),
@ -368,8 +387,9 @@ AbstractRunnerPrivate::AbstractRunnerPrivate(AbstractRunner *r)
runner(r),
fastRuns(0),
package(0),
defaultSyntax(0),
hasRunOptions(false),
defaultSyntax(0)
suspendMatching(false)
{
}

View File

@ -63,6 +63,7 @@ class AbstractRunnerPrivate;
class PLASMA_EXPORT AbstractRunner : public QObject
{
Q_OBJECT
Q_PROPERTY(bool matchingSuspended READ isMatchingSuspended WRITE suspendMatching NOTIFY matchingSuspended)
public:
/** Specifies a nominal speed for the runner */
@ -257,6 +258,13 @@ class PLASMA_EXPORT AbstractRunner : public QObject
*/
RunnerSyntax *defaultSyntax() const;
/**
* @return true if the runner is currently busy with non-interuptable work, signaling that
* new threads should not be created for it at this time
* @since 4.6
*/
bool isMatchingSuspended() const;
Q_SIGNALS:
/**
* This signal is emitted when matching is about to commence, giving runners
@ -277,6 +285,13 @@ class PLASMA_EXPORT AbstractRunner : public QObject
*/
void teardown();
/**
* Emitted when the runner enters or exits match suspension
* @see matchingSuspended
* @since 4.6
*/
void matchingSuspended(bool suspended);
protected:
friend class RunnerManager;
friend class RunnerManagerPrivate;
@ -286,6 +301,12 @@ class PLASMA_EXPORT AbstractRunner : public QObject
AbstractRunner(QObject *parent, const QVariantList &args);
/**
* Sets whether or not the runner is available for match requests. Useful to
* prevent more thread spawning when the thread is in a busy state.
*/
void suspendMatching(bool suspend);
/**
* Provides access to the runner's configuration object.
*/

View File

@ -46,12 +46,13 @@ public:
KPluginInfo runnerDescription;
AbstractRunner *runner;
int fastRuns;
QReadWriteLock speedLock;
Package *package;
QHash<QString, QAction*> actions;
QList<RunnerSyntax> syntaxes;
bool hasRunOptions;
QReadWriteLock speedLock;
RunnerSyntax *defaultSyntax;
bool hasRunOptions : 1;
bool suspendMatching : 1;
};
} // namespace Plasma

View File

@ -263,6 +263,7 @@ public:
if (runner) {
kDebug() << "================= loading runner:" << service->name() << "=================";
QObject::connect(runner, SIGNAL(matchingSuspended(bool)), q, SLOT(runnerMatchingSuspended(bool)));
QMetaObject::invokeMethod(runner, "init");
}
@ -352,6 +353,32 @@ public:
QObject::connect(dummy, SIGNAL(done(ThreadWeaver::Job*)), dummy, SLOT(deleteLater()));
}
void runnerMatchingSuspended(bool suspended)
{
if (suspended || !prepped || teardownRequested) {
return;
}
AbstractRunner *runner = qobject_cast<AbstractRunner *>(q->sender());
if (runner) {
startJob(runner);
}
}
void startJob(AbstractRunner *runner)
{
if ((runner->ignoredTypes() & context.type()) == 0) {
FindMatchesJob *job = new FindMatchesJob(runner, &context, Weaver::instance());
QObject::connect(job, SIGNAL(done(ThreadWeaver::Job*)), q, SLOT(jobDone(ThreadWeaver::Job*)));
if (runner->speed() == AbstractRunner::SlowSpeed) {
job->setDelayTimer(&delayTimer);
}
Weaver::instance()->enqueue(job);
searchJobs.insert(job);
}
}
// Delay in ms before slow runners are allowed to run
static const int slowRunDelay = 400;
@ -445,6 +472,7 @@ void RunnerManager::loadRunner(const QString &path)
{
if (!d->runners.contains(path)) {
AbstractRunner *runner = new AbstractRunner(this, path);
connect(runner, SIGNAL(matchingSuspended(bool)), this, SLOT(runnerMatchingSuspended(bool)));
d->runners.insert(path, runner);
}
}
@ -580,12 +608,12 @@ QMimeData * RunnerManager::mimeDataForMatch(const QString &id) const
QMimeData * RunnerManager::mimeDataForMatch(const QueryMatch &match) const
{
AbstractRunner *runner = match.runner();
QMimeData * mimeData;
QMimeData *mimeData;
if (runner && QMetaObject::invokeMethod(
runner,
"mimeDataForMatch", Qt::DirectConnection,
Q_RETURN_ARG(QMimeData*, mimeData),
Q_ARG(const Plasma::QueryMatch *, & match)
Q_ARG(const Plasma::QueryMatch *, &match)
)) {
return mimeData;
}
@ -689,16 +717,11 @@ void RunnerManager::launchQuery(const QString &untrimmedTerm, const QString &run
}
foreach (Plasma::AbstractRunner *r, runable) {
if ((r->ignoredTypes() & d->context.type()) == 0) {
// kDebug() << "launching" << r->name();
FindMatchesJob *job = new FindMatchesJob(r, &d->context, Weaver::instance());
connect(job, SIGNAL(done(ThreadWeaver::Job*)), this, SLOT(jobDone(ThreadWeaver::Job*)));
if (r->speed() == AbstractRunner::SlowSpeed) {
job->setDelayTimer(&d->delayTimer);
}
Weaver::instance()->enqueue(job);
d->searchJobs.insert(job);
if (r->isMatchingSuspended()) {
continue;
}
d->startJob(r);
}
// Start timer to unblock slow runners

View File

@ -290,6 +290,7 @@ class PLASMA_EXPORT RunnerManager : public QObject
Q_PRIVATE_SLOT(d, void matchesChanged())
Q_PRIVATE_SLOT(d, void jobDone(ThreadWeaver::Job*))
Q_PRIVATE_SLOT(d, void unblockJobs())
Q_PRIVATE_SLOT(d, void runnerMatchingSuspended(bool))
RunnerManagerPrivate * const d;