From 12614b2c5aaaed44ef9b3d1b3f6dbf50fd2d405f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 13:10:27 +0200 Subject: QLocalSocket: fix reading from a socket after broken connection Reading from a socket with a broken connection didn't work, even if there were still bytes to read in the internal read buffer. Autotest: tst_QLocalSocket::writeToClientAndDisconnect Task-number: QTBUG-10921 Reviewed-by: ossi --- src/network/socket/qlocalsocket_win.cpp | 10 ++++++---- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 5f46ecb..dc87ade 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -192,6 +192,9 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize) { Q_D(QLocalSocket); + if (d->pipeClosed && d->actualReadBufferSize == 0) + return -1; // signal EOF + qint64 readSoFar; // If startAsyncRead() read data, copy it to its destination. if (maxSize == 1 && d->actualReadBufferSize > 0) { @@ -213,10 +216,8 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize) } if (d->pipeClosed) { - if (readSoFar == 0) { + if (d->actualReadBufferSize == 0) QTimer::singleShot(0, this, SLOT(_q_pipeClosed())); - return -1; // signal EOF - } } else { if (!d->readSequenceStarted) d->startAsyncRead(); @@ -345,7 +346,8 @@ DWORD QLocalSocketPrivate::bytesAvailable() if (!pipeClosed) { pipeClosed = true; emit q->readChannelFinished(); - QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); + if (actualReadBufferSize == 0) + QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); } } return 0; diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index dbb58c1..87a30c2 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -980,6 +980,7 @@ void tst_QLocalSocket::writeToClientAndDisconnect() QLocalServer server; QLocalSocket client; + QSignalSpy readChannelFinishedSpy(&client, SIGNAL(readChannelFinished())); QVERIFY(server.listen("writeAndDisconnectServer")); client.connectToServer("writeAndDisconnectServer"); @@ -992,10 +993,19 @@ void tst_QLocalSocket::writeToClientAndDisconnect() memset(buffer, 0, sizeof(buffer)); QCOMPARE(clientSocket->write(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); clientSocket->waitForBytesWritten(); - clientSocket->disconnectFromServer(); - QVERIFY(client.waitForReadyRead()); + clientSocket->close(); + server.close(); + + // Wait for the client to notice the broken connection. + int timeout = 5000; + do { + const int timestep = 100; + QTest::qWait(timestep); + timeout -= timestep; + } while (!readChannelFinishedSpy.count() && timeout > 0); + + QVERIFY(!readChannelFinishedSpy.isEmpty()); QCOMPARE(client.read(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); - QVERIFY(client.waitForDisconnected()); QCOMPARE(client.state(), QLocalSocket::UnconnectedState); } -- cgit v0.12