summaryrefslogtreecommitdiff
path: root/src/websockets/qwebsocketframe.cpp
diff options
context:
space:
mode:
authorRyan Chu <ryan.chu@qt.io>2019-06-28 14:37:05 +0200
committerRyan Chu <ryan.chu@qt.io>2019-08-23 15:28:46 +0200
commitb14f5f59a3ae96949e6a33302385a751d6448182 (patch)
tree5594f3816864eaf6757bcadeecebb84a67b8c2e7 /src/websockets/qwebsocketframe.cpp
parent24894c032719157a2d738f03e0c70d3ff0cf1782 (diff)
downloadqtwebsockets-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.cpp62
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;
}
}
}