ThreadWeaver

collection.cpp
1/* -*- C++ -*-
2 This file implements the Collection class.
3
4 SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <mirko@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "collection.h"
10
11#include "collection_p.h"
12#include "debuggingaids.h"
13#include "queueapi.h"
14#include "queueing.h"
15
16#include <QList>
17#include <QObject>
18#include <QPointer>
19
20#include "dependencypolicy.h"
21#include "executewrapper_p.h"
22#include "thread.h"
23
24namespace ThreadWeaver
25{
26class CollectionExecuteWrapper : public ExecuteWrapper
27{
28public:
29 CollectionExecuteWrapper()
30 : collection(nullptr)
31 {
32 }
33
34 void setCollection(Collection *collection_)
35 {
36 collection = collection_;
37 }
38
39 void begin(const JobPointer &job, Thread *thread) override
40 {
41 TWDEBUG(4, "CollectionExecuteWrapper::begin: collection %p\n", collection);
42 ExecuteWrapper::begin(job, thread);
43 Q_ASSERT(collection);
44 collection->d()->elementStarted(collection, job, thread);
45 ExecuteWrapper::begin(job, thread);
46 }
47
48 void end(const JobPointer &job, Thread *thread) override
49 {
50 TWDEBUG(4, "CollectionExecuteWrapper::end: collection %p\n", collection);
51 Q_ASSERT(collection);
52 ExecuteWrapper::end(job, thread);
53 collection->d()->elementFinished(collection, job, thread);
54 }
55
56 bool ownedByJob() const override
57 {
58 return true;
59 }
60
61private:
62 ThreadWeaver::Collection *collection;
63};
64
65Collection::Collection()
66 : Job(new Private::Collection_Private)
67{
68}
69
70Collection::Collection(Private::Collection_Private *d__)
71 : Job(d__)
72{
73}
74
75Collection::~Collection()
76{
77 MUTEX_ASSERT_UNLOCKED(mutex());
78 // dequeue all remaining jobs:
79 QMutexLocker l(mutex());
80 Q_UNUSED(l);
81 if (d()->api != nullptr) { // still queued
82 d()->dequeueElements(this, false);
83 }
84}
85
86void Collection::addJob(JobPointer job)
87{
89 Q_UNUSED(l);
90 REQUIRE(d()->api == nullptr || d()->selfIsExecuting == true); // not queued yet or still running
91 REQUIRE(job != nullptr);
92
93 CollectionExecuteWrapper *wrapper = new CollectionExecuteWrapper();
94 wrapper->setCollection(this);
95 wrapper->wrap(job->setExecutor(wrapper));
96 d()->elements.append(job);
97}
98
100{
101 d()->stop(this);
102}
103
105{
107 d()->requestAbort(this);
108}
109
111{
112 Q_ASSERT(!mutex()->tryLock());
113 Q_ASSERT(d()->api == nullptr); // never queue twice
114 d()->api = api;
115 d()->selfExecuteWrapper.wrap(setExecutor(&d()->selfExecuteWrapper));
116 CollectionExecuteWrapper *wrapper = new CollectionExecuteWrapper();
117 wrapper->setCollection(this);
118 wrapper->wrap(setExecutor(wrapper));
120}
121
123{
124 Q_ASSERT(!mutex()->tryLock());
125 Q_ASSERT(api && d()->api == api);
126 d()->dequeueElements(this, true);
127 d()->api = nullptr;
128
129 Q_ASSERT(dynamic_cast<CollectionExecuteWrapper *>(executor()));
130 auto wrapper = static_cast<CollectionExecuteWrapper *>(executor());
131 wrapper->unwrap(this);
132 delete wrapper;
133
134 Q_ASSERT(executor() == &d()->selfExecuteWrapper);
135 d()->selfExecuteWrapper.unwrap(this);
136
138}
139
140void Collection::execute(const JobPointer &job, Thread *thread)
141{
142 {
143 QMutexLocker l(mutex());
144 Q_UNUSED(l);
145 Q_ASSERT(d()->self.isNull());
146 Q_ASSERT(d()->api != nullptr);
147 d()->self = job;
148 d()->selfIsExecuting = true; // reset in elementFinished
149 }
150 Job::execute(job, thread);
151}
152
153void Collection::run(JobPointer, Thread *)
154{
155 // empty
156}
157
158Private::Collection_Private *Collection::d()
159{
160 return reinterpret_cast<Private::Collection_Private *>(Job::d());
161}
162
163const Private::Collection_Private *Collection::d() const
164{
165 return reinterpret_cast<const Private::Collection_Private *>(Job::d());
166}
167
168JobPointer Collection::jobAt(int i)
169{
170 Q_ASSERT(!mutex()->tryLock());
171 Q_ASSERT(i >= 0 && i < d()->elements.size());
172 return d()->elements.at(i);
173}
174
176{
177 QMutexLocker l(mutex());
178 Q_UNUSED(l);
179 return jobListLength_locked();
180}
181
183{
184 return d()->elements.size();
185}
186
187Collection &Collection::operator<<(JobInterface *job)
188{
189 addJob(make_job(job));
190 return *this;
191}
192
193Collection &Collection::operator<<(const JobPointer &job)
194{
195 addJob(job);
196 return *this;
197}
198
199Collection &Collection::operator<<(JobInterface &job)
200{
201 addJob(make_job_raw(&job));
202 return *this;
203}
204
205}
A Collection is a vector of Jobs that will be queued together.
Definition collection.h:35
virtual void addJob(JobPointer)
Append a job to the collection.
virtual int jobListLength_locked() const
Return the number of jobs in the joblist.
int elementCount() const
Return the number of elements in the collection.
void aboutToBeQueued_locked(QueueAPI *api) override
Overload to queue the collection.
void execute(const JobPointer &job, Thread *) override
Overload the execute method.
Collection & operator<<(ThreadWeaver::JobInterface *job)
Add the job to this collection by pointer.
void stop()
Stop processing, dequeue all remaining Jobs.
void run(JobPointer self, Thread *thread) override
Overload run().
void aboutToBeDequeued_locked(QueueAPI *api) override
Overload to dequeue the collection.
void requestAbort() override
Dequeue all remaining Jobs and request abortion of all running jobs.
JobPointer jobAt(int i)
Return a ref-erence to the job in the job list at position i.
A Job is a simple abstraction of an action that is to be executed in a thread context.
Definition job.h:47
Executor * setExecutor(Executor *executor) override
Set the Executor object that is supposed to run the job.
Definition job.cpp:87
QMutex * mutex() const override
The mutex used to protect this job.
Definition job.cpp:194
void aboutToBeDequeued_locked(QueueAPI *api) override
Called from aboutToBeDequeued() while the mutex is being held.
Definition job.cpp:151
void execute(const JobPointer &job, Thread *) override
Perform the job.
Definition job.cpp:56
Executor * executor() const override
Returns the executor currently set on the Job.
Definition job.cpp:92
void aboutToBeQueued_locked(QueueAPI *api) override
Called from aboutToBeQueued() while the mutex is being held.
Definition job.cpp:140
void requestAbort() override
Abort the execution of the job.
Definition job.cpp:118
Thread represents a worker thread in a Queue's inventory.
Definition thread.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:57:09 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.