summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
authorMartin Petersson <Martin.Petersson@nokia.com>2012-07-12 12:52:17 +0200
committerQt by Nokia <qt-info@nokia.com>2012-07-30 10:43:50 +0200
commit4d38a3b2dabda9c89c1b257820911aa987f04d2b (patch)
tree46c0e5697e204f43f49804208e5cf8370afdb5c5 /src/network/socket
parentada38c75cccb33947107212c08e7b080e6b54f84 (diff)
QtNetwork: Better detection of connection failures on Windows
If the error code from WSAConnect is WSAEWOULDBLOCK, then the operation proceeds but the outcome is not known at that time. We then check SO_ERROR's value to detect errors. But if that call returns 0 this could indicate that the value is still not know. In this case we try one more time to increase the chance of getting the correct value. This fixed the tst_QNetworkReply::getFromUnreachableIp auto test on Windows. Change-Id: I25008aca062b2f823e3d93ebb0ae456d7e4a6ecc Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp62
1 files changed, 41 insertions, 21 deletions
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 59e851714f..aebb9dc40e 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -683,28 +683,48 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
// unfinished operation.
int value = 0;
QT_SOCKLEN_T valueSize = sizeof(value);
- if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
- if (value == WSAECONNREFUSED) {
- setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
+ bool tryAgain = false;
+ bool errorDetected = false;
+ int tries = 0;
+ do {
+ if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
+ if (value == WSAECONNREFUSED) {
+ setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ errorDetected = true;
+ break;
+ }
+ if (value == WSAETIMEDOUT) {
+ setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ errorDetected = true;
+ break;
+ }
+ if (value == WSAEHOSTUNREACH) {
+ setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ errorDetected = true;
+ break;
+ }
+ if (value == WSAEADDRNOTAVAIL) {
+ setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ errorDetected = true;
+ break;
+ }
+ if (value == NOERROR) {
+ // When we get WSAEWOULDBLOCK the outcome was not known, so a
+ // NOERROR might indicate that the result of the operation
+ // is still unknown. We try again to increase the chance that we did
+ // get the correct result.
+ tryAgain = !tryAgain;
+ }
}
- if (value == WSAETIMEDOUT) {
- setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- }
- if (value == WSAEHOSTUNREACH) {
- setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- }
- if (value == WSAEADDRNOTAVAIL) {
- setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
- socketState = QAbstractSocket::UnconnectedState;
- break;
- }
- }
+ tries++;
+ } while (tryAgain && (tries < 2));
+
+ if (errorDetected)
+ break;
// fall through
}
case WSAEINPROGRESS: