summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/socket/qabstractsocket.cpp29
-rw-r--r--src/network/socket/qabstractsocket.h1
-rw-r--r--src/network/socket/qabstractsocket_p.h2
3 files changed, 30 insertions, 2 deletions
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 955fee0..89a6e91 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -462,6 +462,7 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
isBuffered(false),
blockingTimeout(30000),
connectTimer(0),
+ disconnectTimer(0),
connectTimeElapsed(0),
hostLookupId(-1),
socketType(QAbstractSocket::UnknownSocketType),
@@ -497,9 +498,10 @@ void QAbstractSocketPrivate::resetSocketLayer()
socketEngine = 0;
cachedSocketDescriptor = -1;
}
- if (connectTimer) {
+ if (connectTimer)
connectTimer->stop();
- }
+ if (disconnectTimer)
+ disconnectTimer->stop();
}
/*! \internal
@@ -1094,6 +1096,15 @@ void QAbstractSocketPrivate::_q_abortConnectionAttempt()
}
}
+void QAbstractSocketPrivate::_q_forceDisconnect()
+{
+ Q_Q(QAbstractSocket);
+ if (socketEngine && socketEngine->isValid() && state == QAbstractSocket::ClosingState) {
+ socketEngine->close();
+ q->disconnectFromHost();
+ }
+}
+
/*! \internal
Reads data from the socket layer into the read buffer. Returns
@@ -2356,6 +2367,20 @@ void QAbstractSocket::disconnectFromHostImplementation()
// Wait for pending data to be written.
if (d->socketEngine && d->socketEngine->isValid() && (d->writeBuffer.size() > 0
|| d->socketEngine->bytesToWrite() > 0)) {
+ // hack: when we are waiting for the socket engine to write bytes (only
+ // possible when using Socks5 or HTTP socket engine), then close
+ // anyway after 2 seconds. This is to prevent a timeout on Mac, where we
+ // sometimes just did not get the write notifier from the underlying
+ // CFSocket and no progress was made.
+ if (d->writeBuffer.size() == 0 && d->socketEngine->bytesToWrite() > 0) {
+ if (!d->disconnectTimer) {
+ d->disconnectTimer = new QTimer(this);
+ connect(d->disconnectTimer, SIGNAL(timeout()), this,
+ SLOT(_q_forceDisconnect()), Qt::DirectConnection);
+ }
+ if (!d->disconnectTimer->isActive())
+ d->disconnectTimer->start(2000);
+ }
d->socketEngine->setWriteNotificationEnabled(true);
#if defined(QABSTRACTSOCKET_DEBUG)
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 5d94a01..5cfae17 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -216,6 +216,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_startConnecting(const QHostInfo &))
Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt())
Q_PRIVATE_SLOT(d_func(), void _q_testConnection())
+ Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
#ifdef QT3_SUPPORT
public:
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index 8ccddd3..acf82bf 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -93,6 +93,7 @@ public:
void _q_startConnecting(const QHostInfo &hostInfo);
void _q_testConnection();
void _q_abortConnectionAttempt();
+ void _q_forceDisconnect();
bool readSocketNotifierCalled;
bool readSocketNotifierState;
@@ -148,6 +149,7 @@ public:
int blockingTimeout;
QTimer *connectTimer;
+ QTimer *disconnectTimer;
int connectTimeElapsed;
int hostLookupId;