diff options
author | Ryan Chu <ryan.chu@qt.io> | 2019-06-28 14:37:05 +0200 |
---|---|---|
committer | Ryan Chu <ryan.chu@qt.io> | 2019-08-23 15:28:46 +0200 |
commit | b14f5f59a3ae96949e6a33302385a751d6448182 (patch) | |
tree | 5594f3816864eaf6757bcadeecebb84a67b8c2e7 /src/websockets/qwebsocketframe.cpp | |
parent | 24894c032719157a2d738f03e0c70d3ff0cf1782 (diff) | |
download | qtwebsockets-b14f5f59a3ae96949e6a33302385a751d6448182.tar.gz |
Remove waitForReadyRead from QWebSocketFrame::readFrame
Asynchronously process socket frame in QWebSocketDataProcessor::process.
If the processing of QWebSocketFrame is not done and waiting for more
data, QWebSocketDataProcessor::process will return the control and wait
for next readyRead signal to continue processing the unfinished socket
frame. QWebSocketDataProcessor::process gets timeout after 5 seconds,
and then an errorEncountered signal will be emitted.
Fixes: QTBUG-74464
Change-Id: I03b7f874c1c266617e7eadf59c59ae43fa8540ce
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/websockets/qwebsocketframe.cpp')
-rw-r--r-- | src/websockets/qwebsocketframe.cpp | 62 |
1 files changed, 29 insertions, 33 deletions
diff --git a/src/websockets/qwebsocketframe.cpp b/src/websockets/qwebsocketframe.cpp index 5b10e02..11373a7 100644 --- a/src/websockets/qwebsocketframe.cpp +++ b/src/websockets/qwebsocketframe.cpp @@ -188,7 +188,7 @@ void QWebSocketFrame::swap(QWebSocketFrame &other) */ QWebSocketProtocol::CloseCode QWebSocketFrame::closeCode() const { - return m_closeCode; + return isDone() ? m_closeCode : QWebSocketProtocol::CloseCodeGoingAway; } /*! @@ -196,7 +196,7 @@ QWebSocketProtocol::CloseCode QWebSocketFrame::closeCode() const */ QString QWebSocketFrame::closeReason() const { - return m_closeReason; + return isDone() ? m_closeReason : tr("Waiting for more data from socket."); } /*! @@ -289,67 +289,63 @@ void QWebSocketFrame::clear() */ bool QWebSocketFrame::isValid() const { - return m_isValid; + return isDone() && m_isValid; } -#define WAIT_FOR_MORE_DATA(returnState) \ - { needMoreData = true; \ - m_processingState = (returnState); } +/*! + \internal + */ +bool QWebSocketFrame::isDone() const +{ + return m_processingState == PS_DISPATCH_RESULT; +} /*! \internal */ void QWebSocketFrame::readFrame(QIODevice *pIoDevice) { - bool isDone = false; - while (!isDone) + while (true) { - bool needMoreData = false; switch (m_processingState) { case PS_READ_HEADER: m_processingState = readFrameHeader(pIoDevice); - if (m_processingState == PS_WAIT_FOR_MORE_DATA) - WAIT_FOR_MORE_DATA(PS_READ_HEADER); + if (m_processingState == PS_WAIT_FOR_MORE_DATA) { + m_processingState = PS_READ_HEADER; + return; + } break; case PS_READ_PAYLOAD_LENGTH: m_processingState = readFramePayloadLength(pIoDevice); - if (m_processingState == PS_WAIT_FOR_MORE_DATA) - WAIT_FOR_MORE_DATA(PS_READ_PAYLOAD_LENGTH); + if (m_processingState == PS_WAIT_FOR_MORE_DATA) { + m_processingState = PS_READ_PAYLOAD_LENGTH; + return; + } break; case PS_READ_MASK: m_processingState = readFrameMask(pIoDevice); - if (m_processingState == PS_WAIT_FOR_MORE_DATA) - WAIT_FOR_MORE_DATA(PS_READ_MASK); + if (m_processingState == PS_WAIT_FOR_MORE_DATA) { + m_processingState = PS_READ_MASK; + return; + } break; case PS_READ_PAYLOAD: m_processingState = readFramePayload(pIoDevice); - if (m_processingState == PS_WAIT_FOR_MORE_DATA) - WAIT_FOR_MORE_DATA(PS_READ_PAYLOAD); + if (m_processingState == PS_WAIT_FOR_MORE_DATA) { + m_processingState = PS_READ_PAYLOAD; + return; + } break; case PS_DISPATCH_RESULT: - m_processingState = PS_DISPATCH_RESULT; - isDone = true; - break; + return; default: Q_UNREACHABLE(); - break; - } - - if (needMoreData) { - // TODO: waitForReadyRead should really be changed - // now, when a WebSocket is used in a GUI thread - // the GUI will hang for at most 5 seconds - // maybe, a QStateMachine should be used - if (!pIoDevice->waitForReadyRead(5000)) { - setError(QWebSocketProtocol::CloseCodeGoingAway, - tr("Timeout when reading data from socket.")); - m_processingState = PS_DISPATCH_RESULT; - } + return; } } } |