1/* -*- C++ -*-
2 This file is part of ThreadWeaver.
3
4 SPDX-FileCopyrightText: 2005-2013 Mirko Boehm <mirko@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include <QMutexLocker>
10
11#include "debuggingaids.h"
12#include "destructedstate.h"
13#include "inconstructionstate.h"
14#include "queuepolicy.h"
15#include "shuttingdownstate.h"
16#include "suspendedstate.h"
17#include "suspendingstate.h"
18#include "weaver_p.h"
19#include "workinghardstate.h"
20
21namespace ThreadWeaver
22{
23namespace Private
24{
25Weaver_Private::Weaver_Private()
26 : QueueSignals_Private()
27 , active(0)
28 , inventoryMax(qMax(a: 4, b: 2 * QThread::idealThreadCount()))
29 , mutex(new QMutex)
30
31{
32}
33
34Weaver_Private::~Weaver_Private()
35{
36 // FIXME no need for dynamic allocation
37 delete mutex;
38}
39
40/** @brief Dump the current jobs to the console.
41 *
42 * Use at your own risk.
43 */
44void Weaver_Private::dumpJobs()
45{
46 QMutexLocker l(mutex);
47 Q_UNUSED(l);
48 TWDEBUG(0, "WeaverImpl::dumpJobs: current jobs:\n");
49 for (int index = 0; index < assignments.size(); ++index) {
50 TWDEBUG(0,
51 "--> %4i: %p (priority %i, can be executed: %s)\n",
52 index,
53 (void *)assignments.at(index).data(),
54 assignments.at(index)->priority(),
55 canBeExecuted(assignments.at(index)) ? "yes" : "no");
56 }
57}
58
59/** @brief Check with the assigned queue policies if the job can be executed.
60 *
61 * If it returns true, it expects that the job is executed right after that. The done() methods of the
62 * queue policies will be automatically called when the job is finished.
63 *
64 * If it returns false, all queue policy resources have been freed, and the method can be called again
65 * at a later time.
66 */
67bool Weaver_Private::canBeExecuted(JobPointer job)
68{
69 Q_ASSERT(!mutex->tryLock()); // mutex has to be held when this method is called
70
71 QList<QueuePolicy *> acquired;
72
73 bool success = true;
74
75 QMutexLocker l(job->mutex());
76 QList<QueuePolicy *> policies = job->queuePolicies();
77 if (!policies.isEmpty()) {
78 TWDEBUG(4, "WeaverImpl::canBeExecuted: acquiring permission from %i queue %s.\n", policies.size(), policies.size() == 1 ? "policy" : "policies");
79 for (int index = 0; index < policies.size(); ++index) {
80 if (policies.at(i: index)->canRun(job)) {
81 acquired.append(t: policies.at(i: index));
82 } else {
83 success = false;
84 break;
85 }
86 }
87
88 TWDEBUG(4, "WeaverImpl::canBeExecuted: queue policies returned %s.\n", success ? "true" : "false");
89
90 if (!success) {
91 for (int index = 0; index < acquired.size(); ++index) {
92 acquired.at(i: index)->release(job);
93 }
94 }
95 } else {
96 TWDEBUG(4, "WeaverImpl::canBeExecuted: no queue policies, this job can be executed.\n");
97 }
98 return success;
99}
100
101void Weaver_Private::deleteExpiredThreads()
102{
103 Q_ASSERT(!mutex->tryLock()); // mutex has to be held when this method is called
104 for (Thread *thread : std::as_const(t&: expiredThreads)) {
105 thread->wait();
106 delete thread;
107 }
108 expiredThreads.clear();
109}
110
111}
112
113}
114

source code of threadweaver/src/weaver_p.cpp