Http2: speed up window_update for many streams

By keeping a list of blocked streams we can query just those instead of
any and all open streams when we get additional data transfer budget.

In the future we could additionally sort them by priority, if we start
taking priority into account.

Task-number: QTBUG-126772
Change-Id: Ieab250893e157d2c50b0db2fdc10aa2dc3c38048
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
(cherry picked from commit 1e57371695752d4112fa59c89d38e58b977d55bc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Mårten Nordheim 2024-07-19 12:38:16 +02:00 committed by Qt Cherry-pick Bot
parent 5ac0c50cae
commit 727b71bd2b
2 changed files with 13 additions and 2 deletions

View File

@ -457,6 +457,8 @@ void QHttp2Stream::maybeResumeUpload()
isUploadBlocked());
if (isUploadingDATA() && !isUploadBlocked())
internalSendDATA();
else
getConnection()->m_blockedStreams.insert(streamID());
}
/*!
@ -872,6 +874,10 @@ QHttp2Stream *QHttp2Connection::createStreamInternal_impl(quint32 streamID)
stream = new QHttp2Stream(this, streamID);
stream->m_recvWindow = streamInitialReceiveWindowSize;
stream->m_sendWindow = streamInitialSendWindowSize;
connect(stream, &QHttp2Stream::uploadBlocked, this, [this, stream] {
m_blockedStreams.insert(stream->streamID());
});
return stream;
}
@ -1721,10 +1727,13 @@ void QHttp2Connection::handleWINDOW_UPDATE()
if (!valid || qAddOverflow(sessionSendWindowSize, qint32(delta), &sum))
return connectionError(PROTOCOL_ERROR, "WINDOW_UPDATE invalid delta");
sessionSendWindowSize = sum;
for (const auto &stream : std::as_const(m_streams)) {
// Stream may have been unblocked, so maybe try to write again:
const auto blockedStreams = std::exchange(m_blockedStreams, {});
for (quint32 blockedStreamID : blockedStreams) {
const QPointer<QHttp2Stream> stream = m_streams.value(blockedStreamID);
if (!stream || !stream->isActive())
continue;
// Stream may have been unblocked, so maybe try to write again
if (stream->isUploadingDATA() && !stream->isUploadBlocked())
QMetaObject::invokeMethod(stream, &QHttp2Stream::maybeResumeUpload,
Qt::QueuedConnection);

View File

@ -19,6 +19,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qhash.h>
#include <QtCore/qset.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qxpfunctional.h>
#include <QtNetwork/qhttp2configuration.h>
@ -324,6 +325,7 @@ private:
QHttp2Configuration m_config;
QHash<quint32, QPointer<QHttp2Stream>> m_streams;
QSet<quint32> m_blockedStreams;
QHash<QUrl, quint32> m_promisedStreams;
QList<quint32> m_resetStreamIDs;