summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2016-04-01 13:19:10 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2016-04-07 11:45:41 +0000
commitccb693299e6ef633d3ac330961c872a03815c93c (patch)
treef9f4c5835cbaa2189504d33b95a3ea4ffee08032
parent115d4fc8cc1816d70f41c839d7eaa4e24ff86db2 (diff)
Rework toggling the state of read notifier on unbuffered socket
To avoid infinite loop on unbuffered socket, previous implementation always disabled the read notifications before emitting a readyRead() signal. So, it's very likely that the socket will toggle the state of notifier twice (on->off->on) in one notification cycle. This patch prevents this unnecessary toggling by deferring the notification disabling in canReadNotification() to the next notification cycle. Change-Id: Iebc5a7ad18a6f40ea1cf63e7f1b12f6c180cbf7a Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>
-rw-r--r--src/network/socket/qabstractsocket.cpp12
-rw-r--r--src/network/socket/qabstractsocket_p.h1
-rw-r--r--src/network/socket/qudpsocket.cpp3
3 files changed, 13 insertions, 3 deletions
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 731afd4e36..03f2ddb968 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -563,6 +563,7 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
cachedSocketDescriptor(-1),
readBufferMaxSize(0),
isBuffered(false),
+ hasPendingData(false),
connectTimer(0),
disconnectTimer(0),
hostLookupId(-1),
@@ -593,6 +594,7 @@ void QAbstractSocketPrivate::resetSocketLayer()
qDebug("QAbstractSocketPrivate::resetSocketLayer()");
#endif
+ hasPendingData = false;
if (socketEngine) {
socketEngine->close();
socketEngine->disconnect();
@@ -683,8 +685,13 @@ bool QAbstractSocketPrivate::canReadNotification()
qDebug("QAbstractSocketPrivate::canReadNotification()");
#endif
- if (!isBuffered)
- socketEngine->setReadNotificationEnabled(false);
+ if (!isBuffered) {
+ if (hasPendingData) {
+ socketEngine->setReadNotificationEnabled(false);
+ return true;
+ }
+ hasPendingData = true;
+ }
// If buffered, read data from the socket into the read buffer
qint64 newBytes = 0;
@@ -2434,6 +2441,7 @@ qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
d->state = QAbstractSocket::UnconnectedState;
} else {
// Only do this when there was no error
+ d->hasPendingData = false;
d->socketEngine->setReadNotificationEnabled(true);
}
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index ab642e039b..3164c96c1e 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -143,6 +143,7 @@ public:
qint64 readBufferMaxSize;
bool isBuffered;
+ bool hasPendingData;
QTimer *connectTimer;
QTimer *disconnectTimer;
diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp
index c406009069..083648bc23 100644
--- a/src/network/socket/qudpsocket.cpp
+++ b/src/network/socket/qudpsocket.cpp
@@ -398,7 +398,8 @@ qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *addres
readBytes = d->socketEngine->readDatagram(data, maxSize);
}
- d_func()->socketEngine->setReadNotificationEnabled(true);
+ d->hasPendingData = false;
+ d->socketEngine->setReadNotificationEnabled(true);
if (readBytes < 0)
d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
return readBytes;