diff options
author | Oliver Wolff <oliver.wolff@qt.io> | 2018-03-15 08:54:25 +0100 |
---|---|---|
committer | Oliver Wolff <oliver.wolff@qt.io> | 2018-04-06 05:31:03 +0000 |
commit | 29b21e83ba4af67e8ea4925e7a10bc9c6f5a13f6 (patch) | |
tree | 8cf8cc4079e5ab3e0e676dcbce0349771a7cc914 /src/network/socket | |
parent | 20d2f024851d1b4c335d6288bd9aa6942ed02d4e (diff) |
winrt: process pending data before closing a socket connection
If data is received and the remote immediately closes the connection,
it was possible that data was lost. If a remote closes the connection
make sure that any pending data is processed, before signaling closing
of the socket.
Change-Id: Ia94a616a31184fd28695919baaff99811fe0f1dd
Reviewed-by: Andre de la Rocha <andre.rocha@qt.io>
Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io>
Diffstat (limited to 'src/network/socket')
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt.cpp | 26 | ||||
-rw-r--r-- | src/network/socket/qnativesocketengine_winrt_p.h | 2 |
2 files changed, 22 insertions, 6 deletions
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 4470d19d8c..e427b19896 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -548,7 +548,7 @@ QNativeSocketEngine::QNativeSocketEngine(QObject *parent) #endif connect(this, SIGNAL(connectionReady()), SLOT(connectionNotification()), Qt::QueuedConnection); - connect(this, SIGNAL(readReady()), SLOT(readNotification()), Qt::QueuedConnection); + connect(this, SIGNAL(readReady()), SLOT(processReadReady()), Qt::QueuedConnection); connect(this, SIGNAL(writeReady()), SLOT(writeNotification()), Qt::QueuedConnection); connect(d->worker, &SocketEngineWorker::connectOpFinished, this, &QNativeSocketEngine::handleConnectOpFinished, Qt::QueuedConnection); @@ -872,12 +872,15 @@ void QNativeSocketEngine::close() if (d->closingDown) return; - d->closingDown = true; + if (d->pendingReadNotification) + processReadReady(); + d->closingDown = true; d->notifyOnRead = false; d->notifyOnWrite = false; d->notifyOnException = false; + d->emitReadReady = false; HRESULT hr; if (d->socketType == QAbstractSocket::TcpSocket) { @@ -1019,8 +1022,10 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen) << copyLength << "of" << d->worker->pendingData.length() << "bytes"; readData = d->worker->pendingData.left(maxlen); d->worker->pendingData.remove(0, maxlen); - if (d->notifyOnRead) + if (d->notifyOnRead) { + d->pendingReadNotification = true; emit readReady(); + } } mutexLocker.unlock(); @@ -1369,6 +1374,7 @@ void QNativeSocketEngine::handleNewData() if (d->socketType == QAbstractSocket::UdpSocket && !d->worker->emitDataReceived) return; qCDebug(lcNetworkSocketVerbose) << this << Q_FUNC_INFO << "Emitting readReady"; + d->pendingReadNotification = true; emit readReady(); d->worker->emitDataReceived = false; d->emitReadReady = false; @@ -1389,9 +1395,17 @@ void QNativeSocketEngine::handleTcpError(QAbstractSocket::SocketError error) } d->setError(error, errorString); - d->socketState = QAbstractSocket::UnconnectedState; - if (d->notifyOnRead) - emit readReady(); + close(); +} + +void QNativeSocketEngine::processReadReady() +{ + Q_D(QNativeSocketEngine); + if (d->closingDown) + return; + + d->pendingReadNotification = false; + readNotification(); } bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol) diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index f47e2a7dd7..6688bfe35c 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -184,6 +184,7 @@ private slots: WinRTSocketEngine::ErrorString errorString); void handleNewData(); void handleTcpError(QAbstractSocket::SocketError error); + void processReadReady(); private: Q_DECLARE_PRIVATE(QNativeSocketEngine) @@ -228,6 +229,7 @@ private: EventRegistrationToken connectionToken; bool emitReadReady = true; + bool pendingReadNotification = false; HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); |