ThreadWeaver

thread.cpp
1/* -*- C++ -*-
2 This file is part of ThreadWeaver. It implements the Thread class.
3
4 SPDX-FileCopyrightText: 2004-2013 Mirko Boehm <mirko@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7
8 $Id: Thread.cpp 25 2005-08-14 12:41:38Z mirko $
9*/
10
11#include "thread.h"
12
13#include <QCoreApplication>
14#include <QDebug>
15#include <QPointer>
16
17#include "debuggingaids.h"
18#include "exception.h"
19#include "job.h"
20#include "threadweaver.h"
21#include "weaver.h"
22
23using namespace ThreadWeaver;
24
25class Q_DECL_HIDDEN Thread::Private
26{
27public:
28 explicit Private(Weaver *theParent)
29 : parent(theParent)
30 , id(makeId())
31 , job(nullptr)
32 {
33 Q_ASSERT(parent);
34 }
35
36 Weaver *parent;
37 const unsigned int id;
38 JobPointer job;
39 QMutex mutex;
40
41 static unsigned int makeId()
42 {
43 static QAtomicInt s_id(1);
44 return s_id.fetchAndAddRelease(1);
45 }
46};
47
49 : QThread() // no parent, because the QObject hierarchy of this thread
50 // does not have a parent (see QObject::pushToThread)
51 , d(new Private(parent))
52{
53 const QString queueName =
54 parent->objectName().isEmpty() ? QString::fromLatin1("Queue(0x%1)").arg(quintptr(parent), 0, 16, QChar::fromLatin1('0')) : parent->objectName();
55 setObjectName(QString::fromLatin1("%1[%2]").arg(queueName).arg(QString::number(id()), 2, QChar::fromLatin1('0')));
56}
57
59{
60 delete d;
61}
62
63unsigned int Thread::id() const
64{
65 return d->id; // id is const
66}
67
69{
70 Q_ASSERT(d->parent);
71 Q_ASSERT(QCoreApplication::instance() != nullptr);
72 d->parent->threadEnteredRun(this);
73
74 TWDEBUG(3, "Thread::run [%u]: running.\n", id());
75
76 bool wasBusy = false;
77 while (true) {
78 TWDEBUG(3, "Thread::run [%u]: trying to execute the next job.\n", id());
79
80 try {
81 // the assignment is intentional: newJob needs to go out of scope at the end of the if statement
82 if (JobPointer newJob = d->parent->applyForWork(this, wasBusy)) {
83 QMutexLocker l(&d->mutex);
84 Q_UNUSED(l);
85 d->job = newJob;
86 } else {
87 break;
88 }
89 } catch (AbortThread &) {
90 break;
91 }
92
93 wasBusy = true;
94 d->job->execute(d->job, this);
95 JobPointer oldJob;
96 { // When finally destroying the last reference to d->job, do not hold the mutex.
97 // It may trigger destruction of the job, which can execute arbitrary code.
98 QMutexLocker l(&d->mutex);
99 Q_UNUSED(l);
100 oldJob = d->job;
101 d->job.clear();
102 }
103 oldJob.clear();
104 }
105 TWDEBUG(3, "Thread::run [%u]: exiting.\n", id());
106}
107
109{
110 QMutexLocker l(&d->mutex);
111 Q_UNUSED(l);
112 if (d->job) {
113 d->job->requestAbort();
114 }
115}
116
117#include "moc_thread.cpp"
Thread represents a worker thread in a Queue's inventory.
Definition thread.h:28
~Thread() override
The destructor.
Definition thread.cpp:58
Thread(Weaver *parent=nullptr)
Create a thread.
Definition thread.cpp:48
unsigned int id() const
Returns the thread id.
Definition thread.cpp:63
void requestAbort()
Request the abortion of the job that is processed currently.
Definition thread.cpp:108
void run() override
The run method is reimplemented to execute jobs from the queue.
Definition thread.cpp:68
A Weaver manages worker threads.
Definition weaver.h:35
void threadEnteredRun(Thread *thread)
Called from a new thread when entering the run method.
Definition weaver.cpp:489
JobPointer applyForWork(Thread *thread, bool wasBusy) override
Assign a job to the calling thread.
Definition weaver.cpp:573
QChar fromLatin1(char c)
QCoreApplication * instance()
QObject * parent() const const
void setObjectName(QAnyStringView name)
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
QString number(double n, char format, int precision)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 12 2024 11:52:00 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.