summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2018-03-15 08:54:25 +0100
committerOliver Wolff <oliver.wolff@qt.io>2018-04-06 05:31:03 +0000
commit29b21e83ba4af67e8ea4925e7a10bc9c6f5a13f6 (patch)
tree8cf8cc4079e5ab3e0e676dcbce0349771a7cc914
parent20d2f024851d1b4c335d6288bd9aa6942ed02d4e (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>
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp26
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h2
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);