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
This commit is contained in:
Charl Wentzel
2019-06-05 19:13:04 +02:00
parent fa6825b72a
commit 08fce64629
7 changed files with 202 additions and 154 deletions

View File

@@ -68,11 +68,19 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig )
// Add Channels // Add Channels
if (!(CmdChannel = GetChannel( "Command" ))) if (!(CmdChannel = GetChannel( "Command" )))
CmdChannel = AddChannel( "Command", true, true ); CmdChannel = AddChannel( "Command", true );
else
SetChannelState( CmdChannel, true );
if (!(DeviceChannel = GetChannel( "Device" ))) if (!(DeviceChannel = GetChannel( "Device" )))
DeviceChannel = AddChannel( "Device", true, true ); DeviceChannel = AddChannel( "Device", true );
else
SetChannelState( DeviceChannel, true );
if (!(EventChannel = GetChannel( "Event" ))) if (!(EventChannel = GetChannel( "Event" )))
EventChannel = AddChannel( "Event", true, true ); EventChannel = AddChannel( "Event", true );
else
SetChannelState( EventChannel, true );
// Load Polling configuration // Load Polling configuration
PollConfig = Config->GetChild( "Polling", true ); PollConfig = Config->GetChild( "Polling", true );

View File

@@ -86,7 +86,7 @@ TFileHandle * CFileCore::AddFile( const char * Name, const char * Path, bool Ap
// Create Channel if necessary // Create Channel if necessary
if (CreateChannel) { if (CreateChannel) {
AddChannel( Name ); AddChannel( Name, false );
} }
// Set Parameters // Set Parameters

View File

@@ -54,12 +54,8 @@ CFunctionCore::~CFunctionCore()
free( FirstChannel->Ref ); free( FirstChannel->Ref );
} }
// Destroy Linked Outputs // Destroy Linked Channels
while (FirstChannel->FirstLink) { while (FirstChannel->FirstLink) {
if (FirstChannel->FirstLink->Name) {
free( FirstChannel->FirstLink->Name );
free( FirstChannel->FirstLink->Ref );
}
NextLinkedChannel = FirstChannel->FirstLink->Next; NextLinkedChannel = FirstChannel->FirstLink->Next;
delete FirstChannel->FirstLink; delete FirstChannel->FirstLink;
FirstChannel->FirstLink = NextLinkedChannel; FirstChannel->FirstLink = NextLinkedChannel;
@@ -103,13 +99,8 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig )
// Load Channels // Load Channels
ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true ); ChannelConfig = FunctionConfig->GetChFirstChild( "Channels", true );
while (ChannelConfig) while (ChannelConfig) {
{ AddChannel( ChannelConfig->GetName(), false );
if (ChannelConfig->GetName()) {
AddChannel( ChannelConfig->GetName(),
ChannelConfig->GetChBool( "InputEnabled", true, true ),
ChannelConfig->GetChBool( "OutputEnabled", false, true ));
}
ChannelConfig = ChannelConfig->GetNextPeer(); ChannelConfig = ChannelConfig->GetNextPeer();
} }
@@ -118,7 +109,6 @@ bool CFunctionCore::Init( CDataMember * FunctionConfig )
ConfigName = (char*)FunctionConfig->GetChStr( "Config" ); ConfigName = (char*)FunctionConfig->GetChStr( "Config" );
Config = Application->Config->GetChild( ConfigName, true ); Config = Application->Config->GetChild( ConfigName, true );
} }
if (Config->isNull()) Config->SetObject();
return true; return true;
} }
@@ -145,9 +135,10 @@ bool CFunctionCore::InitChannelLinks( CDataMember * LinkConfig )
{ {
// Get Parameters // Get Parameters
LinkChannel( Channel->Name, LinkChannel( Channel->Name,
FunctionMember->GetChStr( "Function" ), FunctionMember->GetChStr( "Function", NULL, true ),
FunctionMember->GetChStr( "Channel" ), FunctionMember->GetChStr( "Channel", NULL, true ),
FunctionMember->GetChBool( "Bidirectional" ) ); FunctionMember->GetChBool( "Input", false, true ),
FunctionMember->GetChBool( "Output", false, true ) );
FunctionMember = FunctionMember->GetNextPeer(); 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; TChannel ** Channel = NULL;
@@ -197,63 +188,106 @@ TChannel * CFunctionCore::AddChannel( const char * ChannelName, const bool pInpu
// Set Name // Set Name
(*Channel)->Name = strdup( ChannelName ); (*Channel)->Name = strdup( ChannelName );
(*Channel)->Ref = (char*)malloc( strlen(Name)+strlen(ChannelName)+2 );
sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName ); sprintf( (*Channel)->Ref, "%s/%s", Name, ChannelName );
(*Channel)->Ready = Ready;
// Log Event // Log Event
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Channel '%s' - Created, Ref:'%s', Ready:%s",
ProcessName, Name, ChannelName ); ProcessName, Name, ChannelName, (*Channel)->Ref, (((*Channel)->Ready)? "Yes" : "No") );
} }
// Set parameters
(*Channel)->InputEnabled = pInputEnable;
(*Channel)->OutputEnabled = pOutputEnable;
return *Channel; return *Channel;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Automated Data Input/Output bool CFunctionCore::SetChannelState( TChannel * Channel, const bool Ready )
bool CFunctionCore::LinkChannel( const char * ChannelName, const char * LinkFunctionName, const char * LinkChannelName, bool Bidirectional )
{ {
TChannel * OutChannel = NULL; TChannelLink * LinkChannel;
CFunctionCore * InFunction = NULL;
TChannel * InChannel = NULL; // 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; TChannelLink ** LinkedChannel = NULL;
// Check if Channels & Function exist // Check if Channels & Function exist
if (!(OutChannel = GetChannel( ChannelName )) || if (!(Channel = GetChannel( ChannelName )) ||
!(InFunction = Application->GetFunction( LinkFunctionName )) || !(LinkFunction = Application->GetFunction( LinkFunctionName )) ||
!(InChannel = InFunction->GetChannel( LinkChannelName )) ) { !(LinkChannel = LinkFunction->GetChannel( LinkChannelName )) ) {
return false; return false;
} }
// Check if linked Channel exists // Check if linked Channel exists
LinkedChannel = &(OutChannel->FirstLink); LinkedChannel = &(Channel->FirstLink);
while (*LinkedChannel && (((*LinkedChannel)->Function != InFunction) || strcmp( (*LinkedChannel)->Name, LinkChannelName ) )) { while (*LinkedChannel && ((*LinkedChannel)->Channel == LinkChannel))
LinkedChannel = &((*LinkedChannel)->Next); LinkedChannel = &((*LinkedChannel)->Next);
}
// Create if not found
if (!*LinkedChannel) if (!*LinkedChannel)
{
// Create
*LinkedChannel = new TChannelLink; *LinkedChannel = new TChannelLink;
// Set Parameters // Set Parameters
(*LinkedChannel)->Function = InFunction; (*LinkedChannel)->Function = LinkFunction;
(*LinkedChannel)->Name = strdup( LinkChannelName ); (*LinkedChannel)->Channel = LinkChannel;
sprintf( (*LinkedChannel)->Ref, "%s/%s", LinkFunctionName, LinkChannelName ); (*LinkedChannel)->Input = Input;
(*LinkedChannel)->Output = Output;
// Log Event // Log Event
if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Output Linked - '%s/%s' --> '%s/%s'", if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Forward Channel Linked - '%s'-->'%s' - In:%s, Out:%s",
ProcessName, Name, Name, ChannelName, LinkFunctionName, LinkChannelName ); ProcessName, Name, Channel->Ref, (*LinkedChannel)->Channel->Ref, ((Input)? "Yes" : "No"), ((Output)? "Yes" : "No") );
}
// Link return direction as well // Find Linked channel on remote function
if (Bidirectional) { LinkedChannel = &(LinkChannel->FirstLink);
return InFunction->LinkChannel( LinkChannelName, Name, ChannelName, false ); 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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -274,9 +308,8 @@ int CFunctionCore::Input( const char * ChannelName, const char * SourceRef, cons
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0; 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 not Ready",
if (Log) Log->Message( LogLevel, dlHigh, "%s/%s: Channel '%s'-'%s' - Input rejected, Channel input disabled",
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0; 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 ) 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 TempLen = 0;
int OutLen = 0; int OutLen = 0;
@@ -325,27 +358,20 @@ int CFunctionCore::Output( const TChannel * Channel, const char * TargetRef, con
return 0; 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 // 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)") ); ProcessName, Name, Channel->Name, ((TargetRef && *TargetRef)? TargetRef : "(All)") );
// Pass output to all linked inputs // Pass output to all linked inputs
if (Len == -1) if (Len == -1)
Len = strlen( Data ); Len = strlen( Data );
OutChannel = Channel->FirstLink; LinkChannel = Channel->FirstLink;
while (OutChannel) { while (LinkChannel) {
if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, OutChannel->Ref )) { if (!TargetRef || !*TargetRef || !strcasecmp( TargetRef, LinkChannel->Channel->Ref )) {
TempLen = OutChannel->Function->Input( OutChannel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len ); TempLen = LinkChannel->Function->Input( LinkChannel->Channel->Name, ((SourceRef)? Channel->Ref : NULL), Data, Len );
OutLen = (TempLen > OutLen)? TempLen : OutLen; OutLen = (TempLen > OutLen)? TempLen : OutLen;
} }
OutChannel = OutChannel->Next; LinkChannel = LinkChannel->Next;
} }
// Return processed bytes // Return processed bytes

View File

@@ -30,10 +30,7 @@ struct SChannel
char * Name = NULL; char * Name = NULL;
char * Ref = NULL; char * Ref = NULL;
TChannelLink * FirstLink = NULL; // List of channels from which input can be received TChannelLink * FirstLink = NULL; // List of channels linked for input/output
bool InputEnabled = NULL; // Can Channel receive input
bool OutputEnabled = NULL; // Can channel receive output
bool Ready = false; // Channel ready to receive input bool Ready = false; // Channel ready to receive input
@@ -44,8 +41,10 @@ struct SChannel
struct SChannelLink struct SChannelLink
{ {
CFunctionCore * Function = NULL; CFunctionCore * Function = NULL;
char * Name = NULL; TChannel * Channel = NULL;
char * Ref = NULL;
bool Input = false;
bool Output = false;
SChannelLink * Next = NULL; SChannelLink * Next = NULL;
}; };
@@ -84,6 +83,13 @@ protected:
Channel = Channel->Next; Channel = Channel->Next;
return Channel; 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 // Data Input/Output
virtual int Output( const TChannel * Channel, const char * TargetRef, const bool SourceRef, const char * Data, int Len, int OutputFormat = loNone ); 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; }; inline const char * GetType() { return Type; };
// Manage Channels // Manage Channels
virtual TChannel * AddChannel( const char * ChannelName, const bool pInputEnable = true, const bool pOutputEnabled = true ); virtual TChannel * AddChannel( const char * ChannelName, const bool Ready );
inline bool SetChannelOutEnable( const char * ChannelName, const bool pOutputEnable ) {
TChannel * Channel = GetChannel( ChannelName ); virtual bool SetChannelState( TChannel * Channel, const bool Ready );
if (!Channel) return false; virtual bool ChannelStateEvent( TChannel * Channel, const char * SourceRef, const bool Ready );
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);
}
// Pushing Data Output -> Input // Pushing Data Output -> Input
virtual int Output( const char * ChannelName, const char * TargetRef, const bool SourceRef, const char * Data, int Len = -1 ); 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 ); virtual int Input( const char * ChannelName, const char * SourceRef, const char * Data, int Len = -1 );
// Automated Data Input/Output // 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; virtual bool Process() = 0;
friend class CApplication; friend class CApplication;

View File

@@ -112,7 +112,7 @@ THandle * CSelectableBare::CreateHandle( const char * HandleName, bool CreateCh
// Create Matching Channel // Create Matching Channel
if (CreateChannel) { if (CreateChannel) {
(*Handle)->Channel = AddChannel( HandleName ); (*Handle)->Channel = AddChannel( HandleName, false );
} }
return *Handle; 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 ) bool CSelectableBare::SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback )
{ {
// Validate // Validate
@@ -356,6 +381,7 @@ int CSelectableBare::Open( THandle * Handle, bool DelayResolve )
{ {
THandle * NewHandle = NULL; THandle * NewHandle = NULL;
// Validate // Validate
if (!Handle || (Handle->Type == ctNone)) { if (!Handle || (Handle->Type == ctNone)) {
return -1; return -1;
@@ -391,11 +417,11 @@ int CSelectableBare::Open( THandle * Handle, bool DelayResolve )
Selector->Add( Handle->FD, true, false, Handle, this ); Selector->Add( Handle->FD, true, false, Handle, this );
} }
// Set state
ChangeState( Handle, csOpen );
// Set timer (for re-open or auto-close) // Set timer (for re-open or auto-close)
SetStartTime( &Handle->LastAction ); SetStartTime( &Handle->LastAction );
// Set state
ChangeState( Handle, csOpen );
return (NewHandle)? NewHandle->FD : -1; return (NewHandle)? NewHandle->FD : -1;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -411,7 +437,16 @@ bool CSelectableBare::Close( THandle * Handle, bool QuickReopen )
// Close Handle // Close Handle
Fail = (close( Handle->FD ))? true : false; 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) // Start timer (for re-open)
if (QuickReopen) if (QuickReopen)
@@ -423,15 +458,8 @@ bool CSelectableBare::Close( THandle * Handle, bool QuickReopen )
if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - %s", if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - %s",
ProcessName, Name, Handle->Name, ((Fail)? "failed" : "closed") ); ProcessName, Name, Handle->Name, ((Fail)? "failed" : "closed") );
// Remove from Select List // Set State
if (!Fail && Selector) { ChangeState( Handle, ((Fail)? csFailed : csClosed) );
if (Handle->Type != ctUDPremote) {
Selector->Remove( Handle->FD, true, true );
}
}
// Reset FD
Handle->FD = ((Fail)? Handle->FD : -1);
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -695,9 +723,9 @@ int CSelectableBare::Input( const char * ChannelName, const char * SourceRef, co
ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0; return 0;
} }
else if (!Channel->InputEnabled) { else if (!Channel->Ready) {
// Channel disabled // 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 ); ProcessName, Name, ((SourceRef && *SourceRef)? SourceRef : "(Any)"), ChannelName );
return 0; return 0;
} }

View File

@@ -632,6 +632,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
// Set state // Set state
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed ); ChangeState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -646,6 +647,7 @@ THandle * CSelectableCore::OpenUNIXserverSocket( THandle * Handle )
// Set state // Set state
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed ); ChangeState( Handle, csFailed );
return NULL; return NULL;
}; };
@@ -729,11 +731,10 @@ THandle * CSelectableCore::OpenUNIXclientSocket( THandle * Handle )
// Close socket // Close socket
close( Handle->FD ); close( Handle->FD );
ChangeState( Handle, csFailed ); Handle->FD = -1;
Handle->AddressFailed = true; Handle->AddressFailed = true;
// Reset Handle ChangeState( Handle, csFailed );
Handle->FD = -1;
return NULL; 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)", 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) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Close handle
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true; Handle->AddressFailed = true;
// Change state
ChangeState( Handle, csFailed );
return NULL; 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)", 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) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Close handle
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true; Handle->AddressFailed = true;
ChangeState( Handle, csFailed );
return NULL; 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)", 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) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set state // Close handle
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed );
Handle->AddressFailed = true; Handle->AddressFailed = true;
ChangeState( Handle, csFailed );
return NULL; 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)", 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) ); ProcessName, Name, Handle->Name, Handle->HostName, Handle->PortName, strerror(errno) );
// Set State // Close handle
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1; Handle->FD = -1;
ChangeState( Handle, csFailed ); ChangeState( Handle, csFailed );
return NULL; return NULL;
} }
@@ -1413,11 +1419,10 @@ THandle * CSelectableCore::OpenTCPclientSocket( THandle * Handle, bool DelayReso
// Close socket // Close socket
close( Handle->FD ); close( Handle->FD );
ChangeState( Handle, csFailed ); Handle->FD = -1;
Handle->AddressFailed = true; Handle->AddressFailed = true;
// Reset Handle ChangeState( Handle, csFailed );
Handle->FD = -1;
return NULL; return NULL;
} }
} }
@@ -1515,7 +1520,16 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
} else { } else {
Fail = (close( Handle->FD ))? true : false; 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) // Start timer (for re-open)
if (QuickReopen) if (QuickReopen)
@@ -1599,15 +1613,8 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
break; break;
}; };
// Remove from Select List // Change State
if (!Fail && Selector) { ChangeState( Handle, ((Fail)? csFailed : csClosed) );
if (Handle->Type != ctUDPremote) {
Selector->Remove( Handle->FD, true, true );
}
}
// Reset FD
Handle->FD = ((Fail)? Handle->FD : -1);
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -194,6 +194,7 @@ protected:
// Managing File Handles // Managing File Handles
bool RemoveHandle( THandle * Handle ); bool RemoveHandle( THandle * Handle );
bool DestroyHandle( THandle * Handle ); bool DestroyHandle( THandle * Handle );
bool ChangeState( THandle * Handle, EConnectState State );
// Get Parameters // Get Parameters
inline int GetFD( const char * HandleName ) { inline int GetFD( const char * HandleName ) {
@@ -201,15 +202,6 @@ protected:
return ((Handle)? Handle->FD : -1); 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 // Mutual Operations
int ReadFromFD( int FD, char * Data, int MaxLen ); int ReadFromFD( int FD, char * Data, int MaxLen );
int WriteToFD( int FD, const char * Data, int Len, bool Force ); int WriteToFD( int FD, const char * Data, int Len, bool Force );
@@ -233,16 +225,14 @@ public:
virtual bool Init( CDataMember * FunctionConfig ) = 0; virtual bool Init( CDataMember * FunctionConfig ) = 0;
// Finding Handles // Finding Handles
inline THandle * GetHandle( const char * HandleName ) inline THandle * GetHandle( const char * HandleName ) {
{
if (!HandleName) return NULL; if (!HandleName) return NULL;
THandle * Handle = FirstHandle; THandle * Handle = FirstHandle;
while ( Handle && strcmp( HandleName, Handle->Name )) while ( Handle && strcmp( HandleName, Handle->Name ))
Handle = Handle->Next; Handle = Handle->Next;
return Handle; return Handle;
} }
inline THandle * GetHandle( int FD ) inline THandle * GetHandle( int FD ) {
{
if (FD < 0) return NULL; if (FD < 0) return NULL;
THandle * Handle = FirstHandle; THandle * Handle = FirstHandle;
while ( Handle && (FD != Handle->FD)) while ( Handle && (FD != Handle->FD))