diff options
author | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2023-03-10 11:03:55 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-03-30 11:11:10 +0000 |
commit | dc16efb93de03b852fb3c71aec228b3804903404 (patch) | |
tree | a348e93938a75e4676741477dc5d506a95e035d8 | |
parent | 3a5732eeea01b80883d8833ec2b1cade530f8943 (diff) |
Windows: Fix crash on QMqttClient destruction6.4
On Windows, sending DISCONNECT might return data before the
QMqttConnection is destroyed, causing it to invoke on bogus QMqttClient
members.
Hence, set a flag to avoid this event, but still aim to send a
disconnect to the broker to nicely quit.
Fixes: QTBUG-111846
Change-Id: Ia94865c9b404ecbd814150c313679aa10b3f6aa0
Reviewed-by: Mate Barany <mate.barany@qt.io>
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
(cherry picked from commit c04b21a2dcce46047bc08c9a833ca78ee43ee41c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/mqtt/qmqttclient.cpp | 7 | ||||
-rw-r--r-- | src/mqtt/qmqttconnection.cpp | 6 | ||||
-rw-r--r-- | src/mqtt/qmqttconnection_p.h | 4 |
3 files changed, 14 insertions, 3 deletions
diff --git a/src/mqtt/qmqttclient.cpp b/src/mqtt/qmqttclient.cpp index 6e15f72..7191684 100644 --- a/src/mqtt/qmqttclient.cpp +++ b/src/mqtt/qmqttclient.cpp @@ -326,7 +326,11 @@ QMqttClient::QMqttClient(QObject *parent) : QObject(*(new QMqttClientPrivate(thi */ QMqttClient::~QMqttClient() { - disconnectFromHost(); + Q_D(QMqttClient); + if (d->m_connection.internalState() == QMqttConnection::BrokerConnected) { + d->m_connection.setClientDestruction(); + disconnectFromHost(); + } } /*! @@ -575,6 +579,7 @@ void QMqttClient::disconnectFromHost() switch (d->m_connection.internalState()) { case QMqttConnection::BrokerConnected: + case QMqttConnection::ClientDestruction: d->m_connection.sendControlDisconnect(); break; case QMqttConnection::BrokerDisconnected: diff --git a/src/mqtt/qmqttconnection.cpp b/src/mqtt/qmqttconnection.cpp index 6650ef3..a302484 100644 --- a/src/mqtt/qmqttconnection.cpp +++ b/src/mqtt/qmqttconnection.cpp @@ -291,6 +291,7 @@ bool QMqttConnection::sendControlAuthenticate(const QMqttAuthenticationPropertie switch (m_internalState) { case BrokerDisconnected: case BrokerConnecting: + case ClientDestruction: qCDebug(lcMqttConnection) << "Using AUTH while disconnected."; return false; case BrokerWaitForConnectAck: @@ -601,7 +602,8 @@ bool QMqttConnection::sendControlDisconnect() qCDebug(lcMqttConnection) << "Failed to write DISCONNECT to transport."; return false; } - m_internalState = BrokerDisconnected; + if (m_internalState != ClientDestruction) + m_internalState = BrokerDisconnected; if (m_transport->waitForBytesWritten(30000)) { // MQTT-3.14.4-1 must disconnect @@ -676,6 +678,8 @@ void QMqttConnection::transportConnectionClosed() m_readPosition = 0; m_pingTimer.stop(); m_pingTimeout = 0; + if (m_internalState == ClientDestruction) + return; if (m_internalState == BrokerDisconnected) // We manually disconnected m_clientPrivate->setStateAndError(QMqttClient::Disconnected, QMqttClient::NoError); else diff --git a/src/mqtt/qmqttconnection_p.h b/src/mqtt/qmqttconnection_p.h index c17433a..f5ea4b2 100644 --- a/src/mqtt/qmqttconnection_p.h +++ b/src/mqtt/qmqttconnection_p.h @@ -38,7 +38,8 @@ public: BrokerDisconnected = 0, BrokerConnecting, BrokerWaitForConnectAck, - BrokerConnected + BrokerConnected, + ClientDestruction }; explicit QMqttConnection(QObject *parent = nullptr); @@ -67,6 +68,7 @@ public: inline quint16 unusedPacketIdentifier() const; inline InternalConnectionState internalState() const { return m_internalState; } + inline void setClientDestruction() { m_internalState = ClientDestruction; } void cleanSubscriptions(); |