/********************************************************************\ Tentative FACT central control - Provides central run number dispatcher. Note: Declaring class static ensures destructor is called when exit() is invoked Oliver Grimm, March 2010 \********************************************************************/ #define SERVER_NAME "Chief" #include "Evidence.h" using namespace std; // ========= Class Declarations ========= class ChiefClass; class RunNumberRpc: public DimRpc { ChiefClass *Chief; void rpcHandler(); public: RunNumberRpc(class ChiefClass *Chief): DimRpc("NextRunNumber", "C", "I"), Chief(Chief) {}; }; class ChiefClass: public EvidenceServer { RunNumberRpc *RN_Rpc; public: ChiefClass(); ~ChiefClass(); DimService *LastRunNumber; string RunNumFilename; int RunNumber; }; // ========= Class Definitions ========= // Constructor ChiefClass::ChiefClass(): EvidenceServer(SERVER_NAME) { RunNumFilename = GetConfig("RunNumFile"); RunNumber = -2; LastRunNumber = new DimService(SERVER_NAME"/LastRunNumber", RunNumber); // RPC for dispatching run numbers RN_Rpc = new RunNumberRpc(this); } // Destructor ChiefClass::~ChiefClass() { delete RN_Rpc; delete LastRunNumber; } // Remote procedure call: Request for next run number void RunNumberRpc::rpcHandler() { bool OK = true; int RunNumber; // Open file containing last run number FILE *RunNumFile = fopen(Chief->RunNumFilename.c_str(), "r+"); if(RunNumFile == NULL) { Chief->Message(Chief->ERROR, "Could not open file '%s' that contains the last run number (%s)", Chief->RunNumFilename.c_str(), strerror(errno)); OK = false; } else { // Read last run number if(fscanf(RunNumFile,"%d", &RunNumber) != 1 ) { Chief->Message(Chief->ERROR, "Could not read run number from file '%s'", Chief->RunNumFilename.c_str()); OK = false; } else RunNumber++; // Update run number in file rewind(RunNumFile); if(OK && fprintf(RunNumFile,"%.8u ",RunNumber) < 0) { Chief->Message(Chief->ERROR, "Could not write to run number file '%s'", Chief->RunNumFilename.c_str()); OK = false; } // Close run number file if(fclose(RunNumFile) != 0) { Chief->Message(Chief->ERROR, "Could not close run number file '%s'", Chief->RunNumFilename.c_str()); OK = false; } } // Dispatch real run number only if all successful if (!OK) RunNumber = -1; Chief->RunNumber = RunNumber; setData(RunNumber); Chief->LastRunNumber->updateService(); Chief->Message(Chief->INFO, "Dispatched run number %d", RunNumber); } // // Main program // int main() { static ChiefClass TheBoss; // Sleep until exit requested while (!TheBoss.ExitRequest) pause(); }