From 4e5a85dda56aac4a82c4d67bc0abd0b27cc01e9c Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 15 Apr 2019 19:52:49 +0800 Subject: [PATCH 1/3] Remove closed connections immediately Previously it relied on a timer to drop dead connections but that proved to be too slow when there is an incoming burst of connections. Fixes #10487. --- src/base/http/server.cpp | 13 ++++++++++--- src/base/http/server.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp index 778b94b39..72fec2d47 100644 --- a/src/base/http/server.cpp +++ b/src/base/http/server.cpp @@ -98,15 +98,22 @@ void Server::incomingConnection(qintptr socketDescriptor) Connection *c = new Connection(serverSocket, m_requestHandler, this); m_connections.append(c); + connect(serverSocket, &QAbstractSocket::disconnected, this, [c, this]() { removeConnection(c); }); +} + +void Server::removeConnection(Connection *connection) +{ + m_connections.removeOne(connection); + connection->deleteLater(); } void Server::dropTimedOutConnection() { QMutableListIterator i(m_connections); while (i.hasNext()) { - auto connection = i.next(); - if (connection->isClosed() || connection->hasExpired(KEEP_ALIVE_DURATION)) { - delete connection; + Connection *connection = i.next(); + if (connection->hasExpired(KEEP_ALIVE_DURATION)) { + connection->deleteLater(); i.remove(); } } diff --git a/src/base/http/server.h b/src/base/http/server.h index 91dc26dab..8f4e35123 100644 --- a/src/base/http/server.h +++ b/src/base/http/server.h @@ -63,6 +63,7 @@ namespace Http private: void incomingConnection(qintptr socketDescriptor); + void removeConnection(Connection *connection); IRequestHandler *m_requestHandler; QList m_connections; // for tracking persistent connections From df6df2096993253b23ae5fc9aada2b91b727a9e0 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Mon, 15 Apr 2019 21:22:11 +0800 Subject: [PATCH 2/3] Use QSet for tracking server connections We don't need to maintain order between connections so QSet would be more suitable. --- src/base/http/server.cpp | 6 +++--- src/base/http/server.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp index 72fec2d47..2b27c3037 100644 --- a/src/base/http/server.cpp +++ b/src/base/http/server.cpp @@ -97,19 +97,19 @@ void Server::incomingConnection(qintptr socketDescriptor) #endif Connection *c = new Connection(serverSocket, m_requestHandler, this); - m_connections.append(c); + m_connections.insert(c); connect(serverSocket, &QAbstractSocket::disconnected, this, [c, this]() { removeConnection(c); }); } void Server::removeConnection(Connection *connection) { - m_connections.removeOne(connection); + m_connections.remove(connection); connection->deleteLater(); } void Server::dropTimedOutConnection() { - QMutableListIterator i(m_connections); + QMutableSetIterator i(m_connections); while (i.hasNext()) { Connection *connection = i.next(); if (connection->hasExpired(KEEP_ALIVE_DURATION)) { diff --git a/src/base/http/server.h b/src/base/http/server.h index 8f4e35123..48846d533 100644 --- a/src/base/http/server.h +++ b/src/base/http/server.h @@ -31,6 +31,7 @@ #ifndef HTTP_SERVER_H #define HTTP_SERVER_H +#include #include #ifndef QT_NO_OPENSSL @@ -66,7 +67,7 @@ namespace Http void removeConnection(Connection *connection); IRequestHandler *m_requestHandler; - QList m_connections; // for tracking persistent connections + QSet m_connections; // for tracking persistent connections #ifndef QT_NO_OPENSSL QList safeCipherList() const; From e365d57063fe8a49c2583248b6eca432b9b5328c Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 10 Apr 2019 16:33:06 +0800 Subject: [PATCH 3/3] Fix unsafe type narrowing Appending the warning below: qBittorrent\src\base/utils/version.h(176): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data qBittorrent\src\base/utils/version.h(185): note: see reference to function template instantiation 'std::array Utils::Version::parseList(const StringsList &)' being compiled with [ T=unsigned short, StringsList=QList ] --- src/base/utils/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/utils/version.h b/src/base/utils/version.h index e82e3b6e9..b4bb4fee6 100644 --- a/src/base/utils/version.h +++ b/src/base/utils/version.h @@ -168,12 +168,12 @@ namespace Utils { if ((static_cast(versionParts.size()) > N) || (static_cast(versionParts.size()) < Mandatory)) - throw std::runtime_error ("Incorrect number of version components"); + throw std::runtime_error("Incorrect number of version components"); bool ok = false; ComponentsArray res {{}}; for (std::size_t i = 0; i < static_cast(versionParts.size()); ++i) { - res[i] = static_cast(versionParts[i].toInt(&ok)); + res[i] = static_cast(versionParts[static_cast(i)].toInt(&ok)); if (!ok) throw std::runtime_error("Can not parse version component"); }