summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2017-10-11 15:19:17 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2017-10-27 19:22:23 +0000
commite8d2e831a4054a7519c60b11d1ba9e6bec85c3bd (patch)
treece7f716543054e28bacc5296d93adf035f548ac4 /src/network/ssl
parent754b636053869d8b673a0e131ae6470a5adace3b (diff)
QSslSocket::waitForDisconnected(): flush write buffer before waiting
Otherwise, the plain socket might be blocked indefinitely on waiting for socket activity. This issue is tested by tst_QSslSocket::disconnectFromHostWhenConnected() which was unstable in CI. Task-number: QTBUG-64016 Change-Id: I6a1a111dea4d1d1adaf55e6a90c0c5f995a270af Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qsslsocket.cpp14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 9d11506fcb..8eba5db9fe 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1686,7 +1686,8 @@ bool QSslSocket::waitForDisconnected(int msecs)
if (!d->plainSocket)
return false;
- if (d->mode == UnencryptedMode)
+ // Forward to the plain socket unless the connection is secure.
+ if (d->mode == UnencryptedMode && !d->autoStartHandshake)
return d->plainSocket->waitForDisconnected(msecs);
QElapsedTimer stopWatch;
@@ -1697,6 +1698,17 @@ bool QSslSocket::waitForDisconnected(int msecs)
if (!waitForEncrypted(msecs))
return false;
}
+ // We are delaying the disconnect, if the write buffer is not empty.
+ // So, start the transmission.
+ if (!d->writeBuffer.isEmpty())
+ d->transmit();
+
+ // At this point, the socket might be disconnected, if disconnectFromHost()
+ // was called just after the connectToHostEncrypted() call. Also, we can
+ // lose the connection as a result of the transmit() call.
+ if (state() == UnconnectedState)
+ return true;
+
bool retVal = d->plainSocket->waitForDisconnected(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
if (!retVal) {
setSocketState(d->plainSocket->state());