- FunctionCore
- Replace Channel->Ready with Channel->State (off/waiting/ready)
- Add Function reference to Handle
- SelectableBare/Core:
- Implement async address resolve with event handling
- Create ResolveHandler() signal handler (friend) function
- Change Create/Remove/DestroyHandle() methods to virtual methods
- Move socket specific code to SelectableCore
- Rename ChangeState() to virtual HandleState()
- Move ClearHandle() from SelectableBare -> SelectableCore
- Implement new/delete from THandle
- Set max TCP SYN count on connect
152 lines
4.8 KiB
C++
152 lines
4.8 KiB
C++
/*
|
|
* SignalCore.cpp
|
|
*
|
|
* Created on: 17 May 2016
|
|
* Author: wentzelc
|
|
*/
|
|
|
|
// Standard C/C++ Libraries
|
|
#include <iostream>
|
|
#include <signal.h>
|
|
|
|
// redA Libraries
|
|
#include "ApplicationCore.h"
|
|
#include "SignalCore.h"
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Global vars
|
|
extern char * ProcessName;
|
|
extern CApplication * Application;
|
|
|
|
// Termination Vars
|
|
bool Terminate = false;
|
|
int TermCount = 0;
|
|
int MaxTermCount = 5;
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Configure Signal handling
|
|
void ConfigureSignalHandlers()
|
|
{
|
|
struct sigaction TermAct;
|
|
struct sigaction AbortAct;
|
|
|
|
// Signals to be ignored
|
|
signal( SIGCHLD, SIG_IGN );
|
|
signal( SIGPIPE, SIG_IGN );
|
|
|
|
// Signals for normal termination
|
|
TermAct.sa_handler = SignalTerminate;
|
|
sigemptyset( &TermAct.sa_mask );
|
|
TermAct.sa_flags = SA_RESTART;
|
|
|
|
sigaction( SIGHUP, &TermAct, NULL );
|
|
sigaction( SIGINT, &TermAct, NULL );
|
|
sigaction( SIGQUIT, &TermAct, NULL );
|
|
sigaction( SIGTERM, &TermAct, NULL );
|
|
sigaction( SIGTSTP, &TermAct, NULL );
|
|
|
|
// Signals for immediate termination
|
|
AbortAct.sa_handler = SignalAbort;
|
|
sigemptyset( &AbortAct.sa_mask );
|
|
AbortAct.sa_flags = 0;
|
|
|
|
sigaction( SIGABRT, &AbortAct, NULL );
|
|
sigaction( SIGFPE, &AbortAct, NULL );
|
|
sigaction( SIGILL, &AbortAct, NULL );
|
|
sigaction( SIGSEGV, &AbortAct, NULL );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Signal handler to terminate program the standard way
|
|
void SignalTerminate( int sig )
|
|
{
|
|
char SigName[10];
|
|
|
|
// Determine signal name
|
|
switch (sig)
|
|
{
|
|
case SIGHUP : strcpy( SigName, "SIGHUP " ); break;
|
|
case SIGINT : strcpy( SigName, "SIGINT " ); break;
|
|
case SIGQUIT : strcpy( SigName, "SIGQUIT" ); break;
|
|
case SIGTERM : strcpy( SigName, "SIGTERM" ); break;
|
|
case SIGTSTP : strcpy( SigName, "SIGTSTP" ); break;
|
|
default : strcpy( SigName, "UNKNOWN" ); break;
|
|
}
|
|
|
|
// Allow process to terminate normally
|
|
Terminate = true;
|
|
TermCount++;
|
|
|
|
std::cerr << std::endl << ProcessName << ": ***********************************" << std::endl;
|
|
|
|
// Create Application->Log Entry
|
|
if (Application->Log)
|
|
{
|
|
Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount );
|
|
// Check for Terminate Limit
|
|
if (TermCount < MaxTermCount) {
|
|
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating normally... **", ProcessName );
|
|
} else {
|
|
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::cerr << ProcessName << ": ** " << SigName << " signal received [" << TermCount << "] **" << std::endl;
|
|
// Check for Terminate Limit
|
|
if (TermCount < MaxTermCount) {
|
|
std::cerr << ProcessName << ": ** Terminating normally... **" << std::endl;
|
|
} else {
|
|
std::cerr << ProcessName << ": ** Terminating immediately! **" << std::endl;
|
|
}
|
|
}
|
|
|
|
std::cerr << ProcessName << ": ***********************************" << std::endl << std::endl;
|
|
|
|
// Check for Terminate Limit
|
|
if (TermCount >= MaxTermCount) {
|
|
exit( sig );
|
|
}
|
|
|
|
return;
|
|
}//---------------------------------------------------------------------------
|
|
|
|
// Signal Handler to terminate program immediately
|
|
void SignalAbort( int sig )
|
|
{
|
|
char SigName[10];
|
|
|
|
// Determine Signal name
|
|
switch (sig)
|
|
{
|
|
case SIGABRT : strcpy( SigName, "SIGABRT" ); break;
|
|
case SIGFPE : strcpy( SigName, "SIGFPE " ); break;
|
|
case SIGILL : strcpy( SigName, "SIGILL " ); break;
|
|
case SIGPIPE : strcpy( SigName, "SIGPIPE" ); break;
|
|
case SIGSEGV : strcpy( SigName, "SIGSEGV" ); break;
|
|
default : strcpy( SigName, "UNKNOWN" ); break;
|
|
}
|
|
|
|
// Show signal received
|
|
std::cerr << std::endl << ProcessName << ": ********************************" << std::endl;
|
|
|
|
// Create Application->Log Entry - but don't post
|
|
if (Application->Log) {
|
|
Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received **", ProcessName, SigName );
|
|
Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName );
|
|
}
|
|
else {
|
|
std::cerr << ProcessName << ": ** " << SigName << " signal received **" << std::endl;
|
|
std::cerr << ProcessName << ": ** Terminating immediately! **" << std::endl;
|
|
}
|
|
|
|
std::cerr << ProcessName << ": ********************************" << std::endl << std::endl;
|
|
|
|
// Terminate with signal
|
|
exit( sig );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|