From 378e26dd14df808a55471330400984841ef414d4 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 11 Feb 2015 20:02:07 +0200 Subject: QUdpSocket: avoid infinite read notifier blocking There was a small amount of time between the last readDatagram() call and disabling a read notifier in case the socket had a pending datagram. If a new datagram arrived in this period, this qualified as absence of a datagram reader. Do not change the read notifier state because it is disabled on canReadNotification() entry and always enabled by the datagram reader. Thanks to Peter Seiderer, who investigated the same: "Querying hasPendingDatagrams() for enabling/disabling setReadNotificationEnabled() is racy (a new datagram could arrive after readDatagam() is called and before hasPendingDatagrams() is checked). But for unbuffered sockets the ReadNotification is already disabled before the readReady signal is emitted and should be re-enabled when calling read() or readDatagram() from the user." However, this patch does not completely solve the problem under Windows, as the socket notifier may emit spurious notifications. Task-number: QTBUG-46552 Change-Id: If7295d53ae2c788c39e86303502f38135c4d6180 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/network/socket/qabstractsocket.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src/network/socket/qabstractsocket.cpp') diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index c42b4f520c..d93150799c 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -739,15 +739,9 @@ bool QAbstractSocketPrivate::canReadNotification() return true; } - if (socketEngine) { - // turn the socket engine off if we've either: - // - got pending datagrams - // - reached the buffer size limit - if (isBuffered) - socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable()); - else if (socketType != QAbstractSocket::TcpSocket) - socketEngine->setReadNotificationEnabled(!socketEngine->hasPendingDatagrams()); - } + // turn the socket engine off if we've reached the buffer size limit + if (socketEngine && isBuffered) + socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable()); // reset the read socket notifier state if we reentered inside the // readyRead() connected slot. -- cgit v1.2.3 From b03d91e3f7d9b3ff96692d4e284b003ca5b90b82 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 27 Sep 2015 12:33:46 -0700 Subject: Remove unnecessary null-pointer check It was dereferenced 8 lines before and the pointer cannot have changed since. Found by Coverity, CID 11363. Change-Id: I42e7ef1a481840699a8dffff1407ecab4e4f5930 Reviewed-by: Richard J. Moore --- src/network/socket/qabstractsocket.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/network/socket/qabstractsocket.cpp') diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 75da64468f..02147d2054 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2485,8 +2485,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size) // Buffer what was not written yet char *ptr = d->writeBuffer.reserve(size - written); memcpy(ptr, data + written, size - written); - if (d->socketEngine) - d->socketEngine->setWriteNotificationEnabled(true); + d->socketEngine->setWriteNotificationEnabled(true); } return size; // size=actually written + what has been buffered } else if (!d->isBuffered && d->socketType != TcpSocket) { -- cgit v1.2.3 From 0872156559dd290e8e940d22a89cb95a46ef0cf6 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Sat, 10 Oct 2015 19:49:41 +0300 Subject: QAbstractSocket: fix writing to socket in HostLookup state After calling connectToHost(), the socket enters HostLookup state. At this stage, the socket engine was not created yet, and writing to the socket should result in either data buffering or an error. So, add a check for d->socketEngine to prevent a crash on unbuffered sockets. Task-number: QTBUG-48356 Change-Id: I15ea9ce7de97ce6d7e13e358eca5350745b556bb Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard J. Moore --- src/network/socket/qabstractsocket.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/network/socket/qabstractsocket.cpp') diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index d93150799c..5b1c5fa601 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2456,13 +2456,15 @@ qint64 QAbstractSocket::readLineData(char *data, qint64 maxlen) qint64 QAbstractSocket::writeData(const char *data, qint64 size) { Q_D(QAbstractSocket); - if (d->state == QAbstractSocket::UnconnectedState) { + if (d->state == QAbstractSocket::UnconnectedState + || (!d->socketEngine && d->socketType != TcpSocket && !d->isBuffered)) { d->socketError = QAbstractSocket::UnknownSocketError; setErrorString(tr("Socket is not connected")); return -1; } - if (!d->isBuffered && d->socketType == TcpSocket && d->writeBuffer.isEmpty()) { + if (!d->isBuffered && d->socketType == TcpSocket + && d->socketEngine && d->writeBuffer.isEmpty()) { // This code is for the new Unbuffered QTcpSocket use case qint64 written = d->socketEngine->write(data, size); if (written < 0) { @@ -2473,8 +2475,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size) // Buffer what was not written yet char *ptr = d->writeBuffer.reserve(size - written); memcpy(ptr, data + written, size - written); - if (d->socketEngine) - d->socketEngine->setWriteNotificationEnabled(true); + d->socketEngine->setWriteNotificationEnabled(true); } return size; // size=actually written + what has been buffered } else if (!d->isBuffered && d->socketType != TcpSocket) { -- cgit v1.2.3