QLocalSocket/Win: destroy the pipe before emitting final signals
Both readChannelFinished() and disconnected() signals should be emitted after closing the pipe. Otherwise, these signals do not correspond to the state of the socket and may even be resent, if a slot connected to one of these signals processes events. [ChangeLog][QtNetwork][Important Behavior Changes] QLocalSocket on Windows now emits both readChannelFinished() and disconnected() signals after closing the pipe and emitting stateChanged(UnconnectedState), which is consistent with the behavior on Unix. Pick-to: 6.2 Change-Id: I1cc551b7897fdba3cec1fd6705f5396790818c7d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>bb10
parent
de58fa3038
commit
6c1bc7798b
|
|
@ -336,22 +336,23 @@ void QLocalSocketPrivate::_q_pipeClosed()
|
|||
if (state == QLocalSocket::UnconnectedState)
|
||||
return;
|
||||
|
||||
emit q->readChannelFinished();
|
||||
if (state != QLocalSocket::ClosingState) {
|
||||
state = QLocalSocket::ClosingState;
|
||||
emit q->stateChanged(state);
|
||||
if (state != QLocalSocket::ClosingState)
|
||||
return;
|
||||
}
|
||||
state = QLocalSocket::UnconnectedState;
|
||||
emit q->stateChanged(state);
|
||||
emit q->disconnected();
|
||||
|
||||
pipeReader->stop();
|
||||
delete pipeWriter;
|
||||
pipeWriter = nullptr;
|
||||
destroyPipeHandles();
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
|
||||
state = QLocalSocket::UnconnectedState;
|
||||
emit q->stateChanged(state);
|
||||
emit q->readChannelFinished();
|
||||
emit q->disconnected();
|
||||
}
|
||||
|
||||
qint64 QLocalSocket::bytesAvailable() const
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ private slots:
|
|||
void verifyListenWithDescriptor_data();
|
||||
|
||||
void serverBindingsAndProperties();
|
||||
|
||||
protected slots:
|
||||
void socketClosedSlot();
|
||||
};
|
||||
|
||||
tst_QLocalSocket::tst_QLocalSocket()
|
||||
|
|
@ -1543,11 +1546,23 @@ void tst_QLocalSocket::bytesWrittenSignal()
|
|||
QVERIFY(writeThread.wait(2000));
|
||||
}
|
||||
|
||||
void tst_QLocalSocket::socketClosedSlot()
|
||||
{
|
||||
QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
|
||||
|
||||
QCOMPARE(socket->state(), QLocalSocket::UnconnectedState);
|
||||
}
|
||||
|
||||
void tst_QLocalSocket::syncDisconnectNotify()
|
||||
{
|
||||
QLocalServer server;
|
||||
QVERIFY(server.listen("syncDisconnectNotify"));
|
||||
QLocalSocket client;
|
||||
connect(&client, &QLocalSocket::disconnected,
|
||||
this, &tst_QLocalSocket::socketClosedSlot);
|
||||
connect(&client, &QIODevice::readChannelFinished,
|
||||
this, &tst_QLocalSocket::socketClosedSlot);
|
||||
|
||||
client.connectToServer("syncDisconnectNotify");
|
||||
QVERIFY(server.waitForNewConnection());
|
||||
QLocalSocket* serverSocket = server.nextPendingConnection();
|
||||
|
|
@ -1563,12 +1578,19 @@ void tst_QLocalSocket::asyncDisconnectNotify()
|
|||
QVERIFY(server.listen("asyncDisconnectNotify"));
|
||||
QLocalSocket client;
|
||||
QSignalSpy disconnectedSpy(&client, SIGNAL(disconnected()));
|
||||
QSignalSpy readChannelFinishedSpy(&client, SIGNAL(readChannelFinished()));
|
||||
connect(&client, &QLocalSocket::disconnected,
|
||||
this, &tst_QLocalSocket::socketClosedSlot);
|
||||
connect(&client, &QIODevice::readChannelFinished,
|
||||
this, &tst_QLocalSocket::socketClosedSlot);
|
||||
|
||||
client.connectToServer("asyncDisconnectNotify");
|
||||
QVERIFY(server.waitForNewConnection());
|
||||
QLocalSocket* serverSocket = server.nextPendingConnection();
|
||||
QVERIFY(serverSocket);
|
||||
delete serverSocket;
|
||||
QTRY_VERIFY(!disconnectedSpy.isEmpty());
|
||||
QCOMPARE(readChannelFinishedSpy.count(), 1);
|
||||
}
|
||||
|
||||
void tst_QLocalSocket::verifySocketOptions_data()
|
||||
|
|
|
|||
Loading…
Reference in New Issue