summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Winkelmann <Michael.winkelmann@qt.io>2016-09-19 16:39:30 +0200
committerMichael Winkelmann <Michael.winkelmann@qt.io>2016-09-26 07:45:24 +0000
commit6bed30d5ceef1463469e37173b3ebac2cfdc2352 (patch)
tree520514fb102aace6c688d59aacc2feae67d9ad1a
parent3dfc46f069f3287c411ab178513d0ad47bf95352 (diff)
Fixed QModbusRtuSerialMaster stack overflow on close
QSerialPort::aboutToClose calls q->close() which leads to an infinite recursion. Calling QModbusRtuSerialMaster::close() explicitly is not necessary because when the serial port is closed, QModbusRtuSerialMaster::close() has been invoked already in all cases. Moreover, QSerialPort::aboutToClose asserts that serial master is always in closing state. Task-number: QTBUG-56009 Change-Id: If0dce93bbaa22116328b467f26c289cb58efc93f Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/serialbus/qmodbusrtuserialmaster.cpp7
-rw-r--r--src/serialbus/qmodbusrtuserialmaster_p.h5
2 files changed, 9 insertions, 3 deletions
diff --git a/src/serialbus/qmodbusrtuserialmaster.cpp b/src/serialbus/qmodbusrtuserialmaster.cpp
index c646ee7..95ab5eb 100644
--- a/src/serialbus/qmodbusrtuserialmaster.cpp
+++ b/src/serialbus/qmodbusrtuserialmaster.cpp
@@ -112,10 +112,15 @@ bool QModbusRtuSerialMaster::open()
*/
void QModbusRtuSerialMaster::close()
{
- if (state() == QModbusDevice::UnconnectedState)
+ if (state() == QModbusDevice::UnconnectedState ||
+ state() == QModbusDevice::ClosingState) {
return;
+ }
+
+ setState(QModbusDevice::ClosingState);
Q_D(QModbusRtuSerialMaster);
+
if (d->m_serialPort->isOpen())
d->m_serialPort->close();
diff --git a/src/serialbus/qmodbusrtuserialmaster_p.h b/src/serialbus/qmodbusrtuserialmaster_p.h
index 105e4a0..baa6174 100644
--- a/src/serialbus/qmodbusrtuserialmaster_p.h
+++ b/src/serialbus/qmodbusrtuserialmaster_p.h
@@ -216,8 +216,9 @@ public:
QObject::connect(m_serialPort, &QSerialPort::aboutToClose, q, [this]() {
Q_Q(QModbusRtuSerialMaster);
- if (q->state() != QModbusDevice::ClosingState)
- q->close();
+ Q_UNUSED(q); // To avoid unused variable warning in release mode
+ Q_ASSERT(q->state() == QModbusDevice::ClosingState);
+
m_sendTimer.stop();
m_responseTimer.stop();
});