ThreadWeaver

job.cpp
1 /* -*- C++ -*-
2  This file implements the Job class.
3 
4  SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 
8  $Id: Job.cpp 20 2005-08-08 21:02:51Z mirko $
9 */
10 
11 #include "job.h"
12 #include "job_p.h"
13 
14 #include "debuggingaids.h"
15 #include "thread.h"
16 #include <QAtomicInt>
17 #include <QAtomicPointer>
18 #include <QList>
19 #include <QMutex>
20 
21 #include "dependencypolicy.h"
22 #include "exception.h"
23 #include "executewrapper_p.h"
24 #include "executor_p.h"
25 #include "managedjobpointer.h"
26 #include "queuepolicy.h"
27 
28 namespace ThreadWeaver
29 {
31  : d_(new Private::Job_Private())
32 {
33 #if !defined(NDEBUG)
34  d()->debugExecuteWrapper.wrap(setExecutor(&(d()->debugExecuteWrapper)));
35 #endif
36  d()->status.storeRelease(Status_New);
37 }
38 
39 Job::Job(Private::Job_Private *d__)
40  : d_(d__)
41 {
42 #if !defined(NDEBUG)
43  d()->debugExecuteWrapper.wrap(setExecutor(&(d()->debugExecuteWrapper)));
44 #endif
45  d()->status.storeRelease(Status_New);
46 }
47 
49 {
50  for (int index = 0; index < d()->queuePolicies.size(); ++index) {
51  d()->queuePolicies.at(index)->destructed(this);
52  }
53  delete d_;
54 }
55 
56 void Job::execute(const JobPointer &self, Thread *th)
57 {
58  Executor *executor = d()->executor.loadAcquire();
59  Q_ASSERT(executor); // may never be unset!
60  Q_ASSERT(self);
61  executor->begin(self, th);
62  self->setStatus(Status_Running);
63  try {
64  executor->execute(self, th);
65  if (self->status() == Status_Running) {
66  self->setStatus(Status_Success);
67  }
68  } catch (JobAborted &) {
69  self->setStatus(Status_Aborted);
70  } catch (JobFailed &) {
71  self->setStatus(Status_Failed);
72  } catch (AbortThread &) {
73  throw;
74  } catch (...) {
75  TWDEBUG(0, "Uncaught exception in Job %p, aborting.", self.data());
76  throw;
77  }
78  Q_ASSERT(self->status() > Status_Running);
79  executor->end(self, th);
80  executor->cleanup(self, th);
81 }
82 
84 {
85  execute(ManagedJobPointer<Job>(this), nullptr);
86 }
87 
88 Executor *Job::setExecutor(Executor *executor)
89 {
90  return d()->executor.fetchAndStoreOrdered(executor == nullptr ? &Private::defaultExecutor : executor);
91 }
92 
93 Executor *Job::executor() const
94 {
95  return d()->executor.loadAcquire();
96 }
97 
98 int Job::priority() const
99 {
100  return 0;
101 }
102 
103 void Job::setStatus(JobInterface::Status status)
104 {
105  d()->status.storeRelease(status);
106 }
107 
108 JobInterface::Status Job::status() const
109 {
110  // since status is set only through setStatus, this should be safe:
111  return static_cast<Status>(d()->status.loadAcquire());
112 }
113 
114 bool Job::success() const
115 {
116  return d()->status.loadAcquire() == Status_Success;
117 }
118 
120 {
121 }
122 
123 void Job::defaultEnd(const JobPointer &job, Thread *)
124 {
125  d()->freeQueuePolicyResources(job);
126 }
127 
128 void Job::aboutToBeQueued(QueueAPI *api)
129 {
130  QMutexLocker l(mutex());
131  Q_UNUSED(l);
133 }
134 
136 {
137 }
138 
139 void Job::aboutToBeDequeued(QueueAPI *api)
140 {
141  QMutexLocker l(mutex());
142  Q_UNUSED(l);
144 }
145 
147 {
148 }
149 
151 {
152  Q_ASSERT(!mutex()->tryLock());
153  if (!d()->queuePolicies.contains(policy)) {
154  d()->queuePolicies.append(policy);
155  }
156 }
157 
159 {
160  Q_ASSERT(!mutex()->tryLock());
161  int index = d()->queuePolicies.indexOf(policy);
162  if (index != -1) {
163  d()->queuePolicies.removeAt(index);
164  }
165 }
166 
168 {
169  Q_ASSERT(!mutex()->tryLock());
170  return d()->queuePolicies;
171 }
172 
173 Private::Job_Private *Job::d()
174 {
175  return d_;
176 }
177 
178 const Private::Job_Private *Job::d() const
179 {
180  return d_;
181 }
182 
183 bool Job::isFinished() const
184 {
185  const Status s = status();
186  return s == Status_Success || s == Status_Failed || s == Status_Aborted;
187 }
188 
190 {
191  return &(d()->mutex);
192 }
193 
194 }
195 
196 #include "managedjobpointer.h"
void execute(const JobPointer &job, Thread *) override
Perform the job.
Definition: job.cpp:56
int priority() const override
The queueing priority of the job.
Definition: job.cpp:98
void defaultBegin(const JobPointer &job, Thread *thread) override
Perform standard tasks before starting the execution of a job.
Definition: job.cpp:119
void aboutToBeDequeued_locked(QueueAPI *api) override
Called from aboutToBeDequeued() while the mutex is being held.
Definition: job.cpp:146
Executor * setExecutor(Executor *executor) override
Set the Executor object that is supposed to run the job.
Definition: job.cpp:88
void removeQueuePolicy(QueuePolicy *) override
Remove a queue policy from this job.
Definition: job.cpp:158
QList< QueuePolicy * > queuePolicies() const override
Return the queue policies assigned to this Job.
Definition: job.cpp:167
void defaultEnd(const JobPointer &job, Thread *thread) override
Perform standard task after the execution of a job.
Definition: job.cpp:123
Q_SCRIPTABLE CaptureState status()
~Job() override
Destructor.
Definition: job.cpp:48
void aboutToBeQueued(QueueAPI *api) override
The job is about to be added to the weaver's job queue.
Definition: job.cpp:128
void setStatus(Status) override
Set the status of the Job.
Definition: job.cpp:103
void aboutToBeDequeued(QueueAPI *api) override
This Job is about the be dequeued from the weaver's job queue.
Definition: job.cpp:139
Status status() const override
The status of the job.
Definition: job.cpp:108
void blockingExecute() override
Perform the job synchronously in the current thread.
Definition: job.cpp:83
bool isFinished() const override
Returns true if the jobs's execute method finished.
Definition: job.cpp:183
QueuePolicy is an interface for customizations of the queueing behaviour of jobs.
Definition: queuepolicy.h:38
Thread represents a worker thread in a Queue's inventory.
Definition: thread.h:27
void aboutToBeQueued_locked(QueueAPI *api) override
Called from aboutToBeQueued() while the mutex is being held.
Definition: job.cpp:135
Executor * executor() const override
Returns the executor currently set on the Job.
Definition: job.cpp:93
void assignQueuePolicy(QueuePolicy *) override
Assign a queue policy.
Definition: job.cpp:150
bool success() const override
Return whether the Job finished successfully or not.
Definition: job.cpp:114
QMutex * mutex() const override
The mutex used to protect this job.
Definition: job.cpp:189
Job()
Construct a Job.
Definition: job.cpp:30
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:09:38 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.