MythTV master
mythhttpthreadpool.cpp
Go to the documentation of this file.
1// C++ headers
2#include <algorithm>
3
4// MythTV
5#include "mythlogging.h"
8
9#define LOC QString("HTTPPool: ")
10
12{
13 // Number of connections processed concurrently
14 m_maxThreads = static_cast<size_t>(std::max(QThread::idealThreadCount() * 2, 4));
15
16 // Don't allow more connections than we can process, it causes browsers
17 // to open lots of new connections instead of reusing existing ones
18 setMaxPendingConnections(static_cast<int>(m_maxThreads));
19 LOG(VB_GENERAL, LOG_INFO, LOC + QString("Using maximum %1 threads").arg(m_maxThreads));
20}
21
23{
24 for (auto * thread : m_threads)
25 {
26 thread->Quit();
27 thread->wait();
28 delete thread;
29 }
30}
31
33{
34 if (m_upgradedThreads.size() > m_threads.size())
35 LOG(VB_GENERAL, LOG_ERR, LOC + "Threadpool error: upgraded count is higher than total");
36 return m_maxThreads - (m_threads.size() - m_upgradedThreads.size());
37}
38
40{
41 return m_maxThreads;
42}
43
45{
46 return m_threads.size();
47}
48
50{
51 if (Thread)
52 m_threads.emplace_back(Thread);
53}
54
56{
57 auto * qthread = dynamic_cast<QThread*>(sender());
58 auto found = std::ranges::find_if(std::as_const(m_threads),
59 [&qthread](MythHTTPThread* Thread) { return Thread->qthread() == qthread; });
60 if (found == m_threads.cend())
61 {
62 LOG(VB_GENERAL, LOG_ERR, LOC + "Unknown HTTP thread finished");
63 return;
64 }
65
66 // Remove from list of upgraded threads if necessary
67 auto upgraded = std::ranges::find_if(std::as_const(m_upgradedThreads),
68 [&qthread](MythHTTPThread* Thread) { return Thread->qthread() == qthread; });
69 if (upgraded != m_upgradedThreads.cend())
70 m_upgradedThreads.erase(upgraded);
71
72 LOG(VB_HTTP, LOG_INFO, LOC + QString("Deleting thread '%1'").arg((*found)->objectName()));
73 delete *found;
74 m_threads.erase(found);
75}
76
78{
79 auto found = std::ranges::find_if(std::as_const(m_threads),
80 [&Thread](MythHTTPThread* QThread) { return QThread->qthread() == Thread; });
81 if (found == m_threads.cend())
82 {
83 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unknown thread '%1' upgraded").arg(Thread->objectName()));
84 return;
85 }
86
87 m_upgradedThreads.emplace_back(*found);
88 auto standard = m_threads.size() - m_upgradedThreads.size();
89 auto upgraded = m_upgradedThreads.size();
90 LOG(VB_HTTP, LOG_INFO, LOC + QString("Thread '%1' upgraded (Standard:%2 Upgraded:%3)")
91 .arg(Thread->objectName()).arg(standard).arg(upgraded));
92
93 // There is no reasonable way of limiting the number of upgraded sockets (i.e.
94 // websockets) as we have no way of knowing what the client intends to use the
95 // socket for when connecting. On the other hand, if we there are a sizeable
96 // number of valid clients - do we want to restrict the number of connections...
97 if (upgraded > m_maxThreads)
98 {
99 LOG(VB_GENERAL, LOG_WARNING, LOC + QString("%1 upgraded sockets - notional max is %2")
100 .arg(upgraded).arg(m_maxThreads));
101 }
102}
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
Definition: mthread.cpp:217
void ThreadUpgraded(QThread *Thread)
std::list< MythHTTPThread * > m_upgradedThreads
size_t MaxThreads() const
size_t ThreadCount() const
size_t AvailableThreads() const
std::list< MythHTTPThread * > m_threads
void AddThread(MythHTTPThread *Thread)
void setMaxPendingConnections(int n)
Definition: serverpool.h:94
#define LOC
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39