summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2021-10-02 18:10:20 +0300
committerAlex Trotsenko <alex1973tr@gmail.com>2021-10-06 10:16:14 +0300
commit82b86960c051de99fca7c4dfa7af2c914937f5c8 (patch)
treef5a47aa78d39a229e083269c07b52173e194ec0a
parentb689d8dccd3c260e88116285b7b75e827ca9954b (diff)
QLocalSocket/Win: stop reading in close()
After calling close(), the socket can enter 'Closing' state, in which we try to write buffered data before disconnecting. As the device is already closed, we must disable any pipe reader activity and clear the read buffer. Change-Id: I8994df32bf324325d54dd36cbe1a1ee3f08022d1 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
-rw-r--r--src/corelib/io/qwindowspipereader.cpp24
-rw-r--r--src/corelib/io/qwindowspipereader_p.h1
-rw-r--r--src/network/socket/qlocalsocket_win.cpp1
-rw-r--r--tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp3
4 files changed, 24 insertions, 5 deletions
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 5415ad7830..4435a47cab 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -104,6 +104,7 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd)
void QWindowsPipeReader::stop()
{
cancelAsyncRead(Stopped);
+ pipeBroken = true;
}
/*!
@@ -113,6 +114,22 @@ void QWindowsPipeReader::stop()
void QWindowsPipeReader::drainAndStop()
{
cancelAsyncRead(Draining);
+ pipeBroken = true;
+}
+
+/*!
+ Stops the asynchronous read sequence.
+ Clears the internal buffer and discards any pending data.
+ */
+void QWindowsPipeReader::stopAndClear()
+{
+ cancelAsyncRead(Stopped);
+ readBuffer.clear();
+ actualReadBufferSize = 0;
+ // QLocalSocket is supposed to write data in the 'Closing'
+ // state, so we don't set 'pipeBroken' flag here. Also, avoid
+ // setting this flag in checkForReadyRead().
+ lastError = ERROR_SUCCESS;
}
/*!
@@ -120,7 +137,6 @@ void QWindowsPipeReader::drainAndStop()
*/
void QWindowsPipeReader::cancelAsyncRead(State newState)
{
- pipeBroken = true;
if (state != Running)
return;
@@ -147,9 +163,9 @@ void QWindowsPipeReader::cancelAsyncRead(State newState)
}
mutex.unlock();
- // Because pipeBroken was set earlier, finish reading to keep the class
- // state consistent. Note that signals are not emitted in the call
- // below, as the caller is expected to do that synchronously.
+ // Finish reading to keep the class state consistent. Note that
+ // signals are not emitted in the call below, as the caller is
+ // expected to do that synchronously.
consumePending();
}
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index 5eb62cb393..22a4365f02 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -71,6 +71,7 @@ public:
void startAsyncRead();
void stop();
void drainAndStop();
+ void stopAndClear();
void setMaxReadBufferSize(qint64 size);
qint64 maxReadBufferSize() const { return readBufferMaxSize; }
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index b98dcb0dbc..f7e72c055b 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -396,6 +396,7 @@ void QLocalSocket::close()
Q_D(QLocalSocket);
QIODevice::close();
+ d->pipeReader->stopAndClear();
d->serverName = QString();
d->fullServerName = QString();
disconnectFromServer();
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
index 5de1fa2b58..ed665253da 100644
--- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
@@ -1372,7 +1372,7 @@ void tst_QLocalSocket::delayedDisconnect()
QVERIFY(serverSocket);
connect(serverSocket, &QLocalSocket::aboutToClose, [serverSocket]() {
QVERIFY(serverSocket->isOpen());
- QVERIFY(serverSocket->getChar(nullptr));
+ QCOMPARE(serverSocket->bytesAvailable(), qint64(1));
});
QVERIFY(socket.putChar(0));
@@ -1386,6 +1386,7 @@ void tst_QLocalSocket::delayedDisconnect()
serverSocket->close();
QCOMPARE(serverSocket->state(), QLocalSocket::UnconnectedState);
QVERIFY(!serverSocket->isOpen());
+ QCOMPARE(serverSocket->bytesAvailable(), qint64(0));
}
void tst_QLocalSocket::removeServer()