From 92db4da7de5b73a7516b80a578f69dd8182b5275 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Thu, 16 Feb 2017 03:12:18 +0200 Subject: [PATCH] Importnant update: - Add callback functions for change in socket states --- SelectableCore.cpp | 43 ++++++++++++++++++++++++++++--------------- SelectableCore.h | 26 +++++++++++++++++++++----- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 1e430f4..6ecef1a 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -259,6 +259,19 @@ bool CSelectableCore::ClearHandle( THandle * Handle ) } //--------------------------------------------------------------------------- +bool CSelectableCore::SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback ) +{ + // Validate + if (!Handle) { + return false; + } + + // Set callback + Handle->StateCallback[ (int)pState ] = pCallback; + return true; +} +//--------------------------------------------------------------------------- + bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, int ReopenTime ) { // Validate @@ -348,7 +361,7 @@ int CSelectableCore::OpenPort( THandle * Handle ) } // Set state - Handle->State = csOpen; + ChangeState( Handle, csOpen ); return Handle->FD; } @@ -440,7 +453,7 @@ int CSelectableCore::OpenForkPipe( THandle * Handle ) } // Set state - Handle->State = csOpen; + ChangeState( Handle, csOpen ); return Handle->FD; } @@ -480,7 +493,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle ) if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to create Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) ); // Set state - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; }; @@ -492,7 +505,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle ) if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set socket options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) ); // Set state - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; } @@ -507,7 +520,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle ) if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) ); // Set state - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; } @@ -524,7 +537,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle ) // Set state close( Handle->FD ); Handle->FD = -1; - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; }; @@ -537,7 +550,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle ) // Set state close( Handle->FD ); Handle->FD = -1; - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; }; @@ -550,7 +563,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle ) } // Set state - Handle->State = csOpen; + ChangeState( Handle, csOpen ); return Handle->FD; } //--------------------------------------------------------------------------- @@ -639,7 +652,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle ) if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Remote Client connection open [%s]", Name, Handle->Name, Handle->Address ); // Update state - Handle->State = csOpen; + ChangeState( Handle, csOpen ); return Handle->FD; } } @@ -673,7 +686,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle ) if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to create Client socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) ); // Set Status - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; }; @@ -694,7 +707,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle ) // Set State close( Handle->FD ); Handle->FD = -1; - Handle->State = csFailed; + ChangeState( Handle, csFailed ); return -1; } } @@ -715,7 +728,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle ) } // Set status - Handle->State = csOpen; + ChangeState( Handle, csOpen ); return Handle->FD; } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY)) @@ -729,7 +742,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle ) } // Set status - Handle->State = csWaitingtoOpen; + ChangeState( Handle, csWaitingtoOpen ); return Handle->FD; } else @@ -744,7 +757,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle ) // Close socket close( Handle->FD ); - Handle->State = csFailed; + ChangeState( Handle, csFailed ); // Start re-open timer SetStartTime( &(Handle->ReopenStart) ); @@ -821,7 +834,7 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren ) // Close Handle Fail = (close( Handle->FD ))? true : false; - Handle->State = ((Fail)? csFailed : csClosed); + ChangeState( Handle, ((Fail)? csFailed : csClosed) ); // Start re-open timer SetStartTime( &(Handle->ReopenStart) ); diff --git a/SelectableCore.h b/SelectableCore.h index 0a6168d..49a4e9c 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -47,6 +47,9 @@ typedef struct SHandle THandle; class CSelect; class CSelectableCore; +// Callback function for handle events +typedef void (*FHandleCallback)( CSelectableCore * Function, THandle * Handle, EConnectState State ); + //--------------------------------------------------------------------------- // List of Handles for Select Object @@ -71,6 +74,14 @@ struct SHandle { char * Name; EConnectType Type; + // State + int FD; + EConnectState State; + bool Auto; + + // Callback functions + FHandleCallback StateCallback[ 6 ]; + // Type specific parameters char * Path; // Port (file)name or Exec path @@ -80,11 +91,6 @@ struct SHandle { int PortNo; // Socket port no bool KeepAlive; // Socket keep alive - // State - int FD; - EConnectState State; - bool Auto; - // Buffers CBuffer * InBuffer; CBuffer * OutBuffer; @@ -174,6 +180,15 @@ protected: return ((Handle)? Handle->State : csNone); }; + // 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; + } + // Port Operations virtual int OpenPort( THandle * Handle ); @@ -220,6 +235,7 @@ public: // Configuration THandle * CreateHandle( const char * HandleName, bool CreateChannel ); + bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback ); bool SetAutoManage( THandle * Handle, bool AutoManage, int ReopenTime = 0 ); bool SetBuffers( THandle * Handle, int InBufSize, int OutBufSize, int InTimeout, const char * InMarker, int InMarkerLen ); bool SerialConfig( THandle * Handle, int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );