KD SOAP API Documentation 2.2
Loading...
Searching...
No Matches
KDSoapThreadPool.cpp
Go to the documentation of this file.
1/****************************************************************************
2**
3** This file is part of the KD Soap project.
4**
5** SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6**
7** SPDX-License-Identifier: MIT
8**
9****************************************************************************/
10#include "KDSoapThreadPool.h"
12#include <QDebug>
13
14class KDSoapThreadPool::Private
15{
16public:
17 Private()
18 : m_maxThreadCount(QThread::idealThreadCount())
19 {
20 }
21
22 KDSoapServerThread *chooseNextThread();
23
24 int m_maxThreadCount;
25 typedef QList<KDSoapServerThread *> ThreadCollection;
26 ThreadCollection m_threads;
27};
28
30 : QObject(parent)
31 , d(new Private)
32{
33}
34
36{
37 // ask all threads to finish, then delete them all
38 for (KDSoapServerThread *thread : qAsConst(d->m_threads)) {
39 thread->quitThread();
40 }
41 for (KDSoapServerThread *thread : qAsConst(d->m_threads)) {
42 thread->wait();
43 delete thread;
44 }
45
46 delete d;
47}
48
50{
51 d->m_maxThreadCount = maxThreadCount;
52}
53
55{
56 return d->m_maxThreadCount;
57}
58
59KDSoapServerThread *KDSoapThreadPool::Private::chooseNextThread()
60{
61 KDSoapServerThread *chosenThread = nullptr;
62 // Try to pick an existing thread
63 int minSocketCount = 0;
64 KDSoapServerThread *bestThread = nullptr;
65 for (KDSoapServerThread *thr : qAsConst(m_threads)) {
66 // We look at the amount of sockets connected to each thread, and pick the less busy one.
67 // Note that this isn't fully accurate, due to Keep-Alive: it's possible for long-term
68 // idling clients to be all on one thread, and active clients on another one, and this
69 // wouldn't use CPU fully. But this is probably still better than no keep-alive (much more
70 // connection overhead). Maybe we have to look at sockets who made a request in the last
71 // N seconds... but the past is no indication of the future.
72 const int sc = thr->socketCount();
73 if (sc == 0) { // Perfect, an idling thread
74 // qDebug() << "Picked" << thr << "since it was idling";
75 chosenThread = thr;
76 break;
77 }
78 if (!bestThread || sc < minSocketCount) {
79 minSocketCount = sc;
80 bestThread = thr;
81 }
82 }
83
84 // Use an existing non-idling thread, if we reached maxThreads
85 if (!chosenThread && bestThread && m_threads.count() == m_maxThreadCount) {
86 chosenThread = bestThread;
87 }
88
89 // Create new thread
90 if (!chosenThread) {
91 chosenThread = new KDSoapServerThread(nullptr);
92 // qDebug() << "Creating KDSoapServerThread" << chosenThread;
93 m_threads.append(chosenThread);
94 chosenThread->startThread();
95 }
96 return chosenThread;
97}
98
99void KDSoapThreadPool::handleIncomingConnection(int socketDescriptor, KDSoapServer *server)
100{
101 // First, pick or create a thread.
102 KDSoapServerThread *chosenThread = d->chooseNextThread();
103
104 // Then create the socket, and register it in the corresponding socket-pool, and move it to the thread.
105 chosenThread->handleIncomingConnection(socketDescriptor, server);
106}
107
109{
110 int sc = 0;
111 for (KDSoapServerThread *thread : qAsConst(d->m_threads)) {
112 sc += thread->socketCountForServer(server);
113 }
114 return sc;
115}
116
118{
120 for (KDSoapServerThread *thread : qAsConst(d->m_threads)) {
121 thread->disconnectSocketsForServer(server, readyThreads);
122 }
123 // Wait for all threads to have disconnected their sockets
124 readyThreads.acquire(d->m_threads.count());
125}
126
128{
129 int sc = 0;
130 for (KDSoapServerThread *thread : qAsConst(d->m_threads)) {
131 sc += thread->totalConnectionCountForServer(server);
132 }
133 return sc;
134}
135
137{
138 for (KDSoapServerThread *thread : qAsConst(d->m_threads)) {
139 thread->resetTotalConnectionCountForServer(server);
140 }
141}
142
143#include "moc_KDSoapThreadPool.cpp"
int maxThreadCount() const
int totalConnectionCount(const KDSoapServer *server) const
void resetTotalConnectionCount(const KDSoapServer *server)
void setMaxThreadCount(int maxThreadCount)
KDSoapThreadPool(QObject *parent=0)
int numConnectedSockets(const KDSoapServer *server) const
void disconnectSockets(KDSoapServer *server)
T qobject_cast(QObject *object)
QThread * thread() const const
bool wait(QDeadlineTimer deadline)

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-soap/
Generated on Sat Apr 20 2024 00:04:25 for KD SOAP API Documentation by doxygen 1.9.8