File indexing completed on 2024-04-28 11:44:19
0001 /* 0002 SPDX-FileCopyrightText: 2007, 2009 Ryan P. Bitanga <ryan.bitanga@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "runnerjobs_p.h" 0008 0009 #include <QMutexLocker> 0010 #include <QTimer> 0011 0012 #include "krunner_debug.h" 0013 #include "querymatch.h" 0014 #include "runnermanager.h" 0015 0016 using ThreadWeaver::Job; 0017 using ThreadWeaver::Queue; 0018 0019 namespace Plasma 0020 { 0021 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 81) 0022 DelayedRunnerPolicy::DelayedRunnerPolicy() 0023 : QueuePolicy() 0024 { 0025 } 0026 0027 DelayedRunnerPolicy::~DelayedRunnerPolicy() 0028 { 0029 } 0030 0031 DelayedRunnerPolicy &DelayedRunnerPolicy::instance() 0032 { 0033 static DelayedRunnerPolicy policy; 0034 return policy; 0035 } 0036 0037 bool DelayedRunnerPolicy::canRun(ThreadWeaver::JobPointer job) 0038 { 0039 QSharedPointer<FindMatchesJob> aJob(job.dynamicCast<FindMatchesJob>()); 0040 if (QTimer *t = aJob->delayTimer()) { 0041 // If the timer is active, the required delay has not been reached 0042 return !t->isActive(); // DATA RACE! (with QTimer start/stop from runnermanager.cpp) 0043 } 0044 0045 return true; 0046 } 0047 0048 void DelayedRunnerPolicy::free(ThreadWeaver::JobPointer job) 0049 { 0050 Q_UNUSED(job) 0051 } 0052 0053 void DelayedRunnerPolicy::release(ThreadWeaver::JobPointer job) 0054 { 0055 free(job); 0056 } 0057 0058 void DelayedRunnerPolicy::destructed(ThreadWeaver::JobInterface *job) 0059 { 0060 Q_UNUSED(job) 0061 } 0062 #endif 0063 0064 DefaultRunnerPolicy::DefaultRunnerPolicy() 0065 : QueuePolicy() 0066 , m_cap(2) 0067 { 0068 } 0069 0070 DefaultRunnerPolicy::~DefaultRunnerPolicy() 0071 { 0072 } 0073 0074 DefaultRunnerPolicy &DefaultRunnerPolicy::instance() 0075 { 0076 static DefaultRunnerPolicy policy; 0077 return policy; 0078 } 0079 0080 bool DefaultRunnerPolicy::canRun(ThreadWeaver::JobPointer job) 0081 { 0082 Plasma::AbstractRunner *runner = job.dynamicCast<FindMatchesJob>()->runner(); 0083 QMutexLocker l(&m_mutex); 0084 0085 if (m_runCounts[runner->name()] > m_cap) { 0086 return false; 0087 } else { 0088 ++m_runCounts[runner->name()]; 0089 return true; 0090 } 0091 } 0092 0093 void DefaultRunnerPolicy::free(ThreadWeaver::JobPointer job) 0094 { 0095 Plasma::AbstractRunner *runner = job.dynamicCast<FindMatchesJob>()->runner(); 0096 QMutexLocker l(&m_mutex); 0097 0098 --m_runCounts[runner->name()]; 0099 } 0100 0101 void DefaultRunnerPolicy::release(ThreadWeaver::JobPointer job) 0102 { 0103 free(job); 0104 } 0105 0106 void DefaultRunnerPolicy::destructed(ThreadWeaver::JobInterface *job) 0107 { 0108 Q_UNUSED(job) 0109 } 0110 0111 //////////////////// 0112 // Jobs 0113 //////////////////// 0114 0115 FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner *runner, Plasma::RunnerContext *context, QObject *) 0116 : ThreadWeaver::Job() 0117 , m_context(*context, nullptr) 0118 , m_runner(runner) 0119 { 0120 QMutexLocker l(mutex()); 0121 Q_UNUSED(l); 0122 #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 81) 0123 if (runner->speed() == Plasma::AbstractRunner::SlowSpeed) { 0124 assignQueuePolicy(&DelayedRunnerPolicy::instance()); 0125 } else { 0126 assignQueuePolicy(&DefaultRunnerPolicy::instance()); 0127 } 0128 #else 0129 assignQueuePolicy(&DefaultRunnerPolicy::instance()); 0130 #endif 0131 } 0132 0133 FindMatchesJob::~FindMatchesJob() 0134 { 0135 } 0136 0137 void FindMatchesJob::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *) 0138 { 0139 if (m_context.isValid()) { 0140 m_runner->match(m_context); 0141 } 0142 Q_EMIT done(self); 0143 } 0144 0145 int FindMatchesJob::priority() const 0146 { 0147 return m_runner->priority(); 0148 } 0149 0150 Plasma::AbstractRunner *FindMatchesJob::runner() const 0151 { 0152 return m_runner; 0153 } 0154 0155 DelayedJobCleaner::DelayedJobCleaner(const QSet<QSharedPointer<FindMatchesJob>> &jobs, const QSet<AbstractRunner *> &runners) 0156 : QObject(Queue::instance()) 0157 , m_weaver(Queue::instance()) 0158 , m_jobs(jobs) 0159 , m_runners(runners) 0160 { 0161 connect(m_weaver, &ThreadWeaver::QueueSignals::finished, this, &DelayedJobCleaner::checkIfFinished); 0162 0163 for (auto it = m_jobs.constBegin(); it != m_jobs.constEnd(); ++it) { 0164 connect(it->data(), &FindMatchesJob::done, this, &DelayedJobCleaner::jobDone); 0165 } 0166 } 0167 0168 DelayedJobCleaner::~DelayedJobCleaner() 0169 { 0170 qDeleteAll(m_runners); 0171 } 0172 0173 void DelayedJobCleaner::jobDone(ThreadWeaver::JobPointer job) 0174 { 0175 auto runJob = job.dynamicCast<FindMatchesJob>(); 0176 0177 if (!runJob) { 0178 return; 0179 } 0180 0181 m_jobs.remove(runJob); 0182 0183 if (m_jobs.isEmpty()) { 0184 deleteLater(); 0185 } 0186 } 0187 0188 void DelayedJobCleaner::checkIfFinished() 0189 { 0190 if (m_weaver->isIdle()) { 0191 m_jobs.clear(); 0192 deleteLater(); 0193 } 0194 } 0195 0196 } // Plasma namespace 0197 0198 #include "moc_runnerjobs_p.cpp"