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