File indexing completed on 2024-04-21 04:01:29
0001 /* -*- C++ -*- 0002 This file is part of ThreadWeaver. 0003 0004 SPDX-FileCopyrightText: 2005-2013 Mirko Boehm <mirko@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include <QMutexLocker> 0010 0011 #include "debuggingaids.h" 0012 #include "destructedstate.h" 0013 #include "inconstructionstate.h" 0014 #include "queuepolicy.h" 0015 #include "shuttingdownstate.h" 0016 #include "suspendedstate.h" 0017 #include "suspendingstate.h" 0018 #include "weaver_p.h" 0019 #include "workinghardstate.h" 0020 0021 namespace ThreadWeaver 0022 { 0023 namespace Private 0024 { 0025 Weaver_Private::Weaver_Private() 0026 : QueueSignals_Private() 0027 , active(0) 0028 , inventoryMax(qMax(4, 2 * QThread::idealThreadCount())) 0029 , mutex(new QMutex) 0030 0031 { 0032 } 0033 0034 Weaver_Private::~Weaver_Private() 0035 { 0036 // FIXME no need for dynamic allocation 0037 delete mutex; 0038 } 0039 0040 /** @brief Dump the current jobs to the console. 0041 * 0042 * Use at your own risk. 0043 */ 0044 void Weaver_Private::dumpJobs() 0045 { 0046 QMutexLocker l(mutex); 0047 Q_UNUSED(l); 0048 TWDEBUG(0, "WeaverImpl::dumpJobs: current jobs:\n"); 0049 for (int index = 0; index < assignments.size(); ++index) { 0050 TWDEBUG(0, 0051 "--> %4i: %p (priority %i, can be executed: %s)\n", 0052 index, 0053 (void *)assignments.at(index).data(), 0054 assignments.at(index)->priority(), 0055 canBeExecuted(assignments.at(index)) ? "yes" : "no"); 0056 } 0057 } 0058 0059 /** @brief Check with the assigned queue policies if the job can be executed. 0060 * 0061 * If it returns true, it expects that the job is executed right after that. The done() methods of the 0062 * queue policies will be automatically called when the job is finished. 0063 * 0064 * If it returns false, all queue policy resources have been freed, and the method can be called again 0065 * at a later time. 0066 */ 0067 bool Weaver_Private::canBeExecuted(JobPointer job) 0068 { 0069 Q_ASSERT(!mutex->tryLock()); // mutex has to be held when this method is called 0070 0071 QList<QueuePolicy *> acquired; 0072 0073 bool success = true; 0074 0075 QMutexLocker l(job->mutex()); 0076 QList<QueuePolicy *> policies = job->queuePolicies(); 0077 if (!policies.isEmpty()) { 0078 TWDEBUG(4, "WeaverImpl::canBeExecuted: acquiring permission from %i queue %s.\n", policies.size(), policies.size() == 1 ? "policy" : "policies"); 0079 for (int index = 0; index < policies.size(); ++index) { 0080 if (policies.at(index)->canRun(job)) { 0081 acquired.append(policies.at(index)); 0082 } else { 0083 success = false; 0084 break; 0085 } 0086 } 0087 0088 TWDEBUG(4, "WeaverImpl::canBeExecuted: queue policies returned %s.\n", success ? "true" : "false"); 0089 0090 if (!success) { 0091 for (int index = 0; index < acquired.size(); ++index) { 0092 acquired.at(index)->release(job); 0093 } 0094 } 0095 } else { 0096 TWDEBUG(4, "WeaverImpl::canBeExecuted: no queue policies, this job can be executed.\n"); 0097 } 0098 return success; 0099 } 0100 0101 void Weaver_Private::deleteExpiredThreads() 0102 { 0103 Q_ASSERT(!mutex->tryLock()); // mutex has to be held when this method is called 0104 for (Thread *thread : std::as_const(expiredThreads)) { 0105 thread->wait(); 0106 delete thread; 0107 } 0108 expiredThreads.clear(); 0109 } 0110 0111 } 0112 0113 }