diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc index 0eb9a1f57210499f4d1e46e5da8bf30d71cd9f0e..85bc0b7c16dc981bb9e30ffc7fa20901eb0f0784 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc @@ -34,6 +34,7 @@ #include <APL/APLCommon/StationInfo.h> #include <APL/APLCommon/APLCommonExceptions.h> #include <APL/APLCommon/Controller_Protocol.ph> +#include <signal.h> #include "MACSchedulerDefines.h" #include "MACScheduler.h" @@ -49,6 +50,9 @@ namespace LOFAR { using namespace APLCommon; using namespace ACC::APS; namespace MainCU { + +// static (this) pointer used for signal handling +static MACScheduler* pMacScheduler = 0; // // MACScheduler() @@ -114,6 +118,13 @@ MACScheduler::~MACScheduler() } } +void MACScheduler::sigintHandler(/*@unused@*/int signum) +{ + LOG_INFO(LOFAR::formatString("SIGINT signal detected (%d)",signum)); + if(0 != pMacScheduler) + pMacScheduler->finish(); +} + // // handlePropertySetAnswer(answer) @@ -310,6 +321,12 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& break; case F_ENTRY: { + // install my own signal handler. GCFTask also installs a handler so we have to install our + // handler later than the GCFTask handler. + pMacScheduler = this; + /* install ctrl-c signal handler */ + (void)signal(SIGINT,MACScheduler::sigintHandler); + // update PVSS itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("active")); itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); @@ -403,6 +420,53 @@ GCFEvent::TResult MACScheduler::active_state(GCFEvent& event, GCFPortInterface& return (status); } +// +// finishing_state(event, port) +// +// Write controller state to PVSS, wait for 1 second (using a timer) to let GCF handle the property change +// and close the controller +// +GCFEvent::TResult MACScheduler::finishing_state(GCFEvent& event, GCFPortInterface& port) +{ + LOG_DEBUG_STR ("finishing_state:" << evtstr(event) << "@" << port.getName()); + + GCFEvent::TResult status = GCFEvent::HANDLED; + + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: { + // update PVSS + itsPropertySet->setValue(string(PVSSNAME_FSM_STATE),GCFPVString("finished")); + itsPropertySet->setValue(string(PVSSNAME_FSM_ERROR),GCFPVString("")); + + itsTimerPort->setTimer(1L); + break; + } + + case F_TIMER: + GCFTask::stop(); + break; + + default: + LOG_DEBUG("finishing_state, default"); + status = GCFEvent::NOT_HANDLED; + break; + } + return (status); +} + +// +// finish +// +// Make the transition to the finishing state +// +void MACScheduler::finish() +{ + TRAN(MACScheduler::finishing_state); +} + // // _doOTDBcheck // @@ -564,7 +628,7 @@ void MACScheduler::_removeActiveObservation(const string& name) // // _connectedHandler(port) // -void MACScheduler::_connectedHandler(GCFPortInterface& port) +void MACScheduler::_connectedHandler(GCFPortInterface& /*port*/) { } diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h index a8d0a3cb41b960ef605fe14ea3562a41cb528fcd..aada16ab35ac5d31148e72c07a9363c38d4755e4 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h +++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.h @@ -94,6 +94,15 @@ public: GCFEvent::TResult active_state (GCFEvent& e, GCFPortInterface& p); + // Cleaning up. Write state to PVSS property + GCFEvent::TResult finishing_state(GCFEvent& e, + GCFPortInterface& p); + + // Make the transition to the finishing state + void finish(); + + static void sigintHandler(int signum); + private: // avoid copying MACScheduler(const MACScheduler&); diff --git a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc index 1f1b70b6d7a82ca14d3de4bf2082aec684961423..f24973a47769b0daa25400ea71bf881895c448ac 100644 --- a/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc +++ b/MAC/APL/MainCU/src/MACScheduler/MACSchedulerMain.cc @@ -37,7 +37,7 @@ int main(int argc, char* argv[]) MACScheduler ms; ms.start(); // make initial transition - + GCFTask::run(); return 0;