From 794b7e54860fd0a49108169c16babfcd05a63e6f Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Mon, 17 Jun 2019 12:43:12 +0200 Subject: [PATCH] Important Update: - FunctionCore: - Implement UnlinkChannel() - Avoid memory errors on application shutdown (state events) - Unlink channels before destroying in Function destructor - Bug fix: Linked Channels not added correctly --- FunctionCore.cpp | 69 +++++++++++++++++++++++++++++++++++++++--------- FunctionCore.h | 1 + 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/FunctionCore.cpp b/FunctionCore.cpp index 3fc9596..c7cc299 100644 --- a/FunctionCore.cpp +++ b/FunctionCore.cpp @@ -48,18 +48,15 @@ CFunctionCore::~CFunctionCore() // Destroy Channels while (FirstChannel) { - // Destroy Parameters - if (FirstChannel->Name) { - free( FirstChannel->Name ); - free( FirstChannel->Ref ); - } - // Destroy Linked Channels - while (FirstChannel->FirstLink) { - NextLinkedChannel = FirstChannel->FirstLink->Next; - delete FirstChannel->FirstLink; - FirstChannel->FirstLink = NextLinkedChannel; - } + while (FirstChannel->FirstLink) + UnlinkChannel( FirstChannel->Name, FirstChannel->FirstLink->Function->Name, FirstChannel->FirstLink->Channel->Name ); + + // Destroy Parameters + if (FirstChannel->Name) + free( FirstChannel->Name ); + if (FirstChannel->Ref) + free( FirstChannel->Ref ); // Destroy Channel NextChannel = FirstChannel->Next; @@ -280,7 +277,7 @@ bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunc // Check if linked Channel exists LinkedChannel = &(Channel->FirstLink); - while (*LinkedChannel && ((*LinkedChannel)->Channel == LinkChannel)) + while (*LinkedChannel && ((*LinkedChannel)->Channel != LinkChannel)) LinkedChannel = &((*LinkedChannel)->Next); if (!*LinkedChannel) *LinkedChannel = new TChannelLink; @@ -297,7 +294,7 @@ bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunc // Find Linked channel on remote function LinkedChannel = &(LinkChannel->FirstLink); - while (*LinkedChannel && ((*LinkedChannel)->Channel == Channel)) + while (*LinkedChannel && ((*LinkedChannel)->Channel != Channel)) LinkedChannel = &((*LinkedChannel)->Next); if (!*LinkedChannel) *LinkedChannel = new TChannelLink; @@ -315,6 +312,52 @@ bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunc } //--------------------------------------------------------------------------- +bool CFunctionCore::UnlinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName ) +{ + TChannel * Channel = NULL; + CFunctionCore * LinkFunction = NULL; + TChannel * LinkChannel = NULL; + TChannelLink ** LinkedChannel = NULL; + TChannelLink * NextLinkedChannel = NULL; + + // Check if Channels & Function exist + if (!(Channel = GetChannel( ChannelName )) || + !(LinkFunction = Application->GetFunction( LinkFunctionName )) || + !(LinkChannel = LinkFunction->GetChannel( LinkChannelName )) ) { + return false; + } + + // Check if linked Channel exists + LinkedChannel = &(Channel->FirstLink); + while (*LinkedChannel && ((*LinkedChannel)->Channel != LinkChannel)) + LinkedChannel = &((*LinkedChannel)->Next); + + // Unlink channel + if (*LinkedChannel) { + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Forward Channel Unlinked - '%s'-x->'%s'", + ProcessName, Name, Channel->Ref, (*LinkedChannel)->Channel->Ref ); + NextLinkedChannel = (*LinkedChannel)->Next; + delete *LinkedChannel; + *LinkedChannel = NextLinkedChannel; + } + + // Find Linked channel on remote function + LinkedChannel = &(LinkChannel->FirstLink); + while (*LinkedChannel && ((*LinkedChannel)->Channel != Channel)) + LinkedChannel = &((*LinkedChannel)->Next); + + // Unlink channel + if (*LinkedChannel) { + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Reverse Channel Unlinked - '%s'-x->'%s'", + ProcessName, Name, LinkChannel->Ref, (*LinkedChannel)->Channel->Ref ); + NextLinkedChannel = (*LinkedChannel)->Next; + delete *LinkedChannel; + *LinkedChannel = NextLinkedChannel; + } + return true; +} +//--------------------------------------------------------------------------- + int CFunctionCore::Input( const char * ChannelName, const char * SourceRef, const char * Data, int Len ) { TChannel * Channel = NULL; diff --git a/FunctionCore.h b/FunctionCore.h index 090bdd2..6f77962 100644 --- a/FunctionCore.h +++ b/FunctionCore.h @@ -130,6 +130,7 @@ public: // Automated Data Input/Output virtual bool LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Input, bool Output ); + virtual bool UnlinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName ); virtual bool Process() = 0; friend class CApplication;