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>
This commit is contained in:
Oliver Wolff 2018-03-15 08:54:25 +01:00
parent 20d2f02485
commit 29b21e83ba
2 changed files with 22 additions and 6 deletions

View File

@ -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)

View File

@ -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);