Major Update:

- Minor fix: Set correct names in comments at top of file
- New FileCore Class:
  - Writing data to output file
- BufferCore:
  - Check for "EAGAIN" on write and retry write
- FunctionCore:
  - Add new Output method that references LocalIO directly
- SelectableCore:
  - New method SetAutomanage to specify auto re-open parameters
  - Re-open timer implemented to slow re-open events
  - Only call ProcessBuffer() if data received on socket
  - Force processing input data when no input marker set
  - Use new Output method to simplify code
  - Bug fix: Read correctly from buffer on multiple reads/writes on FD
  - Check for "EAGAIN" on write to FD and retry write
This commit is contained in:
Charl Wentzel
2016-07-20 09:37:25 +02:00
parent 6fee4d0eac
commit 1a9f825b25
11 changed files with 511 additions and 61 deletions

View File

@@ -13,6 +13,7 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -310,8 +311,9 @@ int CBuffer::ReadFromFD( int Handle, int MaxRead )
// Read from file descriptor // Read from file descriptor
BufRemain = BufSize - BufEnd; BufRemain = BufSize - BufEnd;
BytesRead = read( Handle, &Buffer[BufEnd], ((BufRemain > DataRemain)? DataRemain : BufRemain) ); BytesRead = read( Handle, &Buffer[BufEnd], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
if (BytesRead <= 0) if (BytesRead <= 0) {
break; break;
}
// Update Buffer Pointers // Update Buffer Pointers
DataRemain -= BytesRead; DataRemain -= BytesRead;
@@ -328,7 +330,6 @@ int CBuffer::ReadFromFD( int Handle, int MaxRead )
BufStart = BufEnd; BufStart = BufEnd;
} }
} }
return TotalRead; return TotalRead;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -355,8 +356,9 @@ int CBuffer::WriteToFD( int Handle, int MaxLen )
// Read from file descriptor // Read from file descriptor
BufRemain = BufSize - ReadPos; BufRemain = BufSize - ReadPos;
BytesWritten = write( Handle, &Buffer[ReadPos], ((BufRemain > DataRemain)? DataRemain : BufRemain) ); BytesWritten = write( Handle, &Buffer[ReadPos], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
if (BytesWritten <= 0) if ((BytesWritten <= 0) && (errno != EAGAIN)) {
break; break;
}
// Update Data Pointers // Update Data Pointers
TotalWritten += BytesWritten; TotalWritten += BytesWritten;

View File

@@ -1,3 +1,3 @@
PROJECT(lib_redAcore) PROJECT(lib_redAcore)
ADD_LIBRARY(redAcore TimingCore.cpp LogCore.cpp SignalCore.cpp BufferCore.cpp FunctionCore.cpp SelectCore.cpp SelectableCore.cpp) ADD_LIBRARY(redAcore TimingCore.cpp LogCore.cpp SignalCore.cpp BufferCore.cpp FunctionCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp)

330
FileCore.cpp Normal file
View File

@@ -0,0 +1,330 @@
/*
* FileCore.cpp
*
* Created on: 1 Jun 2016
* Author: wentzelc
*/
// redA Libraries
#include "FileCore.h"
#include "FunctionCore.h"
#include "TimingCore.h"
#include "LogCore.h"
// Standard C/C++ Libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
//---------------------------------------------------------------------------
// Constants
const float PI = 3.1415927;
//---------------------------------------------------------------------------
CFileCore::CFileCore( const char * Name, EDebugLevel pDebugLevel, int pOuputDisplay ) :
CFunctionCore( Name, pDebugLevel, pOuputDisplay )
{
FirstFile = NULL;
// temp
count = 0;
x = 0;
// temp
}
//---------------------------------------------------------------------------
CFileCore::~CFileCore()
{
TFileHandle * NextFile = NULL;
// Destroy file specs
while (FirstFile)
{
// Close file if open
CloseFile( FirstFile );
// Destroy file parameters
if (FirstFile->Name)
free( FirstFile->Name );
if (FirstFile->Path)
free( FirstFile->Path );
// Destroy File
NextFile = FirstFile->Next;
delete FirstFile;
FirstFile = NextFile;
}
}
//---------------------------------------------------------------------------
TFileHandle * CFileCore::AddFile( const char * Name, const char * Path, bool Append, bool CreateLocalIO )
{
TFileHandle ** FileHandle = NULL;
// Validate
if (!Name || !*Name || !Path || !*Path) {
return NULL;
}
// Find File or End of list
FileHandle = &FirstFile;
while (*FileHandle && strcmp( Name, (*FileHandle)->Name )) {
FileHandle = &((*FileHandle)->Next);
}
// Check if found
if (!*FileHandle)
{
// Create new
*FileHandle = (TFileHandle*)calloc( 1, sizeof(TFileHandle) );
// Set name & Path
(*FileHandle)->Name = (char*)malloc( strlen(Name)+1 );
strcpy( (*FileHandle)->Name, Name );
(*FileHandle)->Path = (char*)malloc( strlen(Path)+1 );
strcpy( (*FileHandle)->Path, Path );
}
// Create IO if necessary
if (CreateLocalIO) {
AddLocalIO( Name );
}
// Set Parameters
(*FileHandle)->Append = Append;
(*FileHandle)->FD = NO_FD;
// Return File
return (*FileHandle);
}
//---------------------------------------------------------------------------
bool CFileCore::SetFilePersistence( TFileHandle * FileHandle, bool Persistent, int PersistTimeout )
{
// Validate
if (!FileHandle) {
return false;
}
// Set parameters
FileHandle->Persistent = Persistent;
FileHandle->PersistTimeout = PersistTimeout;
// Open persistent file
if (Persistent && (!PersistTimeout)) {
OpenFile( FileHandle );
SetStartTime( &(FileHandle->PersistTime) );
}
// Close non-persistent file
else if (!Persistent && isOpen(FileHandle)) {
CloseFile( FileHandle );
}
return true;
}
//---------------------------------------------------------------------------
bool CFileCore::OpenFile( TFileHandle * FileHandle )
{
// Validate
if (!FileHandle) {
return false;
}
// Open file if not already open
if (!isOpen( FileHandle ))
{
// temp
//char FilePath[50];
//sprintf( FilePath, "%s%03d", FileHandle->Path, x++ );
//LogMessage( DebugLevel, dlNone, "f: %s", FilePath );
// temp
// GEt file handle
(FileHandle)->FD = open( FileHandle->Path, O_WRONLY | O_CREAT | ((FileHandle->Append)? O_APPEND : O_TRUNC), 0664 );
// Report event
if (isOpen(FileHandle))
{
// Set timer
SetStartTime( &(FileHandle->PersistTime) );
// temp
count = 0;
// temp
// Report result
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Opened", Name, FileHandle->Name );
}
}
// Check if failed
if (!isOpen(FileHandle))
{
// Report result
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Could not open (%d) %s", Name, FileHandle->Name, errno, strerror(errno) );
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool CFileCore::CloseFile( TFileHandle * FileHandle )
{
// Validate
if (!FileHandle) {
return false;
}
// Close file if not already open
if (isOpen(FileHandle))
{
// Close file
close( FileHandle->FD );
FileHandle->FD = NO_FD;
// Report result
if (!isOpen(FileHandle)) {
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Closed", Name, FileHandle->Name );
} else {
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Could not close", Name, FileHandle->Name );
}
// temp
LogMessage( DebugLevel, dlNone, "%s: File '%s' - Bytes written %d (%d)", Name, FileHandle->Name, count, (count-5038848) );
// temp
}
return true;
}
//---------------------------------------------------------------------------
int CFileCore::ReadFromFD( int FD, char * Data, int MaxLen )
{
int BytesRead = 0;
int TotalRead = 0;
int DataRemain = 0;
// Check if buffer created
if ((FD == -1) || !Data) {
return 0;
}
// Read Data into buffer
DataRemain = (MaxLen == -1)? strlen(Data) : MaxLen;
while (DataRemain)
{
// Read from file descriptor
BytesRead = read( FD, &Data[TotalRead], DataRemain );
if (BytesRead <= 0)
break;
// Update Data Pointers
TotalRead += BytesRead;
DataRemain -= BytesRead;
}
return TotalRead;
}
//---------------------------------------------------------------------------
int CFileCore::WriteToFD( int FD, const char * Data, int Len )
{
int BytesWritten = 0;
int TotalWritten = 0;
int DataRemain = 0;
// Check if buffer created
if ((FD == -1) || !Data) {
return 0;
}
// Read Data into buffer
DataRemain = (Len == -1)? strlen(Data) : Len;
while (DataRemain)
{
// Read from file descriptor
BytesWritten = write( FD, &Data[TotalWritten], DataRemain );
if ((BytesWritten <= 0) && (errno != EAGAIN))
break;
// Update Data Pointers
TotalWritten += BytesWritten;
DataRemain -= BytesWritten;
}
return TotalWritten;
}
//---------------------------------------------------------------------------
// Manual Data Input/Output
int CFileCore::Input( const char * IOName, const char * Data, int MaxLen )
{
TFileHandle * FileHandle = NULL;
int BytesWritten = 0;
// Validate
if (!IOName || !Data) {
return 0;
}
else if (MaxLen == -1) {
MaxLen = strlen( Data );
};
// Get IO
if (!(FileHandle = GetFile( IOName )))
{
// Log event
LogMessage( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Local IO not found", Name, IOName );
return 0;
}
// Log event
//ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, MaxLen, "%s: Local IO '%s' - IN:", Name, IOName );
// Open file
if (!OpenFile( FileHandle )) {
return 0;
}
// Handle Incoming data
BytesWritten = WriteToFD( FileHandle->FD, Data, MaxLen );
SetStartTime( &(FileHandle->PersistTime) );
// temp
count += BytesWritten;
// temp
// Return processed bytes
return BytesWritten;
}
//---------------------------------------------------------------------------
bool CFileCore::Process()
{
TFileHandle * FileHandle;
// Close Persistent files not used
FileHandle = FirstFile;
while (FileHandle)
{
if (isOpen(FileHandle) &&
(!FileHandle->Persistent ||
(FileHandle->PersistTimeout && Timeout( FileHandle->PersistTime, FileHandle->PersistTimeout )))) {
CloseFile( FileHandle );
}
// Next
FileHandle = FileHandle->Next;
}
return true;
}
//---------------------------------------------------------------------------

83
FileCore.h Normal file
View File

@@ -0,0 +1,83 @@
/*
* FileCore.h
*
* Created on: 1 Jun 2016
* Author: wentzelc
*/
#ifndef JOANETELEMETRY_FILECORE_H_
#define JOANETELEMETRY_FILECORE_H_
// redA Libraries
#include "FunctionCore.h"
// Standard C/C++ Libraries
/* none */
//---------------------------------------------------------------------------
const int NO_FD = -1;
typedef struct SFileHandle TFileHandle;
struct SFileHandle
{
char * Name; // Quick reference
char * Path; // Actual location of file
int FD; // File Descriptor
bool Append; // Append data to end of file
bool Persistent; // Keep file open after write
timeval PersistTime; // Time opened/last written to
bool PersistTimeout; // Time to remain open, 0 = permanently open
TFileHandle * Next;
};
//---------------------------------------------------------------------------
class CFileCore : public CFunctionCore
{
private:
// File
TFileHandle * FirstFile;
// temp
int count;
int x;
// temp
// Manage File
virtual bool OpenFile( TFileHandle * FileHandle );
virtual bool CloseFile( TFileHandle * FileHandle );
virtual int ReadFromFD( int FD, char * Data, int MaxLen );
virtual int WriteToFD( int FD, const char * Data, int Len );
inline TFileHandle * GetFile( const char * Name ) {
if (!Name || !*Name) return NULL;
TFileHandle * FileHandle = FirstFile;
while (FileHandle && strcmp( Name, FileHandle->Name ))
FileHandle = FileHandle->Next;
return FileHandle;
};
inline bool isOpen( TFileHandle * FileHandle ) { return (FileHandle->FD != NO_FD); };
public:
// Life cycle
CFileCore( const char * Name, EDebugLevel pDebugLevel, int pOuputDisplay );
~CFileCore();
// Manage files
virtual TFileHandle * AddFile( const char * Name, const char * Path, bool Append = true, bool CreateLocalIO = true );
virtual bool SetFilePersistence( TFileHandle * FileHandle, bool Persistent, int PersistTimeout );
// Data Input
virtual int Input( const char * IOName, const char * Data, int MaxLen = -1 );
// Processing data
virtual bool Process();
};
//---------------------------------------------------------------------------
#endif /* JOANETELEMETRY_FILECORE_H_ */

View File

@@ -260,8 +260,31 @@ int CFunctionCore::Output( const char * IOName, const char * Data, int Len )
return 0; return 0;
} }
// Return processed bytes
return Output( LocalIO, Data, Len );
}
//---------------------------------------------------------------------------
int CFunctionCore::Output( const TLocalIO * LocalIO, const char * Data, int Len )
{
TLinkedIO * Output = NULL;
// Validate
if (!LocalIO || !Data) {
return 0;
} else if (Len == -1) {
Len = strlen( Data );
}
// Log event // Log event
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Local IO '%s' - OUT:", Name, IOName ); ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Local IO '%s' - OUT:", Name, LocalIO->Name );
// Pass output to all linked inputs
Output = LocalIO->FirstOutput;
while (Output) {
Output->Function->Input( Output->IOName, Data, Len );
Output = Output->Next;
}
// Return processed bytes // Return processed bytes
return Len; return Len;

View File

@@ -68,6 +68,9 @@ protected:
return LocalIO; return LocalIO;
} }
// Low Level Local IO interfaces
virtual int Output( const TLocalIO * LocalIO, const char * Data, int Len );
public: public:
// Life cycle // Life cycle
CFunctionCore( const char * ObjectName, EDebugLevel pDebugLevel, int pOuputDisplay ); CFunctionCore( const char * ObjectName, EDebugLevel pDebugLevel, int pOuputDisplay );

View File

@@ -1,5 +1,5 @@
/* /*
* Select.cpp * SelectCore.cpp
* *
* Created on: 13 May 2016 * Created on: 13 May 2016
* Author: wentzelc * Author: wentzelc

View File

@@ -1,5 +1,5 @@
/* /*
* CSelectableCore.cpp * SelectableCore.cpp
* *
* Created on: 20 May 2016 * Created on: 20 May 2016
* Author: wentzelc * Author: wentzelc
@@ -60,7 +60,7 @@ CSelectableCore::~CSelectableCore()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
THandle * CSelectableCore::CreateHandle( const char * HandleName, bool CreateLocalIO, bool AutoManage ) THandle * CSelectableCore::CreateHandle( const char * HandleName, bool CreateLocalIO )
{ {
THandle ** Handle = NULL; THandle ** Handle = NULL;
@@ -73,8 +73,7 @@ THandle * CSelectableCore::CreateHandle( const char * HandleName, bool CreateLo
if (!*Handle) if (!*Handle)
{ {
// Create File handle at end of list // Create File handle at end of list
*Handle = (THandle*)malloc( sizeof(THandle) ); *Handle = (THandle*)calloc( 1, sizeof(THandle) );
memset( *Handle, 0, sizeof(THandle) );
// Set name // Set name
if (HandleName) { if (HandleName) {
@@ -94,9 +93,6 @@ THandle * CSelectableCore::CreateHandle( const char * HandleName, bool CreateLo
(*Handle)->LocalIO = AddLocalIO( HandleName ); (*Handle)->LocalIO = AddLocalIO( HandleName );
} }
// Set other params
(*Handle)->Auto = AutoManage;
return *Handle; return *Handle;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -238,6 +234,20 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, int ReopenTime )
{
// Validate
if (!Handle) {
return false;
}
// Set params
Handle->Auto = AutoManage;
Handle->ReopenTimeout = ReopenTime;
return true;
}
//---------------------------------------------------------------------------
bool CSelectableCore::SetBuffers( THandle * Handle, int InBufSize, int OutBufSize, int InTimeout, const char * InMarker, int InMarkerLen ) bool CSelectableCore::SetBuffers( THandle * Handle, int InBufSize, int OutBufSize, int InTimeout, const char * InMarker, int InMarkerLen )
{ {
// Validate // Validate
@@ -473,7 +483,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
// Create Remote Client Handle // Create Remote Client Handle
sprintf( ClientName, "%s-%d", Handle->Name, ClientFD ); sprintf( ClientName, "%s-%d", Handle->Name, ClientFD );
*RemoteClient = CreateHandle( ClientName, false, false ); *RemoteClient = CreateHandle( ClientName, false );
SetSocketHandle( *RemoteClient, ctRemoteClient, ClientAddress, 0, Handle->KeepAlive ); SetSocketHandle( *RemoteClient, ctRemoteClient, ClientAddress, 0, Handle->KeepAlive );
// Copy Parent Buffer setup // Copy Parent Buffer setup
@@ -560,7 +570,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) )) (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{ {
// Log Event // Log Event
LogMessage( DebugLevel, dlMedium, "%s: Handle %s - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) ); LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
// Set State // Set State
close( Handle->FD ); close( Handle->FD );
@@ -578,7 +588,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
if (!connect( Handle->FD, (struct sockaddr *)&address, addr_len )) if (!connect( Handle->FD, (struct sockaddr *)&address, addr_len ))
{ {
LogMessage( DebugLevel, dlMedium, "%s: Handle %s - Client connected [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo ); LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Client connected [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
// Add to Select Lists // Add to Select Lists
if (Select) { if (Select) {
@@ -615,8 +625,13 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
// Close socket // Close socket
close( Handle->FD ); close( Handle->FD );
Handle->FD = -1;
Handle->State = csFailed; Handle->State = csFailed;
// Start re-open timer
SetStartTime( &(Handle->ReopenStart) );
// Reset Handle
Handle->FD = -1;
return -1; return -1;
} }
} }
@@ -686,6 +701,9 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
Fail = (close( Handle->FD ))? true : false; Fail = (close( Handle->FD ))? true : false;
Handle->State = ((Fail)? csFailed : csClosed); Handle->State = ((Fail)? csFailed : csClosed);
// Start re-open timer
SetStartTime( &(Handle->ReopenStart) );
// Show action // Show action
switch (Handle->Type) switch (Handle->Type)
{ {
@@ -787,17 +805,16 @@ bool CSelectableCore::Read( THandle * Handle )
} }
// Read File directly into buffer // Read File directly into buffer
if (!Handle->InBuffer || !(BytesRead = Handle->InBuffer->ReadFromFD( Handle->FD ))) { if (Handle->InBuffer && (BytesRead = Handle->InBuffer->ReadFromFD( Handle->FD )))
return false; {
}
// Process Buffer // Process Buffer
ProcessBuffer( Handle, false ); ProcessBuffer( Handle, false );
}
// Reset timer // Reset timer
SetStartTime( &(Handle->InStart) ); SetStartTime( &(Handle->InStart) );
return true; return (bool)BytesRead;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -874,8 +891,6 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
int Pos = 0; int Pos = 0;
int Len = 0; int Len = 0;
char * Data = NULL; char * Data = NULL;
TLocalIO * LocalIO = NULL;
TLinkedIO * Output = NULL;
// Check if buffered data // Check if buffered data
if (!Handle || !Handle->InBuffer || !Handle->InBuffer->Len()) { if (!Handle || !Handle->InBuffer || !Handle->InBuffer->Len()) {
@@ -883,7 +898,7 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
} }
// Check if forced processed // Check if forced processed
if (Force) if (Force || !Handle->InMarkerLen)
{ {
// Show Packet // Show Packet
Len = Handle->InBuffer->Peek( &Data ); Len = Handle->InBuffer->Peek( &Data );
@@ -891,18 +906,9 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
// Write buffer to Outputs // Write buffer to Outputs
if (Handle->Type == ctRemoteClient) { if (Handle->Type == ctRemoteClient) {
LocalIO = Handle->Parent->LocalIO; Output( Handle->Parent->LocalIO, Data, Len );
} else { } else {
LocalIO = Handle->LocalIO; Output( Handle->LocalIO, Data, Len );
}
if (LocalIO) {
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: LocalIO '%s' - OUT:", Name, LocalIO->Name );
Output = LocalIO->FirstOutput;
while (Output) {
Output->Function->Input( Output->IOName, Data, Len );
Output = Output->Next;
}
} }
// Clear processed bytes from buffer // Clear processed bytes from buffer
@@ -919,18 +925,9 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
// Write buffer to Outputs // Write buffer to Outputs
if (Handle->Type == ctRemoteClient) { if (Handle->Type == ctRemoteClient) {
LocalIO = Handle->Parent->LocalIO; Output( Handle->Parent->LocalIO, Data, Len );
} else { } else {
LocalIO = Handle->LocalIO; Output( Handle->LocalIO, Data, Len );
}
if (LocalIO) {
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: LocalIO '%s' - OUT:", Name, LocalIO->Name );
Output = LocalIO->FirstOutput;
while (Output) {
Output->Function->Input( Output->IOName, Data, Len );
Output = Output->Next;
}
} }
// Clear processed bytes from buffer // Clear processed bytes from buffer
@@ -957,15 +954,15 @@ int CSelectableCore::ReadFromFD( int FD, char * Data, int MaxLen )
while (DataRemain) while (DataRemain)
{ {
// Read from file descriptor // Read from file descriptor
BytesRead = read( FD, Data, DataRemain ); BytesRead = read( FD, &Data[TotalRead], DataRemain );
if (BytesRead <= 0) if ((BytesRead <= 0)) {
break; break;
}
// Update Data Pointers // Update Data Pointers
TotalRead += BytesRead; TotalRead += BytesRead;
DataRemain -= BytesRead; DataRemain -= BytesRead;
} }
return TotalRead; return TotalRead;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -986,16 +983,15 @@ int CSelectableCore::WriteToFD( int FD, const char * Data, int Len )
while (DataRemain) while (DataRemain)
{ {
// Read from file descriptor // Read from file descriptor
BytesWritten = write( FD, Data, DataRemain ); BytesWritten = write( FD, &Data[TotalWritten], DataRemain );
//write( FD, "\n", 1 ); if ((BytesWritten <= 0) && (errno != EAGAIN)) {
if (BytesWritten <= 0)
break; break;
}
// Update Data Pointers // Update Data Pointers
TotalWritten += BytesWritten; TotalWritten += BytesWritten;
DataRemain -= BytesWritten; DataRemain -= BytesWritten;
} }
return TotalWritten; return TotalWritten;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -1105,9 +1101,17 @@ bool CSelectableCore::Process()
{ {
// Auto manage handles // Auto manage handles
if (Handle->Auto && ((Handle->State == csNone) || (Handle->State == csFailed) || (Handle->State == csClosed))) if (Handle->Auto && ((Handle->State == csNone) || (Handle->State == csFailed) || (Handle->State == csClosed)))
{
// Check duration since last PortIn
if (Timeout( Handle->ReopenStart, Handle->ReopenTimeout ))
{ {
// Complete opening process // Complete opening process
Open( Handle ); if (Open( Handle ) == -1)
{
// Reset Timer
SetStartTime( &(Handle->ReopenStart) );
}
}
} }
// Check Input buffers // Check Input buffers

View File

@@ -1,5 +1,5 @@
/* /*
* Select.h * SelectableCore.h
* *
* Created on: 13 May 2016 * Created on: 13 May 2016
* Author: wentzelc * Author: wentzelc
@@ -91,6 +91,10 @@ struct SHandle {
timeval InStart; timeval InStart;
long InTimeout; // millisecs long InTimeout; // millisecs
// Reopen Timer
timeval ReopenStart;
long ReopenTimeout; // millisecs
// List / Tree // List / Tree
TLocalIO * LocalIO; TLocalIO * LocalIO;
THandle * Parent; THandle * Parent;
@@ -207,7 +211,8 @@ public:
} }
// Configuration // Configuration
THandle * CreateHandle( const char * HandleName, bool CreateIO, bool AutoManage ); THandle * CreateHandle( const char * HandleName, bool CreateIO );
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 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 ); bool SerialConfig( THandle * Handle, int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );

View File

@@ -1,5 +1,5 @@
/* /*
* Timing.cpp * TimingCore.cpp
* *
* Created on: 13 May 2016 * Created on: 13 May 2016
* Author: wentzelc * Author: wentzelc

View File

@@ -1,5 +1,5 @@
/* /*
* Timing.h * TimingCore.h
* *
* Created on: 13 May 2016 * Created on: 13 May 2016
* Author: wentzelc * Author: wentzelc