Move the socket error handling to the common place

Instead of connecting each and every Http2Handler to the socket error,
use QGrpcHttp2ChannelPrivate::handleSocketError to iterate over
alive Http2Handler and send errors right from this handler. This saves
some memory and time on handling errorOccurred signal.

Pick-to: 6.10 6.9 6.8
Change-Id: I907e24425aafe3dccca19100d02fe7adffb1fdaa
Reviewed-by: Dennis Oberst <dennis.oberst@qt.io>
This commit is contained in:
Alexey Edelev 2025-08-13 13:27:04 +02:00
parent 66e4a79353
commit 7da4e6886a
1 changed files with 14 additions and 29 deletions

View File

@ -365,24 +365,6 @@ public:
private:
enum ConnectionState { Connecting = 0, Connected, SettingsReceived, Error };
template <typename T>
void connectErrorHandler(T *socket, Http2Handler *handler)
{
connect(socket, &T::errorOccurred, handler, [this, handler](auto error) {
if (m_isInsideSocketErrorOccurred) {
qCCritical(lcChannel,
"[%p] Socket errorOccurred signal triggered while "
"already handling an error",
this);
return;
}
m_isInsideSocketErrorOccurred = true;
auto reset = qScopeGuard([this]() { m_isInsideSocketErrorOccurred = false; });
emit handler->finish({ StatusCode::Unavailable,
tr("Network error occurred: %1").arg(error) });
});
}
void ensureSchemeIsValid(QLatin1String expected);
bool createHttp2Stream(Http2Handler *handler);
@ -1049,17 +1031,6 @@ void QGrpcHttp2ChannelPrivate::processOperation(QGrpcOperationContext *operation
}
auto *handler = new Http2Handler(this, operationContext, endStream);
#if QT_CONFIG(localserver)
if (m_isLocalSocket) {
connectErrorHandler<QLocalSocket>(static_cast<QLocalSocket *>(m_socket.get()), handler);
} else
#endif
{
connectErrorHandler<QAbstractSocket>(static_cast<QAbstractSocket *>(m_socket.get()),
handler);
}
if (m_connection && !createHttp2Stream(handler))
return;
@ -1124,6 +1095,20 @@ void QGrpcHttp2ChannelPrivate::createHttp2Connection()
void QGrpcHttp2ChannelPrivate::handleSocketError(const QByteArray &errorCode)
{
for_each_non_expired_handler([this, &errorCode](Http2Handler *handler) {
if (m_isInsideSocketErrorOccurred) {
qCCritical(lcChannel,
"[%p] Socket errorOccurred signal triggered while "
"already handling an error",
this);
return;
}
m_isInsideSocketErrorOccurred = true;
auto reset = qScopeGuard([this]() { m_isInsideSocketErrorOccurred = false; });
emit handler->finish({ StatusCode::Unavailable,
tr("Network error occurred: %1").arg(errorCode) });
});
qCDebug(lcChannel, "[%p] Socket error occurred (code=%s, details=%s, hostUri=%s)", this,
errorCode.constData(), qPrintable(m_socket->errorString()),
qPrintable(hostUri.toString()));