From cdc6938bbf854cc15bb8bf7689e27ea3471578e4 Mon Sep 17 00:00:00 2001 From: Dennis Oberst Date: Thu, 17 Jul 2025 15:53:05 +0200 Subject: [PATCH] QGrpcHttp2Channel: Fix deadline timeout start location We should start the deadline-timer when the actual call is beginning and this is indicated when the initial headers have been sent and not the stream that has been attached. As a drive-by mark the timer as single-shot. Pick-to: 6.10 6.9 6.8 Change-Id: I1eb58d143e4934a3c0770cd3ff24ed47972a5289 Reviewed-by: Alexey Edelev --- src/grpc/qgrpchttp2channel.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/grpc/qgrpchttp2channel.cpp b/src/grpc/qgrpchttp2channel.cpp index 4cdd847d..cebaf5b3 100644 --- a/src/grpc/qgrpchttp2channel.cpp +++ b/src/grpc/qgrpchttp2channel.cpp @@ -417,8 +417,10 @@ Http2Handler::Http2Handler(const std::shared_ptr &operati QObject::connect(channelOpPtr, &QGrpcOperationContext::writeMessageRequested, this, &Http2Handler::writeMessage); } + QObject::connect(channelOpPtr, &QGrpcOperationContext::finished, &m_deadlineTimer, &QTimer::stop); + m_deadlineTimer.setSingleShot(true); writeMessage(channelOpPtr->argument()); } @@ -517,16 +519,6 @@ void Http2Handler::attachStream(QHttp2Stream *stream_) QObject::connect(m_stream.get(), &QHttp2Stream::uploadFinished, this, &Http2Handler::processQueue); - std::optional deadline; - if (auto dt = channelOpPtr->callOptions().deadlineTimeout()) - deadline = dt; - else if (auto chdt = channel()->channelOptions().deadlineTimeout()) - deadline = chdt; - if (deadline) { - // We have an active stream and a deadline. It's time to start the timer. - QObject::connect(&m_deadlineTimer, &QTimer::timeout, this, &Http2Handler::deadlineTimeout); - m_deadlineTimer.start(*deadline); - } } QGrpcOperationContext *Http2Handler::operation() const @@ -643,6 +635,16 @@ void Http2Handler::sendInitialRequest() m_state = State::RequestHeadersSent; m_initialHeaders.clear(); processQueue(); + + std::optional deadline = operation()->callOptions().deadlineTimeout(); + if (!deadline) + deadline = channel()->channelOptions().deadlineTimeout(); + if (deadline) { + // We have an active stream, a deadline and the initial headers have + // just been sent. It's time to start the timer. + connect(&m_deadlineTimer, &QTimer::timeout, this, &Http2Handler::deadlineTimeout); + m_deadlineTimer.start(*deadline); + } } // The core logic for sending the already serialized data through the HTTP/2 stream.