From 59656d562b31b1ff576b43cc40bad5789c80babd Mon Sep 17 00:00:00 2001 From: Jannis Voelker Date: Wed, 21 Mar 2018 12:22:30 +0100 Subject: Fix client lifecycle in the open62541 backend - Don't leak the client when calling connectToEndpoint more than once. - Don't segfault when trying to disconnect without a client. This also removes the memory leaks in the test cases. Change-Id: I0405a86e9015465b86cc94facac6e8676b4039a7 Reviewed-by: Maurice Kalinowski Reviewed-by: Frank Meerkoetter --- src/plugins/opcua/open62541/qopen62541backend.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/plugins/opcua/open62541/qopen62541backend.cpp b/src/plugins/opcua/open62541/qopen62541backend.cpp index 24aedf8..ec0eb09 100644 --- a/src/plugins/opcua/open62541/qopen62541backend.cpp +++ b/src/plugins/opcua/open62541/qopen62541backend.cpp @@ -75,6 +75,8 @@ Open62541AsyncBackend::Open62541AsyncBackend(QOpen62541Client *parent) Open62541AsyncBackend::~Open62541AsyncBackend() { qDeleteAll(m_subscriptions); + if (m_uaclient) + UA_Client_delete(m_uaclient); } void Open62541AsyncBackend::readAttributes(uintptr_t handle, UA_NodeId id, QOpcUa::NodeAttributes attr, QString indexRange) @@ -432,6 +434,9 @@ static void clientStateCallback(UA_Client *client, UA_ClientState state) void Open62541AsyncBackend::connectToEndpoint(const QUrl &url) { + if (m_uaclient) + UA_Client_delete(m_uaclient); + UA_ClientConfig conf = UA_ClientConfig_default; conf.clientContext = this; conf.stateCallback = &clientStateCallback; @@ -464,14 +469,16 @@ void Open62541AsyncBackend::disconnectFromEndpoint() m_subscriptions.clear(); m_attributeMapping.clear(); - UA_StatusCode ret = UA_Client_disconnect(m_uaclient); - if (ret != UA_STATUSCODE_GOOD) { - qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Open62541: Failed to disconnect"; - // Fall through intentionally + if (m_uaclient) { + UA_StatusCode ret = UA_Client_disconnect(m_uaclient); + if (ret != UA_STATUSCODE_GOOD) { + qCWarning(QT_OPCUA_PLUGINS_OPEN62541) << "Open62541: Failed to disconnect"; + // Fall through intentionally + } + UA_Client_delete(m_uaclient); + m_uaclient = nullptr; } - UA_Client_delete(m_uaclient); - m_uaclient = nullptr; emit stateAndOrErrorChanged(QOpcUaClient::Disconnected, QOpcUaClient::NoError); } -- cgit v1.2.3