From 08fce64629ed29551a3bcf272db7ee6b14bd4a71 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Wed, 5 Jun 2019 19:13:04 +0200 Subject: [PATCH] Important Update: - FunctionCore - So not set Function JSON "config" param to empty object by default - Change TChannelLink to reference Channel direct - Add Input/Output to TChannelLink - Replace LinkChannel() Bidirectional param with Input/Output param - Update JSON config as well - Implement Channel "Ready" state and events - Remove Input/OutputEnabled parameters and related methods - Remove from JSON config as well - Update AddChannel() method accordingly - Add Ref param to struct TChannel - SelectableCore: - Convert inline ChangeState() to non-inline method - Move ChangeState() to last step in open/close methods - Add Channels in Not Ready state - Change Channel state when Handle state changed - DeviceCore: - Add Channels in Ready state - FileCore: - Add Channel in Not Ready state --- DeviceCore.cpp | 14 +++- FileCore.cpp | 2 +- FunctionCore.cpp | 162 ++++++++++++++++++++++++++------------------- FunctionCore.h | 45 +++++-------- SelectableBare.cpp | 60 ++++++++++++----- SelectableCore.cpp | 53 ++++++++------- SelectableCore.h | 20 ++---- 7 files changed, 202 insertions(+), 154 deletions(-) diff --git a/DeviceCore.cpp b/DeviceCore.cpp index 42d86c3..902d5d6 100644 --- a/DeviceCore.cpp +++ b/DeviceCore.cpp @@ -68,11 +68,19 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig ) // Add Channels if (!(CmdChannel = GetChannel( "Command" ))) - CmdChannel = AddChannel( "Command", true, true ); + CmdChannel = AddChannel( "Command", true ); + else + SetChannelState( CmdChannel, true ); + if (!(DeviceChannel = GetChannel( "Device" ))) - DeviceChannel = AddChannel( "Device", true, true ); + DeviceChannel = AddChannel( "Device", true ); + else + SetChannelState( DeviceChannel, true ); + if (!(EventChannel = GetChannel( "Event" ))) - EventChannel = AddChannel( "Event", true, true ); + EventChannel = AddChannel( "Event", true ); + else + SetChannelState( EventChannel, true ); // Load Polling configuration PollConfig = Config->GetChild( "Polling", true ); diff --git a/FileCore.cpp b/FileCore.cpp index b0a3ac1..8155e5b 100644 --- a/FileCore.cpp +++ b/FileCore.cpp @@ -86,7 +86,7 @@ TFileHandle * CFileCore::AddFile( const char * Name, const char * Path, bool Ap // Create Channel if necessary if (CreateChannel) { - AddChannel( Name ); + AddChannel( Name, false ); } // Set Parameters diff --git a/FunctionCore.cpp b/FunctionCore.cpp index 1fdda9a..c5be8f5 100644 --- a/FunctionCore.cpp +++ b/FunctionCore.cpp @@ -54,12 +54,8 @@ CFunctionCore::~CFunctionCore() free( FirstChannel->Ref ); } - // Destroy Linked Outputs + // Destroy Linked Channels while (FirstChannel->FirstLink) { - if (FirstChannel->FirstLink->Name) { - free( FirstChannel->FirstLink->Name ); - free( FirstChannel->FirstLink->Ref ); - } NextLinkedChannel = FirstChannel->FirstLink->Next; delete FirstChannel->FirstLink; FirstChannel->FirstLink = NextLinkedChannel; @@ -103,13 +99,8 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig ) // Load Channels ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true ); - while (ChannelConfig) - { - if (ChannelConfig->GetName()) { - AddChannel( ChannelConfig->GetName(), - ChannelConfig->GetChBool( "InputEnabled", true, true ), - ChannelConfig->GetChBool( "OutputEnabled", false, true )); - } + while (ChannelConfig) { + AddChannel( ChannelConfig->GetName(), false ); ChannelConfig = ChannelConfig->GetNextPeer(); } @@ -118,7 +109,6 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig ) ConfigName = (char*)FunctionConfig->GetChStr( "Config" ); Config = Application->Config->GetChild( ConfigName, true ); } - if (Config->isNull()) Config->SetObject(); return true; } @@ -145,9 +135,10 @@ bool CFunctionCore::InitChannelLinks( CDataMember * LinkConfig ) { // Get Parameters LinkChannel( Channel->Name, - FunctionMember->GetChStr( "Function" ), - FunctionMember->GetChStr( "Channel" ), - FunctionMember->GetChBool( "Bidirectional" ) ); + FunctionMember->GetChStr( "Function", NULL, true ), + FunctionMember->GetChStr( "Channel", NULL, true ), + FunctionMember->GetChBool( "Input", false, true ), + FunctionMember->GetChBool( "Output", false, true ) ); FunctionMember = FunctionMember->GetNextPeer(); } } @@ -175,7 +166,7 @@ bool CFunctionCore::SetLogLevel( EDebugLevel pDebugLevel ) } //--------------------------------------------------------------------------- -TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInputEnable, const bool pOutputEnable ) +TChannel * CFunctionCore::AddChannel( const char * ChannelName, bool Ready ) { TChannel ** Channel = NULL; @@ -197,63 +188,106 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu // Set Name (*Channel)->Name = strdup( ChannelName ); + (*Channel)->Ref = (char*)malloc( strlen(Name)+strlen(ChannelName)+2 ); sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName ); + (*Channel)->Ready = Ready; // Log Event - if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created", - ProcessName, Name, ChannelName ); + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created, Ref:'%s', Ready:%s", + ProcessName, Name, ChannelName, (*Channel)->Ref, (((*Channel)->Ready)? "Yes" : "No") ); } - - // Set parameters - (*Channel)->InputEnabled = pInputEnable; - (*Channel)->OutputEnabled = pOutputEnable; - return *Channel; } //--------------------------------------------------------------------------- -// Automated Data Input/Output -bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Bidirectional ) +bool CFunctionCore::SetChannelState( TChannel * Channel, const bool Ready ) { - TChannel * OutChannel = NULL; - CFunctionCore * InFunction = NULL; - TChannel * InChannel = NULL; + TChannelLink * LinkChannel; + + // Validate + if (!Channel) + return false; + + // Update state + Channel->Ready = Ready; + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Channel '%s' - Ready:%s", + ProcessName, Name, Channel->Name, ((Ready)? "Yes" : "No") ); + + // Update linked channels + LinkChannel = Channel->FirstLink; + while (LinkChannel) { + LinkChannel->Function->ChannelStateEvent( LinkChannel->Channel, Channel->Ref, Ready ); + LinkChannel = LinkChannel->Next; + } + + return true; +} +//--------------------------------------------------------------------------- + +bool CFunctionCore::ChannelStateEvent( TChannel * Channel, const char * SourceRef, const bool Ready ) +{ + TChannelLink * LinkChannel; + + if (!Channel) + return false; + if (!(LinkChannel = GetLinkChannel( Channel, SourceRef ))) + return false; + + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Update Link Channel '%s'-->'%s' - Ready:%s", + ProcessName, Name, Channel->Name, LinkChannel->Channel->Ref, ((Ready)? "Yes" : "No") ); + + return true; +} +//--------------------------------------------------------------------------- + +// Automated Data Input/Output +bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Input, bool Output ) +{ + TChannel * Channel = NULL; + CFunctionCore * LinkFunction = NULL; + TChannel * LinkChannel = NULL; TChannelLink ** LinkedChannel = NULL; // Check if Channels & Function exist - if (!(OutChannel = GetChannel( ChannelName )) || - !(InFunction = Application->GetFunction( LinkFunctionName )) || - !(InChannel = InFunction->GetChannel( LinkChannelName )) ) { + if (!(Channel = GetChannel( ChannelName )) || + !(LinkFunction = Application->GetFunction( LinkFunctionName )) || + !(LinkChannel = LinkFunction->GetChannel( LinkChannelName )) ) { return false; } // Check if linked Channel exists - LinkedChannel = &(OutChannel->FirstLink); - while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, LinkChannelName ) )) { + LinkedChannel = &(Channel->FirstLink); + while (*LinkedChannel && ((*LinkedChannel)->Channel == LinkChannel)) LinkedChannel = &((*LinkedChannel)->Next); - } - - // Create if not found if (!*LinkedChannel) - { - // Create *LinkedChannel = new TChannelLink; - // Set Parameters - (*LinkedChannel)->Function = InFunction; - (*LinkedChannel)->Name = strdup( LinkChannelName ); - sprintf( (*LinkedChannel)->Ref, "%s/%s", LinkFunctionName, LinkChannelName ); + // Set Parameters + (*LinkedChannel)->Function = LinkFunction; + (*LinkedChannel)->Channel = LinkChannel; + (*LinkedChannel)->Input = Input; + (*LinkedChannel)->Output = Output; - // Log Event - if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Output Linked - '%s/%s' --> '%s/%s'", - ProcessName, Name, Name, ChannelName, LinkFunctionName, LinkChannelName ); - } + // Log Event + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Forward Channel Linked - '%s'-->'%s' - In:%s, Out:%s", + ProcessName, Name, Channel->Ref, (*LinkedChannel)->Channel->Ref, ((Input)? "Yes" : "No"), ((Output)? "Yes" : "No") ); - // Link return direction as well - if (Bidirectional) { - return InFunction->LinkChannel( LinkChannelName, Name, ChannelName, false ); - } + // Find Linked channel on remote function + LinkedChannel = &(LinkChannel->FirstLink); + while (*LinkedChannel && ((*LinkedChannel)->Channel == Channel)) + LinkedChannel = &((*LinkedChannel)->Next); + if (!*LinkedChannel) + *LinkedChannel = new TChannelLink; + // Set Parameters + (*LinkedChannel)->Function = this; + (*LinkedChannel)->Channel = Channel; + (*LinkedChannel)->Input = Output; + (*LinkedChannel)->Output = Input; + + // Log Event + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Reverse Channel Linked - '%s'-->'%s' - In:%s, Out:%s", + ProcessName, Name, LinkChannel->Ref, (*LinkedChannel)->Channel->Ref, ((Output)? "Yes" : "No"), ((Input)? "Yes" : "No") ); return true; } //--------------------------------------------------------------------------- @@ -274,9 +308,8 @@ int CFunctionCore::Input( const char * ChannelName, const char * SourceRef, cons ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); return 0; } - else if (!Channel->InputEnabled) { - // Channel disabled - if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'-'%s' - Input rejected, Channel input disabled", + else if (!Channel->Ready) { + if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready", ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); return 0; } @@ -316,7 +349,7 @@ int CFunctionCore::Output( const char * ChannelName, const char * TargetRef, con int CFunctionCore::Output( const TChannel * Channel, const char * TargetRef, const bool SourceRef, const char * Data, int Len, int OutputFormat ) { - TChannelLink * OutChannel = NULL; + TChannelLink * LinkChannel = NULL; int TempLen = 0; int OutLen = 0; @@ -325,27 +358,20 @@ int CFunctionCore::Output( const TChannel * Channel, const char * TargetRef, con return 0; } - // Check if enabled - if (!Channel->OutputEnabled) { - if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s' - Output rejected, Channel output disabled", - ProcessName, Name, Channel->Name, ((TargetRef && *TargetRef)? TargetRef : "(All)") ); - return 0; - } - // Log event - if (Log) Log->Output( LogLevel, dlHigh, ((!OutputFormat)? LogOutput : OutputFormat), Data, Len, "%s/%s: Channel '%s' - OUT:", + if (Log) Log->Output( LogLevel, dlHigh, ((!OutputFormat)? LogOutput : OutputFormat), Data, Len, "%s/%s: Channel '%s'->'%s' - OUT:", ProcessName, Name, Channel->Name, ((TargetRef && *TargetRef)? TargetRef : "(All)") ); // Pass output to all linked inputs if (Len == -1) Len = strlen( Data ); - OutChannel = Channel->FirstLink; - while (OutChannel) { - if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, OutChannel->Ref )) { - TempLen = OutChannel->Function->Input( OutChannel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len ); + LinkChannel = Channel->FirstLink; + while (LinkChannel) { + if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, LinkChannel->Channel->Ref )) { + TempLen = LinkChannel->Function->Input( LinkChannel->Channel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len ); OutLen = (TempLen > OutLen)? TempLen : OutLen; } - OutChannel = OutChannel->Next; + LinkChannel = LinkChannel->Next; } // Return processed bytes diff --git a/FunctionCore.h b/FunctionCore.h index a82c1f9..4866372 100644 --- a/FunctionCore.h +++ b/FunctionCore.h @@ -30,10 +30,7 @@ struct SChannel char * Name = NULL; char * Ref = NULL; - TChannelLink * FirstLink = NULL; // List of channels from which input can be received - - bool InputEnabled = NULL; // Can Channel receive input - bool OutputEnabled = NULL; // Can channel receive output + TChannelLink * FirstLink = NULL; // List of channels linked for input/output bool Ready = false; // Channel ready to receive input @@ -44,8 +41,10 @@ struct SChannel struct SChannelLink { CFunctionCore * Function = NULL; - char * Name = NULL; - char * Ref = NULL; + TChannel * Channel = NULL; + + bool Input = false; + bool Output = false; SChannelLink * Next = NULL; }; @@ -84,6 +83,13 @@ protected: Channel = Channel->Next; return Channel; } + inline TChannelLink * GetLinkChannel( TChannel * Channel, const char * LinkRef ) { + if (!Channel || !LinkRef ) return NULL; + SChannelLink * LinkChannel = Channel->FirstLink; + while (LinkChannel && strcmp( LinkRef, LinkChannel->Channel->Ref )) + LinkChannel = LinkChannel->Next; + return LinkChannel; + } // Data Input/Output virtual int Output( const TChannel * Channel, const char * TargetRef, const bool SourceRef, const char * Data, int Len, int OutputFormat = loNone ); @@ -106,34 +112,17 @@ public: inline const char * GetType() { return Type; }; // Manage Channels - virtual TChannel * AddChannel( const char * ChannelName, const bool pInputEnable = true, const bool pOutputEnabled = true ); - inline bool SetChannelOutEnable( const char * ChannelName, const bool pOutputEnable ) { - TChannel * Channel = GetChannel( ChannelName ); - if (!Channel) return false; - Channel->OutputEnabled = pOutputEnable; - return true; - } - inline bool SetChannelInEnable( const char * ChannelName, const bool pInputEnable ) { - TChannel * Channel = GetChannel( ChannelName ); - if (!Channel) return false; - Channel->InputEnabled = pInputEnable; - return true; - } - inline bool isInputEnabled( const char * ChannelName ) { - TChannel * Channel = GetChannel( ChannelName ); - return ((Channel)? Channel->InputEnabled : false); - } - inline bool isOutputEnabled( const char * ChannelName ) { - TChannel * Channel = GetChannel( ChannelName ); - return ((Channel)? Channel->OutputEnabled : false); - } + virtual TChannel * AddChannel( const char * ChannelName, const bool Ready ); + + virtual bool SetChannelState( TChannel * Channel, const bool Ready ); + virtual bool ChannelStateEvent( TChannel * Channel, const char * SourceRef, const bool Ready ); // Pushing Data Output -> Input virtual int Output( const char * ChannelName, const char * TargetRef, const bool SourceRef, const char * Data, int Len = -1 ); virtual int Input( const char * ChannelName, const char * SourceRef, const char * Data, int Len = -1 ); // Automated Data Input/Output - virtual bool LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Bidirectional ); + virtual bool LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Input, bool Output ); virtual bool Process() = 0; friend class CApplication; diff --git a/SelectableBare.cpp b/SelectableBare.cpp index 43deb90..48d3f0b 100644 --- a/SelectableBare.cpp +++ b/SelectableBare.cpp @@ -112,7 +112,7 @@ THandle * CSelectableBare::CreateHandle( const char * HandleName, bool CreateCh // Create Matching Channel if (CreateChannel) { - (*Handle)->Channel = AddChannel( HandleName ); + (*Handle)->Channel = AddChannel( HandleName, false ); } return *Handle; @@ -218,6 +218,31 @@ bool CSelectableBare::ClearHandle( THandle * Handle ) } //--------------------------------------------------------------------------- +bool CSelectableBare::ChangeState( THandle * Handle, EConnectState State ) +{ + bool Ready; + + // Validate + if (!Handle || (Handle->State == State)) + return false; + + // Set Call back + if (Handle->StateCallback[ (int)State ]) + (Handle->StateCallback[ (int)State ])( this, Handle, State ); + + // Change state + Handle->State = State; + + // Update Channel + if (Handle->Channel) { + Ready = ((Handle->State == csOpen) || (Handle->State == csDataWaiting)); + if (Handle->Channel->Ready != Ready) + SetChannelState( Handle->Channel, Ready ); + } + return true; +} +//--------------------------------------------------------------------------- + bool CSelectableBare::SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback ) { // Validate @@ -356,6 +381,7 @@ int CSelectableBare::Open( THandle * Handle, bool DelayResolve ) { THandle * NewHandle = NULL; + // Validate if (!Handle || (Handle->Type == ctNone)) { return -1; @@ -391,11 +417,11 @@ int CSelectableBare::Open( THandle * Handle, bool DelayResolve ) Selector->Add( Handle->FD, true, false, Handle, this ); } - // Set state - ChangeState( Handle, csOpen ); - // Set timer (for re-open or auto-close) SetStartTime( &Handle->LastAction ); + + // Set state + ChangeState( Handle, csOpen ); return (NewHandle)? NewHandle->FD : -1; }; //--------------------------------------------------------------------------- @@ -411,7 +437,16 @@ bool CSelectableBare::Close( THandle * Handle, bool QuickReopen ) // Close Handle Fail = (close( Handle->FD ))? true : false; - ChangeState( Handle, ((Fail)? csFailed : csClosed) ); + + // Remove from Select List + if (!Fail && Selector) { + if (Handle->Type != ctUDPremote) { + Selector->Remove( Handle->FD, true, true ); + } + } + + // Reset FD + Handle->FD = ((Fail)? Handle->FD : -1); // Start timer (for re-open) if (QuickReopen) @@ -423,15 +458,8 @@ bool CSelectableBare::Close( THandle * Handle, bool QuickReopen ) if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - %s", ProcessName, Name, Handle->Name, ((Fail)? "failed" : "closed") ); - // Remove from Select List - if (!Fail && Selector) { - if (Handle->Type != ctUDPremote) { - Selector->Remove( Handle->FD, true, true ); - } - } - - // Reset FD - Handle->FD = ((Fail)? Handle->FD : -1); + // Set State + ChangeState( Handle, ((Fail)? csFailed : csClosed) ); return true; } //--------------------------------------------------------------------------- @@ -695,9 +723,9 @@ int CSelectableBare::Input( const char * ChannelName, const char * SourceRef, co ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); return 0; } - else if (!Channel->InputEnabled) { + else if (!Channel->Ready) { // Channel disabled - if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel input disabled", + if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'->'%s' - Input rejected, Channel not Ready", ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); return 0; } diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 1f9537b..97faf75 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -632,6 +632,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle ) // Set state close( Handle->FD ); Handle->FD = -1; + ChangeState( Handle, csFailed ); return NULL; }; @@ -646,6 +647,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle ) // Set state close( Handle->FD ); Handle->FD = -1; + ChangeState( Handle, csFailed ); return NULL; }; @@ -729,11 +731,10 @@ THandle * CSelectableCore::OpenUNIXclientSocket( THandle * Handle ) // Close socket close( Handle->FD ); - ChangeState( Handle, csFailed ); + Handle->FD = -1; Handle->AddressFailed = true; - // Reset Handle - Handle->FD = -1; + ChangeState( Handle, csFailed ); return NULL; } } @@ -978,11 +979,13 @@ THandle * CSelectableCore::OpenUDPserverSocket( THandle * Handle, bool DelayReso if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to bind UDP socket [%s:%s] (%s)", ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); - // Set state + // Close handle close( Handle->FD ); Handle->FD = -1; - ChangeState( Handle, csFailed ); Handle->AddressFailed = true; + + // Change state + ChangeState( Handle, csFailed ); return NULL; }; @@ -1173,11 +1176,12 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to bind TCP Server socket [%s:%s] (%s)", ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); - // Set state + // Close handle close( Handle->FD ); Handle->FD = -1; - ChangeState( Handle, csFailed ); Handle->AddressFailed = true; + + ChangeState( Handle, csFailed ); return NULL; }; @@ -1188,11 +1192,12 @@ THandle * CSelectableCore::OpenTCPserverSocket( THandle * Handle, bool DelayReso if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Failed to listen on TCP Server socket [%s:%s] (%s)", ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); - // Set state + // Close handle close( Handle->FD ); Handle->FD = -1; - ChangeState( Handle, csFailed ); Handle->AddressFailed = true; + + ChangeState( Handle, csFailed ); return NULL; }; @@ -1362,9 +1367,10 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Could not set KeepAlive options [%s:%s] (%s)", ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) ); - // Set State + // Close handle close( Handle->FD ); Handle->FD = -1; + ChangeState( Handle, csFailed ); return NULL; } @@ -1413,11 +1419,10 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso // Close socket close( Handle->FD ); - ChangeState( Handle, csFailed ); + Handle->FD = -1; Handle->AddressFailed = true; - // Reset Handle - Handle->FD = -1; + ChangeState( Handle, csFailed ); return NULL; } } @@ -1515,7 +1520,16 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen ) } else { Fail = (close( Handle->FD ))? true : false; } - ChangeState( Handle, ((Fail)? csFailed : csClosed) ); + + // Remove from Select List + if (!Fail && Selector) { + if (Handle->Type != ctUDPremote) { + Selector->Remove( Handle->FD, true, true ); + } + } + + // Reset FD + Handle->FD = ((Fail)? Handle->FD : -1); // Start timer (for re-open) if (QuickReopen) @@ -1599,15 +1613,8 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen ) break; }; - // Remove from Select List - if (!Fail && Selector) { - if (Handle->Type != ctUDPremote) { - Selector->Remove( Handle->FD, true, true ); - } - } - - // Reset FD - Handle->FD = ((Fail)? Handle->FD : -1); + // Change State + ChangeState( Handle, ((Fail)? csFailed : csClosed) ); return true; } //--------------------------------------------------------------------------- diff --git a/SelectableCore.h b/SelectableCore.h index cce7bc0..8e7f51c 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -194,6 +194,7 @@ protected: // Managing File Handles bool RemoveHandle( THandle * Handle ); bool DestroyHandle( THandle * Handle ); + bool ChangeState( THandle * Handle, EConnectState State ); // Get Parameters inline int GetFD( const char * HandleName ) { @@ -201,15 +202,6 @@ protected: return ((Handle)? Handle->FD : -1); }; - // General fucntions - inline bool ChangeState( THandle * Handle, EConnectState State ) { - if (!Handle || (Handle->State == State)) return false; - if (Handle->StateCallback[ (int)State ]) - (Handle->StateCallback[ (int)State ])( this, Handle, State ); - Handle->State = State; - return true; - } - // Mutual Operations int ReadFromFD( int FD, char * Data, int MaxLen ); int WriteToFD( int FD, const char * Data, int Len, bool Force ); @@ -230,19 +222,17 @@ public: virtual ~CSelectableBare(); // Configuration - virtual bool Init( CDataMember * FunctionConfig ) = 0; + virtual bool Init( CDataMember * FunctionConfig ) = 0; // Finding Handles - inline THandle * GetHandle( const char * HandleName ) - { + inline THandle * GetHandle( const char * HandleName ) { if (!HandleName) return NULL; THandle * Handle = FirstHandle; while ( Handle && strcmp( HandleName, Handle->Name )) Handle = Handle->Next; return Handle; } - inline THandle * GetHandle( int FD ) - { + inline THandle * GetHandle( int FD ) { if (FD < 0) return NULL; THandle * Handle = FirstHandle; while ( Handle && (FD != Handle->FD)) @@ -263,7 +253,7 @@ public: bool ClearHandle( THandle * Handle ); // FD Operations - virtual int Open( THandle * Handle, bool DelayResolve = false ) = 0; + virtual int Open( THandle * Handle, bool DelayResolve = false ) = 0; virtual bool Close( THandle * Handle, bool QuickReopen ); virtual bool Read( THandle * Handle ); virtual bool Write( THandle * Handle );