Skeleton for InputProcessor Skeleton for ScannerPool git-svn-id: https://svn.microneil.com/svn/SNF4CGP/trunk@9 59e8e3e7-56fa-483b-b4b4-fa6ab0af3dfcmaster
#include "ExecutiveProcess.hpp" | #include "ExecutiveProcess.hpp" | ||||
#include "../SNF4CGP/CodeDweller/faults.hpp" | |||||
#include <iostream> | |||||
using namespace std; | using namespace std; | ||||
RuntimeCheck CheckOutputProccessorWasConstructed("ExecutiveProcess::initializeOutput() Check(0 != Output)"); | |||||
RuntimeCheck CheckOutputProcessorWasStarted("ExecutiveProcess::initializeOutput() Check(Output->isRunning())"); | |||||
void ExecutiveProcess::initializeOutput() { | |||||
try { Output = new OutputProcessor(*Jobs); } catch(...) {} | |||||
CheckOutputProcessorWasConstructed(0 != Output); | |||||
try { Output->start() } catch(...) {} | |||||
CheckOutputProcessorWasStarted(Output->isRunning()); | |||||
} | |||||
void ExecutiveProcess::initializeJobPool() { | |||||
} | |||||
void ExecutiveProcess::initializeWorkerPool() { | |||||
} | |||||
void ExecutiveProcess::shutdownWorkerPool() { | |||||
} | |||||
void ExecutiveProcess::shutdownJobPool() { | |||||
} | |||||
void ExecutiveProcess::shutdownOutput() { | |||||
} | |||||
void ExecutiveProcess::dispatchCommand(Command& C) { // Job + Worker + Command; go! | |||||
} | |||||
ExecutiveProcess::ExecutiveProcess(string& Version, string& Config) : // Simple construction. | |||||
VersionInfo(Version), | |||||
ConfigInfo(Config), | |||||
Jobs(0), | |||||
Workers(0), | |||||
Input(0), | |||||
Output(0), | |||||
QuitJobNumber(0) {} | |||||
~ExecutiveProcess::ExecutiveProcess() { // Deal with uncerimoneous shutdowns. | |||||
} | |||||
void ExecutiveProcess::doStartup() { // Startup happens in this sequence. | |||||
initializeJobPool(); | |||||
initializeOutput(); | |||||
initializeWorkerPool(); | |||||
} | |||||
void ExecutiveProcess::doProcessing() { // Command processing happens here. | |||||
Command C; | |||||
C.CommandType = WAKE; // Create the WAKE command to announce | |||||
C.Data = VersionInfo; // that we are alive (and who we are) | |||||
dispatchCommand(C); // and dispatch a job with it. | |||||
// Then process all incoming commands: | |||||
InputProcessor& I = *Input; // Convenient handle for input processor. | |||||
for(;0 == QuitJobNumber;) { // Loop until we have a QUIT job. | |||||
C = I.getCommand(); // Get a command from the input. | |||||
if(QUIT == C.CommandType) QuitJobNumber = C.Number; // QUIT command means it's time to stop. | |||||
else dispatchCommand(C); // Dispatch a job for all other commands. | |||||
} | |||||
} | |||||
void ExecutiveProcess::doShutdown() { // Shutdown happens in this sequence. | |||||
shutdownWorkerPool(); | |||||
shutdownOutput(); | |||||
shutdownJobPool(); | |||||
cout << QuitJobNumber << " OK" << endl; | |||||
} |
InputProcessor* Input; // created, destroyed and | InputProcessor* Input; // created, destroyed and | ||||
OutputProcessor* Output; // connected together. | OutputProcessor* Output; // connected together. | ||||
unsigned int QuitJobNumber; // Quit job number 0 until QUIT. | |||||
void initializeOutput(); // These do what they say. | void initializeOutput(); // These do what they say. | ||||
void initializeJobPool(); | void initializeJobPool(); | ||||
void initializeWorkerPool(); | void initializeWorkerPool(); |
struct Command { // Parsed Command Objects | struct Command { // Parsed Command Objects | ||||
unsigned int Number; // Commands have a serial number | unsigned int Number; // Commands have a serial number | ||||
enum CommandType { // Commands have these types: | enum CommandType { // Commands have these types: | ||||
UNKNOWN; // We don't know this command. | |||||
QUIT; // It is time to stop the app. | |||||
WAKE; // Report the app is now awake. | |||||
INTF; // Report the interface version. | |||||
FILE; // Scan this file. | |||||
UNKNOWN, // We don't know this command. | |||||
QUIT, // It is time to stop the app. | |||||
WAKE, // Report the app is now awake. | |||||
INTF, // Report the interface version. | |||||
FILE // Scan this file. | |||||
} Type; // Here is where we keep it. | } Type; // Here is where we keep it. | ||||
string Data; // Other command data goes here. | string Data; // Other command data goes here. | ||||
}; | }; |
// SNF4CGP/ScannerPool.hpp | // SNF4CGP/ScannerPool.hpp | ||||
// Copyright (C) 2009 ARM Research Labs, LLC | // Copyright (C) 2009 ARM Research Labs, LLC | ||||
// See www.armresearch.com for more information. | // See www.armresearch.com for more information. | ||||
// | |||||
// This module maintains a pool of SNF scanners tied to an active rulebase. | |||||
// When a scanner is requested one is returned from the pool or if none are | |||||
// currently available in the pool an additional scanner is allocated. | |||||
#ifndef IncludedScannerPool | |||||
#define IncludedScannerPool | |||||
#include "../SNF4CGP/SNFMulti/SNFMulti.hpp" | |||||
class Scanner { // SNF Scanner instance for the pool | |||||
private: | |||||
snf_RulebaseHandler& Rulebase_; // Rulebase the scanner uses. | |||||
snf_EngineHandler* Engine_; // Scanner engine. | |||||
public: | |||||
Scanner(snf_RulebaseHandler& Rulebase); // When constructed allocates an engine. | |||||
~Scanner(); // When destructed destroys the engine. | |||||
snf_RulebaseHandler& Rulebase(); // Provides access to both the Rulebase | |||||
snf_EngineHandler& Engine(); // and the Engine. | |||||
}; | |||||
class ScannerPool { // Pool of SNF Scanners | |||||
private: | |||||
snf_RulebaseHandler* Rulebase; // Allocates an SNF rulebase. | |||||
unsigned int ScannerCount; // Allocates and counts scanners. | |||||
public: | |||||
ScannerPool(string Configuration); // Constructed with Rulebase config. | |||||
~ScannerPool(); // Cleans up when destroyed. | |||||
Scanner* grab(); // Provides a Scanner from the pool. | |||||
void drop(Scanner* S); // Returns a Scanner to the pool. | |||||
}; | |||||
// Since Scanners are used for as short a time as possible it is usefule to have them | |||||
// allocated from the pool and returned to the pool within the scope of the scanning | |||||
// function. An easy way to do that is to use the ScopeScanner which provides a scanner | |||||
// from the pool as long as it is in scope and then returns it to the pool when done | |||||
// even if something goes wrong and an exception is thrown. | |||||
class ScopeScanner { // Temporary handle for a Scanner. | |||||
private: | |||||
ScannerPool& ScannerPool_; // Knows the scanner pool. | |||||
Scanner* Scanner_; // Holds a pointer to a scanner. | |||||
public: | |||||
ScopeScanner(ScannerPool& P); // Grabs a scanner on construction. | |||||
~ScopeScanner(); // Drops the scanner on destruction. | |||||
snf_RulebaseHandler& Rulebase(); // Provides the same access as a | |||||
snf_EngineHandler& Engine(); // Scanner object. | |||||
} | |||||
#endif |
SNF4CGP.doShutdown(); | SNF4CGP.doShutdown(); | ||||
} | } | ||||
catch(exception& e) { // Display standard exceptions. | catch(exception& e) { // Display standard exceptions. | ||||
cout << "* SFN4CGP::go() Exception: " << e.what() << endl; | |||||
cout << "* SFN4CGP Exception: " << e.what() << endl; | |||||
} | } | ||||
catch(...) { // Display unusual exceptions. | catch(...) { // Display unusual exceptions. | ||||
cout << "* SNF4CGP::go() Unusual Excetption" << endl; | |||||
cout << "* SNF4CGP Unusual Excetption!" << endl; | |||||
} | } | ||||
cout << SNF4CGP_VERSION_INFO << endl; | cout << SNF4CGP_VERSION_INFO << endl; | ||||
cout << ConfigurationPath << endl; | cout << ConfigurationPath << endl; |