diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h b/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h index 332df24374cb66265e61d6ac7f47babed9cdbe37..d89bcebbcda92ffc984bb148adf76455b005904a 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h @@ -68,8 +68,8 @@ public: SUSPENDED, RELEASE, RELEASED, - FINISH, // child to parent - FINISHED, + QUIT, + QUITED, LAST_STATE } CTstateNr; diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/ParentControl.h b/MAC/APL/APLCommon/include/APL/APLCommon/ParentControl.h index 082ec191f3b5a66b3b32d18824cc37300951437f..d1b0211383770bb81ee376755363508d0bce97a0 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/ParentControl.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/ParentControl.h @@ -72,10 +72,20 @@ public: GCFITCPort* registerTask (GCFTask* mainTask); // Let ParentControlTask watch for start- and stop-time of observation. - // When the given time is reached the ParentControlTask generates a RESUME / QUIT event. - bool activateObservationTimers(const string& cntlrName, - ptime startTime, - ptime stopTime); + // When the given time is reached the ParentControlTask generates a + // RESUME / QUIT event. + bool activateObservationTimers(const string& cntlrName, + ptime startTime, + ptime stopTime); + + // The main task can inform the ParentControl-task what state it is in now. + // When the commands to change state come from the parent executable this is + // not neccesary because the ParentControl-task knows in what state the main-task + // should be. But when the main-task decides on his own that he needs to be in + // another state than he has to inform the ParentControl-task about it, otherwise + // these two tasks become out of sync. + bool nowInState(const string& cntlrName, + CTState::CTstateNr newState); private: // Copying and default construction is not allowed ParentControl(); diff --git a/MAC/APL/APLCommon/src/CTState.cc b/MAC/APL/APLCommon/src/CTState.cc index 7b0ebb520a691a6626cd6bbb6323d50e5d45a240..2a64ce6ed96af6fba7d5411f821ae50acee5f28f 100644 --- a/MAC/APL/APLCommon/src/CTState.cc +++ b/MAC/APL/APLCommon/src/CTState.cc @@ -56,8 +56,8 @@ stateSignal_t stateSignalTable[] = { { CTState::SUSPENDED, CONTROL_SUSPENDED, "Suspended" }, { CTState::RELEASE, CONTROL_RELEASE, "Releasing" }, { CTState::RELEASED, CONTROL_RELEASED, "Released" }, - { CTState::FINISH, CONTROL_FINISH, "Finishing" }, - { CTState::FINISHED, CONTROL_FINISHED, "Finished" } + { CTState::QUIT, CONTROL_QUIT, "Quiting" }, + { CTState::QUITED, CONTROL_QUITED, "Quited" } }; // @@ -153,7 +153,7 @@ CTState::CTstateNr CTState::stateAck(CTstateNr aStateNr) const case RESUME: case SUSPEND: case RELEASE: - case FINISH: + case QUIT: return (stateNr(value(aStateNr)+1)); default: return (aStateNr); diff --git a/MAC/APL/APLCommon/src/ChildControl.cc b/MAC/APL/APLCommon/src/ChildControl.cc index 2cf26291b1d8d77183d5a657ca3a3d4da13a1955..fe9556b11b34fbdac6ab10f63ea98037c509f9a0 100644 --- a/MAC/APL/APLCommon/src/ChildControl.cc +++ b/MAC/APL/APLCommon/src/ChildControl.cc @@ -716,7 +716,7 @@ void ChildControl::_processActionList() } break; - case CTState::FINISHED: + case CTState::QUITED: { CONTROLQuitEvent request; request.cntlrName = controller->cntlrName; @@ -868,11 +868,12 @@ void ChildControl::_setEstablishedState(const string& aName, itsCompletionPort->sendBack(msg); } break; - case CTState::FINISH: { - CONTROLFinishEvent msg; + case CTState::QUITED: { + CONTROLQuitedEvent msg; msg.cntlrName = controller->cntlrName; msg.treeID = controller->obsID; msg.result = result; + // TODO: errormsg itsCompletionPort->sendBack(msg); } break; @@ -902,7 +903,7 @@ void ChildControl::_doGarbageCollection() if (!iter->port) { LOG_DEBUG_STR ("Controller " << iter->cntlrName << " is still unreachable, informing main task"); - _setEstablishedState(iter->cntlrName, CTState::FINISH, time(0), + _setEstablishedState(iter->cntlrName, CTState::QUITED, time(0), CT_RESULT_LOST_CONNECTION); iter->port = (GCFPortInterface*) -1; // start timer for second stage. @@ -1032,7 +1033,7 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, } // found controller, close port - if (controller->currentState >= CTState::FINISH) {// expected disconnect? + if (controller->currentState >= CTState::QUIT) {// expected disconnect? LOG_DEBUG_STR("Removing " << controller->cntlrName << " from the controllerList"); itsCntlrList->erase(controller); // just remove @@ -1040,7 +1041,7 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, else { // unexpected disconnect give child some time to reconnect(?) LOG_WARN_STR ("Lost connection with controller " << controller->cntlrName << - " while not in FINISHED state, waiting 5 minutes for reconnect"); + " while not in QUITING state, waiting 5 minutes for reconnect"); _setEstablishedState(controller->cntlrName, CTState::ANYSTATE, time(0), CT_RESULT_LOST_CONNECTION); @@ -1193,17 +1194,17 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, // do nothing, is not a state change. break; - case CONTROL_FINISH: { - CONTROLFinishEvent msg(event); - _setEstablishedState(msg.cntlrName, CTState::FINISH, time(0), + case CONTROL_QUITED: { + CONTROLQuitedEvent msg(event); + _setEstablishedState(msg.cntlrName, CTState::QUITED, time(0), msg.result); // inform child its shutdown is registered - CONTROLFinishedEvent reply; - reply.cntlrName = msg.cntlrName; - port.send(reply); - _setEstablishedState(msg.cntlrName, CTState::FINISHED, time(0), - msg.result); +// CONTROLFinishedEvent reply; +// reply.cntlrName = msg.cntlrName; +// port.send(reply); +// _setEstablishedState(msg.cntlrName, CTState::FINISHED, time(0), +// msg.result); } break; diff --git a/MAC/APL/APLCommon/src/ControllerDefines.cc b/MAC/APL/APLCommon/src/ControllerDefines.cc index 592401eb00db810ba668dc4f4b8876b1becadd53..3d0a98b8d929555c161d3806c2c163d5f662ffe4 100644 --- a/MAC/APL/APLCommon/src/ControllerDefines.cc +++ b/MAC/APL/APLCommon/src/ControllerDefines.cc @@ -30,7 +30,6 @@ #include <APS/ParameterSet.h> // indexValue #include <APL/APLCommon/ControllerDefines.h> #include <APL/APLCommon/StationInfo.h> -//#include <APL/APLCommon/Controller_Protocol.ph> #include "Controller_Protocol.ph" #include <boost/config.hpp> @@ -306,9 +305,9 @@ bool sendControlResult(GCF::TM::GCFPortInterface& port, return (port.send(answer) > 0); } break; - case CONTROL_FINISH: - case CONTROL_FINISHED: { - CONTROLFinishedEvent answer; + case CONTROL_QUIT: + case CONTROL_QUITED: { + CONTROLQuitedEvent answer; answer.cntlrName = cntlrName; answer.result = result; return (port.send(answer) > 0); diff --git a/MAC/APL/APLCommon/src/Controller_Protocol.prot b/MAC/APL/APLCommon/src/Controller_Protocol.prot index d2db7dcdb47210d4aca97e8b6ea42cfa4d0b081e..03405dfc15c4791e2b744136504c9b534c68b34b 100644 --- a/MAC/APL/APLCommon/src/Controller_Protocol.prot +++ b/MAC/APL/APLCommon/src/Controller_Protocol.prot @@ -54,8 +54,7 @@ prelude = << PRELUDE_END // RELEASE (string cntlrName) // RELEASED (string cntlrName, uint16 result) // QUIT (string cntlrName) -// FINISH (string cntlrName, uint32 treeID, uint16 result, string errorMsg) -// FINISHED (string cntlrName, uint16 result) +// QUITED (string cntlrName, uint32 treeID, uint16 result, string errorMsg) // // COMMON (string cntlrName) // not a real signal, the common part of all signals // @@ -348,10 +347,10 @@ event = { }; // -// FINISH - sent by a child to tell its parent it is dying. +// QUITED - sent by a child to tell its parent it is dying. // event = { - signal = FINISH; + signal = QUITED; dir = IN; // from child to parent param = { name = "cntlrName"; @@ -371,22 +370,6 @@ event = { }; }; -// -// FINISHED - result of the FINISH request -// -event = { - signal = FINISHED; - dir = OUT; // from parent to child - param = { - name = "cntlrName"; - type = "string"; - }; - param = { - name = "result"; - type = "uint16"; - }; -}; - // // COMMON - not a real signal, its the common part of all CONTROL events. // Makes it possible to use a CONTROLCommonEvent to get the name of the controller. diff --git a/MAC/APL/APLCommon/src/ParentControl.cc b/MAC/APL/APLCommon/src/ParentControl.cc index d403a4a837a246031227468accbacd1b315c4a37..b93163b5c71f374b50fd0e2746b73c24ebd13087 100644 --- a/MAC/APL/APLCommon/src/ParentControl.cc +++ b/MAC/APL/APLCommon/src/ParentControl.cc @@ -63,13 +63,14 @@ static stateFlow stateFlowTable[] = { { CONTROL_SUSPENDED, CTState::SUSPEND, CTState::SUSPENDED }, { CONTROL_RELEASE, CTState::ANYSTATE, CTState::RELEASED }, { CONTROL_RELEASED, CTState::RELEASE, CTState::RELEASED }, - { CONTROL_FINISH, CTState::RELEASED, CTState::FINISHED }, - { CONTROL_FINISHED, CTState::RELEASED, CTState::FINISHED }, -// { CONTROL_FINISH, CTState::ANYSTATE, CTState::FINISHED }, - { CONTROL_FINISHED, CTState::FINISH, CTState::FINISHED }, + { CONTROL_QUIT, CTState::ANYSTATE, CTState::QUITED }, + { CONTROL_QUITED, CTState::QUIT, CTState::QUITED }, +// { CONTROL_FINISH, CTState::RELEASED, CTState::FINISHED }, +// { CONTROL_FINISHED, CTState::RELEASED, CTState::FINISHED }, +// { CONTROL_FINISHED, CTState::FINISH, CTState::FINISHED }, { CONTROL_RESYNCED, CTState::ANYSTATE, CTState::ANYSTATE }, { CONTROL_SCHEDULE, CTState::ANYSTATE, CTState::ANYSTATE }, - { CONTROL_QUIT, CTState::ANYSTATE, CTState::FINISH }, +// { CONTROL_QUIT, CTState::ANYSTATE, CTState::FINISH }, { 0x00, CTState::NOSTATE, CTState::NOSTATE } }; @@ -194,7 +195,7 @@ bool ParentControl::activateObservationTimers(const string& cntlrName, // <0 <0 obs is over! if (stopDiff.seconds() < 0) { LOG_ERROR("Stoptime is already past! Shutting down controller."); - parent->requestedState = CTState::FINISH; + parent->requestedState = CTState::QUITED; parent->requestTime = time(0); _doRequestedAction(parent); return (false); @@ -227,6 +228,34 @@ bool ParentControl::activateObservationTimers(const string& cntlrName, return (true); } +// +// nowInState(name, newstate) +// +// The main task can inform the ParentControl-task what state it is in now. +// When the commands to change state come from the parent executable this is +// not neccesary because the ParentControl-task knows in what state the main-task +// should be. But when the main-task decides on his own that he needs to be in +// another state than he has to inform the ParentControl-task about it, otherwise +// these two tasks become out of sync. +// +bool ParentControl::nowInState(const string& cntlrName, + CTState::CTstateNr newState) +{ + CTState cts; + LOG_DEBUG_STR("nowInState(" << cntlrName <<","<< cts.name(newState) << ")"); + + PIiter parent = findParent(cntlrName); + if (!isParent(parent)) { + LOG_ERROR_STR("Unknown controllername " << cntlrName << + ", can not register new state: " << cts.name(newState)); + return (false); + } + + parent->currentState = newState; + parent->requestedState = requestedState(cts.signal(newState)); + return (true); +} + // -------------------- PRIVATE FUNCTIONS -------------------- // @@ -346,9 +375,6 @@ void ParentControl::_doRequestedAction(PIiter parent) parent->nrRetries = -1; itsTimerPort.cancelTimer(parent->timerID); parent->timerID = 0; - if (parent->requestedState != CTState::FINISHED) { - return; - } } // switch (parent->requestedState) { @@ -422,20 +448,11 @@ void ParentControl::_doRequestedAction(PIiter parent) itsMainTaskPort->sendBack(request); } break; - case CTState::FINISH: { - CONTROLQuitEvent request; - request.cntlrName = parent->name; - itsMainTaskPort->sendBack(request); - } - break; - case CTState::FINISHED: { + case CTState::QUITED: { // pass to maintask - CONTROLFinishedEvent request; + CONTROLQuitEvent request; request.cntlrName = parent->name; itsMainTaskPort->sendBack(request); - // close port and cleanup admin - parent->port->close(); - itsParentList.erase(parent); } break; default: @@ -761,7 +778,7 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, } break; - // -------------------- signals from Parent process -------------------- + // -------------------- commands from parent executable -------------------- case CONTROL_RESYNC: case CONTROL_SCHEDULE: case CONTROL_CLAIM: @@ -770,7 +787,6 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, case CONTROL_SUSPEND: case CONTROL_RELEASE: case CONTROL_QUIT: - case CONTROL_FINISHED: // NB: is an answer! { // do we know this parent? PIiter parent = findParent(&port); @@ -911,15 +927,18 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, } break; - case CONTROL_FINISH: + case CONTROL_QUITED: { - CONTROLFinishEvent msg(event); + CONTROLQuitedEvent msg(event); // do we know this parent? PIiter parent = findParent(msg.cntlrName); if (isParent(parent)) { _confirmState(event.signal, msg.cntlrName, msg.result); parent->port->send(msg); } + // close port and cleanup admin + parent->port->close(); + itsParentList.erase(parent); } break;