QAbstractSocket: do not fail writing on read buffer overflow
canReadNotification() could return 'false' if either the socket has been closed, or the read buffer has reached the maximum size. Because of this duality, waitForBytesWritten() should not fail as a result of a canReadNotification() call. Change-Id: I9a15fa174a3b982a7ce404913caa38fc19f64622 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Markus Goetz (Woboq GmbH) <markus@woboq.com>
This commit is contained in:
parent
d930c8b5fc
commit
bec47545dc
@ -2253,8 +2253,10 @@ bool QAbstractSocket::waitForBytesWritten(int msecs)
|
||||
forever {
|
||||
bool readyToRead = false;
|
||||
bool readyToWrite = false;
|
||||
if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, true, !d->writeBuffer.isEmpty(),
|
||||
qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
|
||||
if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite,
|
||||
!d->readBufferMaxSize || d->buffer.size() < d->readBufferMaxSize,
|
||||
!d->writeBuffer.isEmpty(),
|
||||
qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
|
||||
#if defined (QABSTRACTSOCKET_DEBUG)
|
||||
qDebug("QAbstractSocket::waitForBytesWritten(%i) failed (%i, %s)",
|
||||
msecs, d->socketEngine->error(), d->socketEngine->errorString().toLatin1().constData());
|
||||
@ -2269,8 +2271,7 @@ bool QAbstractSocket::waitForBytesWritten(int msecs)
|
||||
#if defined (QABSTRACTSOCKET_DEBUG)
|
||||
qDebug("QAbstractSocket::waitForBytesWritten calls canReadNotification");
|
||||
#endif
|
||||
if(!d->canReadNotification())
|
||||
return false;
|
||||
d->canReadNotification();
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,6 +197,7 @@ private slots:
|
||||
void clientSendDataOnDelayedDisconnect();
|
||||
void serverDisconnectWithBuffered();
|
||||
void socketDiscardDataInWriteMode();
|
||||
void writeOnReadBufferOverflow();
|
||||
void readNotificationsAfterBind();
|
||||
|
||||
protected slots:
|
||||
@ -3067,6 +3068,40 @@ void tst_QTcpSocket::socketDiscardDataInWriteMode()
|
||||
delete socket;
|
||||
}
|
||||
|
||||
// Test waitForBytesWritten() does not fail on read buffer overflow
|
||||
void tst_QTcpSocket::writeOnReadBufferOverflow()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (setProxy)
|
||||
return;
|
||||
|
||||
QTcpServer tcpServer;
|
||||
QTcpSocket *socket = newSocket();
|
||||
|
||||
QVERIFY(tcpServer.listen(QHostAddress::LocalHost));
|
||||
socket->setReadBufferSize(1);
|
||||
socket->connectToHost(tcpServer.serverAddress(), tcpServer.serverPort());
|
||||
QVERIFY(socket->waitForConnected(5000));
|
||||
QCOMPARE(socket->state(), QAbstractSocket::ConnectedState);
|
||||
|
||||
// Accept connection on server side
|
||||
QVERIFY2(tcpServer.waitForNewConnection(5000), "Network timeout");
|
||||
QTcpSocket *newConnection = tcpServer.nextPendingConnection();
|
||||
QVERIFY(newConnection != nullptr);
|
||||
QCOMPARE(newConnection->write("1", 2), Q_INT64_C(2));
|
||||
QVERIFY(newConnection->flush());
|
||||
|
||||
// Wait for buffer overflow
|
||||
QVERIFY(socket->waitForReadyRead(5000));
|
||||
QCOMPARE(socket->bytesAvailable(), Q_INT64_C(1));
|
||||
// Write data and wait for successful send
|
||||
QVERIFY(socket->putChar(0));
|
||||
QVERIFY(socket->waitForBytesWritten(5000));
|
||||
|
||||
delete newConnection;
|
||||
delete socket;
|
||||
}
|
||||
|
||||
// Test that the socket does not enable the read notifications in bind()
|
||||
void tst_QTcpSocket::readNotificationsAfterBind()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user