summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/access/qhttp2connection.cpp32
-rw-r--r--src/network/access/qhttp2connection_p.h5
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp5
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) {