diff options
Diffstat (limited to 'src/network/socket/qabstractsocket.cpp')
-rw-r--r-- | src/network/socket/qabstractsocket.cpp | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 8d9975dcdb..08ccff83fa 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -722,7 +722,7 @@ bool QAbstractSocketPrivate::canReadNotification() } } - // only emit readyRead() when not recursing, and only if there is data available + // Only emit readyRead() if there is data available. bool hasData = newBytes > 0 #ifndef QT_NO_UDPSOCKET || (!isBuffered && socketType != QAbstractSocket::TcpSocket && socketEngine && socketEngine->hasPendingDatagrams()) @@ -730,11 +730,8 @@ bool QAbstractSocketPrivate::canReadNotification() || (!isBuffered && socketType == QAbstractSocket::TcpSocket && socketEngine) ; - if (!emittedReadyRead && hasData) { - QScopedValueRollback<bool> r(emittedReadyRead); - emittedReadyRead = true; - emit q->readyRead(); - } + if (hasData) + emitReadyRead(); // If we were closed as a result of the readyRead() signal, // return. @@ -792,12 +789,12 @@ void QAbstractSocketPrivate::canCloseNotification() // then occur when we read from the socket again and fail // in canReadNotification or by the manually created // closeNotification below. - emit q->readyRead(); + emitReadyRead(); QMetaObject::invokeMethod(socketEngine, "closeNotification", Qt::QueuedConnection); } } else if (socketType == QAbstractSocket::TcpSocket && socketEngine) { - emit q->readyRead(); + emitReadyRead(); } } @@ -817,8 +814,7 @@ bool QAbstractSocketPrivate::canWriteNotification() #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocketPrivate::canWriteNotification() flushing"); #endif - qint64 tmp = writeBuffer.size(); - flush(); + bool dataWasWritten = writeToSocket(); if (socketEngine) { #if defined (Q_OS_WIN) @@ -830,7 +826,7 @@ bool QAbstractSocketPrivate::canWriteNotification() #endif } - return (writeBuffer.size() < tmp); + return dataWasWritten; } /*! \internal @@ -852,21 +848,20 @@ void QAbstractSocketPrivate::connectionNotification() /*! \internal - Writes pending data in the write buffers to the socket. The - function writes as much as it can without blocking. + Writes one pending data block in the write buffer to the socket. It is usually invoked by canWriteNotification after one or more calls to write(). Emits bytesWritten(). */ -bool QAbstractSocketPrivate::flush() +bool QAbstractSocketPrivate::writeToSocket() { Q_Q(QAbstractSocket); if (!socketEngine || !socketEngine->isValid() || (writeBuffer.isEmpty() && socketEngine->bytesToWrite() == 0)) { #if defined (QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocketPrivate::flush() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s", + qDebug("QAbstractSocketPrivate::writeToSocket() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s", (socketEngine && socketEngine->isValid()) ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no"); #endif @@ -884,7 +879,8 @@ bool QAbstractSocketPrivate::flush() qint64 written = socketEngine->write(ptr, nextSize); if (written < 0) { #if defined (QABSTRACTSOCKET_DEBUG) - qDebug() << "QAbstractSocketPrivate::flush() write error, aborting." << socketEngine->errorString(); + qDebug() << "QAbstractSocketPrivate::writeToSocket() write error, aborting." + << socketEngine->errorString(); #endif setErrorAndEmit(socketEngine->error(), socketEngine->errorString()); // an unexpected error so close the socket. @@ -893,7 +889,7 @@ bool QAbstractSocketPrivate::flush() } #if defined (QABSTRACTSOCKET_DEBUG) - qDebug("QAbstractSocketPrivate::flush() %lld bytes written to the network", + qDebug("QAbstractSocketPrivate::writeToSocket() %lld bytes written to the network", written); #endif @@ -914,7 +910,23 @@ bool QAbstractSocketPrivate::flush() if (state == QAbstractSocket::ClosingState) q->disconnectFromHost(); - return true; + return written > 0; +} + +/*! \internal + + Writes pending data in the write buffers to the socket. The function + writes as much as it can without blocking. If any data was written, + this function returns true; otherwise false is returned. +*/ +bool QAbstractSocketPrivate::flush() +{ + bool dataWasWritten = false; + + while (!writeBuffer.isEmpty() && writeToSocket()) + dataWasWritten = true; + + return dataWasWritten; } #ifndef QT_NO_NETWORKPROXY @@ -1248,6 +1260,7 @@ void QAbstractSocketPrivate::_q_forceDisconnect() */ bool QAbstractSocketPrivate::readFromSocket() { + Q_Q(QAbstractSocket); // Find how many bytes we can read from the socket layer. qint64 bytesToRead = socketEngine->bytesAvailable(); if (bytesToRead == 0) { @@ -1276,7 +1289,7 @@ bool QAbstractSocketPrivate::readFromSocket() buffer.chop(bytesToRead); return true; } - buffer.chop(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes)); + buffer.chop(bytesToRead - ((readBytes < 0 || !q->isReadable()) ? qint64(0) : readBytes)); #if defined(QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocketPrivate::readFromSocket() got %lld bytes, buffer size = %lld", readBytes, buffer.size()); @@ -1297,6 +1310,21 @@ bool QAbstractSocketPrivate::readFromSocket() /*! \internal + Prevents from the recursive readyRead() emission. +*/ +void QAbstractSocketPrivate::emitReadyRead() +{ + Q_Q(QAbstractSocket); + // Only emit readyRead() when not recursing. + if (!emittedReadyRead) { + QScopedValueRollback<bool> r(emittedReadyRead); + emittedReadyRead = true; + emit q->readyRead(); + } +} + +/*! \internal + Sets up the internal state after the connection has succeeded. */ void QAbstractSocketPrivate::fetchConnectionParameters() @@ -2374,7 +2402,7 @@ bool QAbstractSocket::isSequential() const */ bool QAbstractSocket::atEnd() const { - return QIODevice::atEnd() && (!isOpen() || d_func()->buffer.isEmpty()); + return QIODevice::atEnd(); } /*! |