diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h b/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h index d89bcebbcda92ffc984bb148adf76455b005904a..27843f44485931349d6e6add7aefee916157f059 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/CTState.h @@ -74,12 +74,13 @@ public: } CTstateNr; // conversion routines - string name (uint16 aStateNr) const; - uint16 value (const string& aStateName) const; - uint16 value (CTstateNr aStateNr) const; - CTstateNr stateNr (uint16 someNr) const; - uint16 signal (CTstateNr aStateNr) const; - CTstateNr stateAck(CTstateNr aStateNr) const; + string name (uint16 aStateNr) const; + uint16 value (const string& aStateName) const; + uint16 value (CTstateNr aStateNr) const; + CTstateNr stateNr (uint16 someNr) const; + uint16 signal (CTstateNr aStateNr) const; + CTstateNr stateAck (CTstateNr aStateNr) const; + CTstateNr signal2stateNr (uint16 someSignal) const; private: // Copying is not allowed diff --git a/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h b/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h index 73a08392f61014d9e23345926d9e04d51ae196fb..29cba72f39397f0f190d1063bdfb9415b9d5c3e5 100644 --- a/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h +++ b/MAC/APL/APLCommon/include/APL/APLCommon/ControllerDefines.h @@ -41,6 +41,9 @@ enum CT_RESULT_BEAMALLOC_FAILED, CT_RESULT_BEAMFREE_FAILED, CT_RESULT_ALREADY_REGISTERED, + CT_RESULT_INVALID_ARGUMENT, + CT_RESULT_CONFLICTING_ARGS, + CT_RESULT_OUT_OF_SYNC, CT_RESULT_UNSPECIFIED }; diff --git a/MAC/APL/APLCommon/src/CTState.cc b/MAC/APL/APLCommon/src/CTState.cc index 2a64ce6ed96af6fba7d5411f821ae50acee5f28f..eaacec9b194add826e055d1341852abe3c35f8cb 100644 --- a/MAC/APL/APLCommon/src/CTState.cc +++ b/MAC/APL/APLCommon/src/CTState.cc @@ -134,6 +134,22 @@ uint16 CTState::signal(CTstateNr aStateNr) const return (stateSignalTable[aStateNr].signal); } +// +// signal2stateNr(signal) +// +CTState::CTstateNr CTState::signal2stateNr (uint16 someSignal) const +{ + uint16 i = NOSTATE; + while (i < LAST_STATE) { + if (stateSignalTable[i].signal == someSignal) { + return (stateSignalTable[i].state); + } + i++; + } + + ASSERTSTR(false, someSignal << " is not a supported signal"); +} + // // stateAck(state) // diff --git a/MAC/APL/APLCommon/src/ChildControl.cc b/MAC/APL/APLCommon/src/ChildControl.cc index d3eec27f01cc12ee27263318b9471d759fef4fe9..3f3c646b94b747db6d852e764b69b6dfd1098501 100644 --- a/MAC/APL/APLCommon/src/ChildControl.cc +++ b/MAC/APL/APLCommon/src/ChildControl.cc @@ -71,7 +71,7 @@ ChildControl::ChildControl() : itsActionList (), itsActionTimer (0), itsGarbageTimer (0), - itsGarbageInterval (30), // TODO: set to 300 for real life + itsGarbageInterval (10), // TODO: set to 300 for real life itsCompletionTimer (0), itsCompletionPort (0) { @@ -1030,17 +1030,21 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, break; case F_DISCONNECTED: { - port.close(); // always close port - + // 170507: in one way or another the controllerport is not recognized here + // anymore. So the code of cleaning up the admin is moved to the + // reception of the QUITED event. +#if 1 CIiter controller = itsCntlrList->begin(); CIiter end = itsCntlrList->end(); while (controller != end) { // search corresponding controller + LOG_DEBUG_STR("Check:" << controller->cntlrName); if (controller->port != &port) { controller++; continue; } + // found controller, close port if (controller->currentState >= CTState::QUIT) {// expected disconnect? LOG_DEBUG_STR("Removing " << controller->cntlrName << @@ -1056,7 +1060,8 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, time(0), CT_RESULT_LOST_CONNECTION); controller->port = 0; -#if 0 // Try to restart the controller over 5 seconds +#if 0 + // Try to restart the controller over 5 seconds // Add it to the action list. controller->retryTime = time(0) + 300 ; itsListener->cancelTimer(itsActionTimer); @@ -1070,8 +1075,11 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& event, } itsGarbageTimer = itsTimerPort.setTimer(1.0 * itsGarbageInterval); } - break;// out of while loop - } + // controlelr was found and handled, break out of the while loop. + break; + } // while +#endif + port.close(); // always close port } break; @@ -1208,12 +1216,15 @@ GCFEvent::TResult ChildControl::operational(GCFEvent& 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); +#if 0 + CIiter controller = findController(msg.cntlrName); + ASSERTSTR(isController(controller), "Controller " << msg.cntlrName << + " not in our administration anymore!"); + // found controller, close port + LOG_DEBUG_STR("Removing " << controller->cntlrName << + " from the controllerlist"); + itsCntlrList->erase(controller); // just remove +#endif } break; diff --git a/MAC/APL/APLCommon/src/Controller_Protocol.prot b/MAC/APL/APLCommon/src/Controller_Protocol.prot index 03405dfc15c4791e2b744136504c9b534c68b34b..3220f18cce18212bff93d11e20d4a3815d700cc3 100644 --- a/MAC/APL/APLCommon/src/Controller_Protocol.prot +++ b/MAC/APL/APLCommon/src/Controller_Protocol.prot @@ -98,7 +98,7 @@ event = { // event = { signal = CONNECT; - dir = IN; // from child to parent + dir = OUT; // from child to parent param = { name = "cntlrName"; type = "string"; @@ -110,7 +110,7 @@ event = { // event = { signal = CONNECTED; - dir = OUT; // from parent to child + dir = IN; // from parent to child param = { name = "cntlrName"; type = "string"; @@ -126,7 +126,7 @@ event = { // event = { signal = RESYNC; - dir = IN; // from child to parent + dir = OUT; // from child to parent param = { name = "cntlrName"; type = "string"; @@ -146,7 +146,7 @@ event = { // event = { signal = RESYNCED; - dir = OUT; // from parent to child + dir = IN; // from parent to child param = { name = "cntlrName"; type = "string"; @@ -376,7 +376,7 @@ event = { // event = { signal = COMMON; - dir = OUT; // from parent to child + dir = IN; // from parent to child param = { name = "cntlrName"; type = "string"; diff --git a/MAC/APL/APLCommon/src/ParentControl.cc b/MAC/APL/APLCommon/src/ParentControl.cc index b93163b5c71f374b50fd0e2746b73c24ebd13087..0efa7c54fbb23b191dfcff225cfbc6cd252f155d 100644 --- a/MAC/APL/APLCommon/src/ParentControl.cc +++ b/MAC/APL/APLCommon/src/ParentControl.cc @@ -50,6 +50,8 @@ typedef struct stateFlow_t { static stateFlow stateFlowTable[] = { // received signal expected in state requested state // ------------------------------------------------------------------ + { CONTROL_STARTED, CTState::ANYSTATE, CTState::CREATED }, + { CONTROL_CONNECTED, CTState::NOSTATE, CTState::CONNECTED }, { CONTROL_CONNECTED, CTState::CONNECT, CTState::CONNECTED }, { CONTROL_CLAIM, CTState::CONNECTED, CTState::CLAIMED }, { CONTROL_CLAIMED, CTState::CLAIM, CTState::CLAIMED }, @@ -61,16 +63,15 @@ static stateFlow stateFlowTable[] = { { CONTROL_SUSPEND, CTState::RESUMED, CTState::SUSPENDED }, { CONTROL_SUSPEND, CTState::PREPARED, CTState::SUSPENDED }, { CONTROL_SUSPENDED, CTState::SUSPEND, CTState::SUSPENDED }, - { CONTROL_RELEASE, CTState::ANYSTATE, CTState::RELEASED }, + { CONTROL_RELEASE, CTState::CLAIMED, CTState::RELEASED }, + { CONTROL_RELEASE, CTState::PREPARED, CTState::RELEASED }, + { CONTROL_RELEASE, CTState::SUSPENDED, CTState::RELEASED }, { CONTROL_RELEASED, CTState::RELEASE, CTState::RELEASED }, - { CONTROL_QUIT, CTState::ANYSTATE, CTState::QUITED }, + { CONTROL_QUIT, CTState::CONNECTED, CTState::QUITED }, + { CONTROL_QUIT, CTState::RELEASED, 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 }, { 0x00, CTState::NOSTATE, CTState::NOSTATE } }; @@ -482,16 +483,22 @@ bool ParentControl::_confirmState(uint16 signal, // cts.name(parent->requestedState)); // } - if (result != CT_RESULT_NO_ERROR) { - parent->failed = true; + if (result != CT_RESULT_NO_ERROR) { // error reaching a state? + parent->failed = true; // report problem LOG_ERROR_STR(cntlrName << " DID NOT reach the " << cts.name(requestedState(signal)) << " state, error=" << result); - return (false); + // if we are NOT trying to quit, don't continue with the state-sequence. + // when we ARE trying to reach the QUIT state continue otherwise we will + // be running forever. + if (parent->requestedState != CTState::QUITED) { + return (false); + } } - - parent->currentState = requestedState(signal); - LOG_DEBUG_STR(cntlrName << " reached " << cts.name(parent->currentState) << - " state succesfully"); + else { // no error while reaching the new state + LOG_DEBUG_STR(cntlrName << " reached " << cts.name(cts.signal2stateNr(signal)) << + " state succesfully"); + } + parent->currentState = requestedState(signal); // store new state if (parent->currentState != parent->requestedState) { // chain of states? _doRequestedAction(parent); // start next step @@ -756,7 +763,9 @@ GCFEvent::TResult ParentControl::operational(GCFEvent& event, // should be a parentport PIiter parent = findParent(&port); if (!isParent(parent)) { - LOG_WARN_STR ("Received CONNECTED event from unknown parent, ignoring"); + CONTROLConnectedEvent inMsg(event); + LOG_WARN_STR ("Received CONNECTED event from unknown parent (" << + inMsg.cntlrName << "), ignoring"); break; } diff --git a/MAC/APL/APLCommon/test/tOutOfBand.cc b/MAC/APL/APLCommon/test/tOutOfBand.cc index aa0c75c3ee5b5cd24541797e14b89dcf8b9e690b..56d4af8591797f9ad1be61784acfabe5dd746b5b 100644 --- a/MAC/APL/APLCommon/test/tOutOfBand.cc +++ b/MAC/APL/APLCommon/test/tOutOfBand.cc @@ -51,16 +51,16 @@ static stateFlow stateFlowTable[] = { { CONTROL_SUSPEND, CTState::RESUMED, CTState::SUSPENDED }, { CONTROL_SUSPEND, CTState::PREPARED, CTState::SUSPENDED }, { CONTROL_SUSPENDED, CTState::SUSPEND, CTState::SUSPENDED }, - { CONTROL_RELEASE, CTState::ANYSTATE, CTState::RELEASED }, + { CONTROL_RELEASE, CTState::CLAIMED, CTState::RELEASED }, + { CONTROL_RELEASE, CTState::PREPARED, CTState::RELEASED }, + { CONTROL_RELEASE, CTState::SUSPENDED, CTState::RELEASED }, { CONTROL_RELEASED, CTState::RELEASE, CTState::RELEASED }, - { CONTROL_QUIT, CTState::ANYSTATE, CTState::QUITED }, + { CONTROL_QUIT, CTState::CONNECTED, CTState::QUITED }, + { CONTROL_QUIT, CTState::RELEASED, CTState::QUITED }, +// { 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 }, { 0x00, CTState::NOSTATE, CTState::NOSTATE } }; @@ -98,8 +98,8 @@ CTState::CTstateNr getNextState(CTState::CTstateNr theCurrentState, CTState::CTstateNr currentState = theCurrentState; i = 0; for (;;) { - LOG_DEBUG_STR("Check " << cts.name(stateFlowTable[i].currentState) << - " to " << cts.name(stateFlowTable[i].requestedState)); +// LOG_DEBUG_STR("Check " << cts.name(stateFlowTable[i].currentState) << +// " to " << cts.name(stateFlowTable[i].requestedState)); // find matching requested state if (stateFlowTable[i].requestedState == requestedState) { // does (moved) currentState match state of table? @@ -167,7 +167,15 @@ int main (int argc, char* argv[]) { CTState::PREPARED))); LOG_DEBUG_STR("resumed -> released : " << cts.name(getNextState(CTState::RESUMED, CTState::RELEASED))); - LOG_DEBUG_STR("resumed -> finished : " << cts.name(getNextState(CTState::RESUMED, + LOG_DEBUG_STR("connected-> quited : " << cts.name(getNextState(CTState::CONNECTED, + CTState::QUITED))); + LOG_DEBUG_STR("claimed -> quited : " << cts.name(getNextState(CTState::CLAIMED, + CTState::QUITED))); + LOG_DEBUG_STR("prepared -> quited : " << cts.name(getNextState(CTState::PREPARED, + CTState::QUITED))); + LOG_DEBUG_STR("resumed -> quited : " << cts.name(getNextState(CTState::RESUMED, + CTState::QUITED))); + LOG_DEBUG_STR("suspended-> quited : " << cts.name(getNextState(CTState::SUSPENDED, CTState::QUITED)));