diff options
-rw-r--r-- | src/network/access/qhttp2connection.cpp | 32 | ||||
-rw-r--r-- | src/network/access/qhttp2connection_p.h | 5 | ||||
-rw-r--r-- | src/network/access/qhttp2protocolhandler.cpp | 5 |
3 files changed, 34 insertions, 8 deletions
diff --git a/src/network/access/qhttp2connection.cpp b/src/network/access/qhttp2connection.cpp index 415f0cd9f5..5df31fa36c 100644 --- a/src/network/access/qhttp2connection.cpp +++ b/src/network/access/qhttp2connection.cpp @@ -805,7 +805,7 @@ QHttp2Connection::createStreamInternal() if (m_goingAway) return { QHttp2Connection::CreateStreamError::ReceivedGOAWAY }; const quint32 streamID = m_nextStreamID; - if (size_t(m_maxConcurrentStreams) <= size_t(numActiveStreams())) + if (size_t(m_maxConcurrentStreams) <= size_t(numActiveLocalStreams())) return { QHttp2Connection::CreateStreamError::MaxConcurrentStreamsReached }; m_nextStreamID += 2; return { createStreamInternal_impl(streamID) }; @@ -823,12 +823,32 @@ QHttp2Stream *QHttp2Connection::createStreamInternal_impl(quint32 streamID) return stream; } -qsizetype QHttp2Connection::numActiveStreams() const noexcept +qsizetype QHttp2Connection::numActiveStreamsImpl(quint32 mask) const noexcept { - return std::count_if(m_streams.cbegin(), m_streams.cend(), - [](const QPointer<QHttp2Stream> &stream) { - return stream && stream->state() == QHttp2Stream::State::Open; - }); + const auto shouldCount = [mask](const QPointer<QHttp2Stream> &stream) -> bool { + return stream && (stream->streamID() & 1) == mask; + }; + return std::count_if(m_streams.cbegin(), m_streams.cend(), shouldCount); +} + +/*! + \internal + The number of streams the remote peer has started that are still active. +*/ +qsizetype QHttp2Connection::numActiveRemoteStreams() const noexcept +{ + const quint32 RemoteMask = m_connectionType == Type::Client ? 0 : 1; + return numActiveStreamsImpl(RemoteMask); +} + +/*! + \internal + The number of streams we have started that are still active. +*/ +qsizetype QHttp2Connection::numActiveLocalStreams() const noexcept +{ + const quint32 LocalMask = m_connectionType == Type::Client ? 1 : 0; + return numActiveStreamsImpl(LocalMask); } /*! diff --git a/src/network/access/qhttp2connection_p.h b/src/network/access/qhttp2connection_p.h index 4704942389..649ad385c9 100644 --- a/src/network/access/qhttp2connection_p.h +++ b/src/network/access/qhttp2connection_p.h @@ -20,6 +20,7 @@ #include <QtCore/qobject.h> #include <QtCore/qhash.h> #include <QtCore/qvarlengtharray.h> +#include <QtCore/qxpfunctional.h> #include <QtNetwork/qhttp2configuration.h> #include <QtNetwork/qtcpsocket.h> @@ -263,7 +264,9 @@ private: const char *message); // Connection failed to be established? void setH2Configuration(QHttp2Configuration config); void closeSession(); - qsizetype numActiveStreams() const noexcept; + qsizetype numActiveStreamsImpl(quint32 mask) const noexcept; + qsizetype numActiveRemoteStreams() const noexcept; + qsizetype numActiveLocalStreams() const noexcept; bool sendClientPreface(); bool sendSETTINGS(); diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index b2b3676fd7..376f7251ff 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -326,7 +326,10 @@ bool QHttp2ProtocolHandler::sendRequest() initReplyFromPushPromise(message, key); } - const qint64 streamsToUse = qBound(0, qint64(maxConcurrentStreams) - activeStreams.size(), + const auto isClientSide = [](const auto &pair) -> bool { return (pair.first & 1) == 1; }; + const auto activeClientSideStreams = std::count_if( + activeStreams.constKeyValueBegin(), activeStreams.constKeyValueEnd(), isClientSide); + const qint64 streamsToUse = qBound(0, qint64(maxConcurrentStreams) - activeClientSideStreams, requests.size()); auto it = requests.begin(); for (qint64 i = 0; i < streamsToUse; ++i) { |