Salome HOME
InitLoop and DoLoop parameters names
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNodeThreads.cxx
index 50b386191e9f6a4d7d82ecfba53fa8da3b27ee6c..42661e2dfda57ac0ed65c790919ea761d19edffc 100644 (file)
@@ -157,6 +157,7 @@ void GraphExecutor::InNode::RunningAction() {
   cdebug << pthread_self() << "/" << ThreadNo()
          << "RunningAction pthread_cond_broadcast _RunningWait "
          << Name() << endl ;
+// That activate the pthread_cond_wait for RunninWait
   if ( pthread_cond_broadcast( &_RunningWait ) ) {
     perror("Running pthread_cond_broadcast ") ;
   }
@@ -449,17 +450,20 @@ void GraphExecutor::InNode::ThreadStartedAction() {
     exit( 0 ) ;
   }
   if ( !_ThreadStartedSync ) {
-    cdebug << "pthread_cond " << Name() << " ThreadStarted pthread_cond_wait"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStarted pthread_cond_wait"
            << endl ;
     _ThreadStartedSync = true ;
     if ( pthread_cond_wait( &_ThreadStartedWait , &_MutexWait ) ) {
       perror("ThreadStarted pthread_cond_wait ") ;
     }
-    cdebug << "pthread_cond " << Name() << " ThreadStarted pthread_cond_waited"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStarted pthread_cond_waited"
            << endl ;
   }
   else {
-    cdebug << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_wait"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_wait"
            << endl ;
 //Debug :
     _ThreadStartedSync = false ;  
@@ -467,7 +471,8 @@ void GraphExecutor::InNode::ThreadStartedAction() {
       perror("ThreadStart pthread_cond_signal ") ;
     }
 //Debug
-    cdebug << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_signaled"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_signaled"
            << endl ;
   }
   if ( pthread_mutex_unlock( &_MutexWait ) ) {
@@ -482,17 +487,20 @@ void GraphExecutor::InNode::ThreadStartAction() {
     exit( 0 ) ;
   }
   if ( _ThreadStartedSync ) {
-    cdebug << "pthread_cond " << Name() << " ThreadStart pthread_cond_signal"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStart pthread_cond_signal"
            << endl ;
     _ThreadStartedSync = false ;  
     if ( pthread_cond_signal( &_ThreadStartedWait ) ) {
       perror("ThreadStart pthread_cond_broadcast ") ;
     }
-    cdebug << "pthread_cond " << Name() << " ThreadStart pthread_cond_signaled"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " ThreadStart pthread_cond_signaled"
            << endl ;
   }
   else {
-    cdebug << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_signal"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_signal"
            << endl ;
     _ThreadStartedSync = true ;
 //Debug :
@@ -500,7 +508,8 @@ void GraphExecutor::InNode::ThreadStartAction() {
       perror("ThreadStarted pthread_cond_wait ") ;
     }
 //Debug
-    cdebug << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_waited"
+    cdebug << pthread_self() << "/" << ThreadNo()
+           << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_waited"
            << endl ;
   }
   if ( pthread_mutex_unlock( &_MutexWait ) ) {
@@ -589,7 +598,7 @@ int GraphExecutor::InNode::executeAction() {
 }
 
 void GraphExecutor::InNode::coutbegin() {
-  cdebug << ThreadNo() << " " << pthread_self() << " run_function begin"
+  cdebug << pthread_self() << "/" << ThreadNo() << " run_function begin"
          << " " << Name() << " " << Automaton()->StateName( State() ) << endl ;
 }
 void GraphExecutor::InNode::coutexit() {
@@ -626,12 +635,12 @@ void * run_function(void *p) {
 int GraphExecutor::InNode::ExecuteAction() {
   int sts ;
 
-//  const char * nextactionname = Automaton()->ActionName( _NextAction ) ;
-//  const char * statename = Automaton()->StateName( State() ) ;
-//  const char * nextstatename = Automaton()->StateName( _NextState ) ;
-//  cdebug << pthread_self() << "/" << ThreadNo() << " --> ExecuteAction "
-//         << nextactionname << " "  << statename << " NextState "
-//         << nextstatename << endl ;
+  const char * nextactionname = Automaton()->ActionName( _NextAction ) ;
+  const char * statename = Automaton()->StateName( State() ) ;
+  const char * nextstatename = Automaton()->StateName( _NextState ) ;
+  cdebug_in << pthread_self() << "/" << ThreadNo() << " --> ExecuteAction "
+            << nextactionname << " "  << statename << " NextState "
+            << nextstatename << endl ;
 
   State( _NextState ) ;
   switch ( _NextAction ) {
@@ -762,8 +771,8 @@ int GraphExecutor::InNode::ExecuteAction() {
     return 0 ;
   }
   }
-//  cdebug << pthread_self() << "/" << ThreadNo() << "<-- ExecuteAction "
-//         << Automaton()->ActionName( nextaction ) << endl ;
+  cdebug_out << pthread_self() << "/" << ThreadNo() << "<-- ExecuteAction "
+             << nextactionname << endl ;
   return sts ;
 }
 
@@ -786,16 +795,16 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
   unsigned int k;
   int InReady = 0 ;
   int res = 1;
-  bool LoopFinished = false ;
   bool LoopBeginning = false ;
+  bool LoopFinished = false ;
   bool SwitchFinished = false ;
 
-  if ( IsEndLoopNode() && !GetChangeNodeInLoop()->GetOutPort()->BoolValue() ) {
-    LoopFinished = true ; // End of Loop
-  }
   if ( IsLoopNode() && GetChangeNodeInLoop()->GetOutPort()->BoolValue() ) {
     LoopBeginning = true ; // Beginning of Loop
   }
+  if ( IsEndLoopNode() && !GetChangeNodeInLoop()->GetOutPort()->BoolValue() ) {
+    LoopFinished = true ; // End of Loop
+  }
   if ( IsEndSwitchNode() && !GetChangeNodeInGate()->GetOutPort()->BoolValue() ) {
     SwitchFinished = true ; // End of Switch
   }
@@ -816,9 +825,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       if ( anInPort->State() == SUPERV::ReadyState ) {
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " ReadyState " ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") ReadyState " ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -830,9 +839,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         anInPort->State( SUPERV::ReadyState ) ;
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " LoopBeginning " << LoopBeginning ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") LoopBeginning " << LoopBeginning ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -844,9 +853,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         anInPort->State( SUPERV::ReadyState ) ;
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " LoopFinished" ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") LoopFinished" ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -858,9 +867,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         anInPort->State( SUPERV::ReadyState ) ;
         InReady += 1 ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " SwitchFinished" ;
+               << anInPort->PortName() << " Was Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") SwitchFinished" ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -870,8 +879,8 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       }
       else {
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Was NOT Done from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
+               << anInPort->PortName() << " Was NOT Done from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
                << " " << Automaton()->StateName( State() ) << " DataConnected "
                << anInPort->IsDataConnected() << " LoopBeginning "
                << LoopBeginning << endl ;
@@ -886,9 +895,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
         InReady += 1 ;
         anInPort->State( SUPERV::ReadyState ) ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " Gate is Opened from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " " ;
+               << anInPort->PortName() << " Gate is Opened from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") " ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -899,9 +908,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       else if ( LoopFinished ) {
         anInPort->State( SUPERV::ReadyState ) ;
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " GATE IS CLOSED from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " LoopFinished" ;
+               << anInPort->PortName() << " GATE IS CLOSED from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") LoopFinished" ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -911,9 +920,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       }
       else {
         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-               << anInPort->PortName() << " GATE IS CLOSED from "
-               << anOutPort->NodeName() << " " << anOutPort->PortName()
-               << " " ;
+               << anInPort->PortName() << " GATE IS CLOSED from Node "
+               << anOutPort->NodeName() << "( " << anOutPort->PortName()
+               << ") " ;
 #ifdef _DEBUG_
         if ( GraphBase::Base::_prof_debug ) {
           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -926,8 +935,9 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       InReady += 1 ;
       anInPort->State( SUPERV::ReadyState ) ;
       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-             << anInPort->PortName() << " " << anInPort->PortStatus() << " is Done from "
-             << anOutPort->NodeName() << " " << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " ;
+             << anInPort->PortName() << " " << anInPort->PortStatus() << " is Done from Node "
+             << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
+             << anOutPort->PortStatus() << " " ;
 #ifdef _DEBUG_
       if ( GraphBase::Base::_prof_debug ) {
         anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
@@ -946,9 +956,11 @@ int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
       }
     }
     else {
-      cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
-             << anInPort->PortName() << " " << anInPort->PortStatus() << " is NOT Done from "
-             << anOutPort->NodeName() << " " << anOutPort->PortName() << " " << anOutPort->PortStatus() << " " ;
+      cdebug << pthread_self() << "/" << ThreadNo() << " Node " << Name() << "( "
+             << anInPort->PortName() << ") " << anInPort->PortStatus()
+             << " is NOT Done from Node "
+             << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
+             << anOutPort->PortStatus() << " " ;
     }
   }
 
@@ -1160,7 +1172,6 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
       MESSAGE(pthread_self() << "Executor::InNode::DataReady_ExecuteAction of " << Name()
               << " ControlState " << Automaton()->ControlStateName( ControlState() )
               << " BEFORE execution ThreadNo " << ThreadNo() ) ;
-      IsLoading( false ) ;
       Err = true ;
     }
     else {
@@ -1183,7 +1194,8 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
         }
         if ( IsOneOfInLineNodes() ) {
           cdebug << " , PyFuncName '" << InLineNode()->PyFuncName() << "' PyRunMethod "
-                 << InLineNode()->PyRunMethod() << " length " << (*InLineNode()->PythonFunction()).length() ;
+                 << InLineNode()->PyRunMethod() << " length "
+                 << (*InLineNode()->PythonFunction()).length() ;
        }
         cdebug << ")" << endl ;
 
@@ -1191,112 +1203,148 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
           bool StsPyDynInvoke = true;
          _OutNode->PyThreadLock() ;
           SetPyCpuUsed() ;
-         IsLoading( false ); // loading complete for InLine nodes. For Computing and Factory - there still
-                             // is some work to be done..  IsLoading( false ) for them is called later just before
-                              // calling DynInvoke()..  but for InLine PyDynInvoke() is called just right here below..  
           try {
 //            if ( IsInLineNode() && (*InLineNode()->PythonFunction()).length() &&
+            bool ItIsaLoop = false ;
             bool CopyInOut = false ;
            if ( IsInLineNode() && /*InLineNode()->PyRunMethod() &&*/
                  strlen( InLineNode()->PyFuncName() ) ) {
-//              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
-//                     << InLineNode()->PyFuncName()
-//                     << "' IsInLineNode PyDynInvoke"  << endl ;
+              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
+                     << InLineNode()->PyFuncName()
+                     << "' IsInLineNode PyDynInvoke"  << endl ;
               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
-           }
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }     }
             else if ( IsLoopNode() ) {
+              ItIsaLoop = true ;
               bool CopyOutIn = false ;
-              if ( GetNodeInLoop()->GetOutPort()->BoolValue() && /*InLineNode()->PyRunMethod() &&*/
-                   strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port
-//                cdebug << ThreadNo() << " !ObjInterface " << Name()
-//                       << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
-//                       << "'" << endl ;
-                StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
-                                              InLineNode()->PyFuncName() ,
-                                              &InParametersList[1] , ServiceInParameter().length() ,
-                                              &OutParametersList[1] , ServiceOutParameter().length() ) ;
-                CopyOutIn = true ;
+// Switch between Init() and Next()
+// if InLoop port is true and does not come from EndLoop ==> execute Init
+// if InLoop port is false or come from EndLoop ==> execute Next
+//              GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
+//              if ( GetNodeInLoop()->GetOutPort()->BoolValue() &&
+              if ( _InitLoop ) {
+                if ( strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port = true ==> Init()
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
+                         << "' InitLoop " << LoopNode()->PyRunMethod() << endl ;
+                  StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
+                                                InLineNode()->PyFuncName() ,
+                                                &InParametersList[1] , ServiceInParameter().length() ,
+                                                &OutParametersList[1] , ServiceOutParameter().length() ) ;
+                if ( !StsPyDynInvoke ) {
+                  RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+               }
+                  CopyOutIn = true ;
+               }
+                else {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode NO PyDynInvoke Void PyFuncName InitLoop" << endl ;
+               }
+                cdebug << ThreadNo() << " !ObjInterface " << Name()
+                       << " IsLoopNode _InitLoop Reset after Init() Python Function" << endl ;
+                _InitLoop = false ;
              }
               else if ( LoopNode()->PyNextMethod() &&
-                        strlen( LoopNode()->PyNextName() ) ){
-//                cdebug << ThreadNo() << " !ObjInterface " << Name()
-//                       << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
-//                       << "'" << endl ;
+                        strlen( LoopNode()->PyNextName() ) ){ // InLoop Port = false ==> Next()
+                cdebug << ThreadNo() << " !ObjInterface " << Name()
+                       << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
+                       << "' " << LoopNode()->PyNextMethod() << endl ;
                 StsPyDynInvoke = PyDynInvoke( LoopNode()->PyNextMethod() ,
                                               LoopNode()->PyNextName() ,
                                               &InParametersList[1] , ServiceInParameter().length() ,
                                               &OutParametersList[1] , ServiceOutParameter().length() ) ;
+                if ( !StsPyDynInvoke ) {
+                  RemovePyDynInvoke( LoopNode()->PyNextName() ) ;
+               }
                 CopyOutIn = true ;
              }
-              if ( StsPyDynInvoke && CopyOutIn ) {
-//                cdebug << ThreadNo() << " !ObjInterface " << Name()
-//                       << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
-//                       << "' Copy of " << ServiceInParameter().length()
-//                       << " OutParameters" << endl ;
-                int i ;
-                for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
-                  InParametersList[i].Value = OutParametersList[i].Value ;
-                  InParametersList[i].Name = OutParametersList[i].Name ;
+              else {
+                cdebug << ThreadNo() << " !ObjInterface " << Name()
+                       << " IsLoopNode NO PyDynInvoke Void PyFuncName NextLoop" << endl ;
+             }
+              if ( StsPyDynInvoke ) {
+                if ( CopyOutIn ) {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
+                         << "' Copy of " << ServiceInParameter().length()
+                         << " OutParameters" << endl ;
+                  int i ;
+// Start at 1 : Do not copy InLoop ( InLoop == true <==> Init ; InLoop == false <==> Next )
+                  for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
+                    InParametersList[i].Value = OutParametersList[i].Value ;
+                    InParametersList[i].Name = OutParametersList[i].Name ;
 //#if 0
-                  switch ( InParametersList[i].Value.type()->kind() ) {
-                  case CORBA::tk_string :
-                    char * t;
-                    InParametersList[i].Value >>= t ;
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(string) " << t << endl ;
-                    break ;
-                  case CORBA::tk_double :
-                    double d;
-                    InParametersList[i].Value >>= d;
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(double) " << d << endl ;
-                    break ;
-                  case CORBA::tk_long :
-                    long l;
-                    InParametersList[i].Value >>= l;
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(long) " << l << endl ;
-                    break ;
-                  case CORBA::tk_objref :
-                    CORBA::Object_ptr obj ;
-                    char * retstr ;
-                    try {
-                      InParametersList[i].Value >>= obj ;
-                      retstr = ObjectToString( obj );
+                    switch ( InParametersList[i].Value.type()->kind() ) {
+                    case CORBA::tk_string :
+                      char * t;
+                      InParametersList[i].Value >>= t ;
                       cdebug << "ArgOut->In" << i << " : "
                              << InParametersList[i].Name.c_str()
-                             << " Value(object reference) " << retstr << endl ;
-                    }
-                    catch ( ... ) {
+                             << " Value(string) " << t << endl ;
+                      break ;
+                    case CORBA::tk_double :
+                      double d;
+                      InParametersList[i].Value >>= d;
                       cdebug << "ArgOut->In" << i << " : "
                              << InParametersList[i].Name.c_str()
-                             << " Value(object reference) Catched ERROR" << endl ;
-                   }
-                    break ;
-                  default :
-                    cdebug << "ArgOut->In" << i << " : "
-                           << InParametersList[i].Name.c_str()
-                           << " Value(other) ERROR" << endl ;
-                 }
+                             << " Value(double) " << d << endl ;
+                      break ;
+                    case CORBA::tk_long :
+                      long l;
+                      InParametersList[i].Value >>= l;
+                      cdebug << "ArgOut->In" << i << " : "
+                             << InParametersList[i].Name.c_str()
+                             << " Value(long) " << l << endl ;
+                      break ;
+                    case CORBA::tk_objref :
+                      CORBA::Object_ptr obj ;
+                      char * retstr ;
+                      try {
+                        InParametersList[i].Value >>= obj ;
+                        retstr = ObjectToString( obj );
+                        cdebug << "ArgOut->In" << i << " : "
+                               << InParametersList[i].Name.c_str()
+                               << " Value(object reference) " << retstr << endl ;
+                      }
+                      catch ( ... ) {
+                        cdebug << "ArgOut->In" << i << " : "
+                               << InParametersList[i].Name.c_str()
+                               << " Value(object reference) Catched ERROR" << endl ;
+                     }
+                      break ;
+                    default :
+                      cdebug << "ArgOut->In" << i << " : "
+                             << InParametersList[i].Name.c_str()
+                             << " Value(other) ERROR" << endl ;
+                   }
 //#endif
+                 }
                }
                 if ( LoopNode()->PyMoreMethod() && strlen( LoopNode()->PyMoreName() ) ) {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
+                         << "' " << LoopNode()->PyMoreMethod() << endl ;
                   StsPyDynInvoke = PyDynInvoke( LoopNode()->PyMoreMethod() ,
                                                 LoopNode()->PyMoreName() ,
                                                 &InParametersList[1] , ServiceInParameter().length() ,
                                                 &OutParametersList[0] , ServiceOutParameter().length()+1 ) ;
+                  if ( !StsPyDynInvoke ) {
+                    RemovePyDynInvoke( LoopNode()->PyMoreName() ) ;
+                 }
                }
                 else {
+                  cdebug << ThreadNo() << " !ObjInterface " << Name()
+                         << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
+                         << "' No MoreMethod" << endl ;
                   CopyInOut = true ;
                }
              }
-              else  if ( !StsPyDynInvoke ) {
+              else {
                 Err = true ;
                 cdebug << ThreadNo() << " InLineNode " << Name() << " "
                        << InLineNode()->PyFuncName() << "/" << LoopNode()->PyNextName()
@@ -1313,6 +1361,9 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }
            }
 //            else if ( IsGOTONode() && (*GOTONode()->PythonFunction()).length() &&
             else if ( IsGOTONode() && /*InLineNode()->PyRunMethod() &&*/
@@ -1324,6 +1375,9 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( GOTONode()->PyFuncName() ) ;
+             }
            }
 //            else if ( IsEndSwitchNode() && (*InLineNode()->PythonFunction()).length() &&
             else if ( ( IsEndSwitchNode() ) &&
@@ -1335,20 +1389,28 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() ,
                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }
            }
             else if ( ( IsEndLoopNode() ) &&
                       InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
-//              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
-//                     << InLineNode()->PyFuncName()
-//                     << "' IsSwitchNode PyDynInvoke"  << endl ;
+              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
+                     << InLineNode()->PyFuncName()
+                     << "' IsSwitchNode PyDynInvoke"  << endl ;
               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
                                             InLineNode()->PyFuncName() ,
                                             &InParametersList[0] , ServiceInParameter().length() + 1 ,
                                             &OutParametersList[0] , ServiceOutParameter().length() + 1 ) ;
+              if ( !StsPyDynInvoke ) {
+                RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
+             }
            }
+
 //            else if ( (*InLineNode()->PythonFunction()).length() == 0 ||
-            if ( InLineNode()->PyRunMethod() == NULL ||
-                 strlen( InLineNode()->PyFuncName() ) == 0 || CopyInOut ) {
+            if ( (!ItIsaLoop && ( InLineNode()->PyRunMethod() == NULL ||
+                                  strlen( InLineNode()->PyFuncName() ) == 0 ) ) || CopyInOut ) {
+// This is a void Python Function : without code (No PyFuncName)
 //              cdebug << ThreadNo() << " !ObjInterface " << Name()
 //                     << " Copy of " << ServiceInParameter().length()
 //                     << " OutParameters" << endl ;
@@ -1358,8 +1420,12 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
               if ( IsLoopNode() || IsEndLoopNode() ) {
                 argout0 = 1 ;
                 argin0 = 1 ; // after DoLoop
-                if ( IsLoopNode() ) {
-                  OutParametersList[0].Value = InParametersList[0].Value ; // DoLoop
+                if ( IsLoopNode() ) { // More() is void
+//                  OutParametersList[0].Value = InParametersList[0].Value ; // DoLoop
+                  cdebug << Name() << " Not Beginning of loop and non void EndLoop : DoLoop = EndLoop(DoLoop)"
+                         << endl ;
+                  GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
+                  OutParametersList[0].Value = *anEndLoopNode->GetNodeOutLoop()->Value() ; // DoLoop = EndLoop(DoLoop)
                }
              }
               for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
@@ -1454,7 +1520,7 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
               }
               catch( ... ) {
                 cdebug << "DynInvoke setProperties catched ERROR" << endl ;
-                Err = true ;
+               Err = true;
              }
            }
             if ( !Err && IsComputingNode() ) {
@@ -1468,7 +1534,7 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                          &InParametersList[1] , ServiceInParameter().length()-1 ,
                          &OutParametersList[0] , ServiceOutParameter().length() ) ;
            }
-            else if ( !Err &&IsFactoryNode() ) {
+            else if ( !Err && IsFactoryNode() ) {
               cdebug << ThreadNo() << " !ObjInterface " << Name()
                      << " IsFactoryNode DynInvoke"  << endl ;
               cdebug << ServiceInParameter().length() << " input parameters and "
@@ -1488,21 +1554,28 @@ int GraphExecutor::InNode::DataReady_ExecuteAction() {
                    << " Node(Component) Dynamic Call Exception catched ERROR"
                    << endl ;
 //Reset of _ThreadId in the Container ...
-            myObjComponent->Kill_impl() ;
+            try {
+              myObjComponent->Kill_impl() ;
+           }
+            catch( ... ) {
+           }
          }
         }
       }
     }
   }
-//  else {
-//    sleep( 1 ) ;
-//  }
 
 //  ostringstream astr ;
 //  astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name() << " is done : "
 //       << Automaton()->StateName( State() ) ;
 //  _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
+
   if ( Err ) {
+    
+    // if exception or something else - IsLoading( false ) may not NOT has been called
+    if ( IsLoading() )
+      IsLoading( false );
+
     if ( ControlState() == SUPERV::ToKillState ||
          ControlState() == SUPERV::ToKillDoneState ||
          ControlState() == SUPERV::ToStopState ) {
@@ -1727,16 +1800,21 @@ void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
   State( GraphExecutor::DataWaitingState ) ;
   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
     GraphBase::InPort * anInPort = GetChangeNodeInPort( i ) ;
-    if ( anInPort->IsGate() ) { // Loop : Open the doors
+    cdebug << "SetWaitingStates InPort " << Name() << "( " << anInPort->PortName() << " ) "
+           << anInPort->PortStatus() << " " << anInPort->State() << endl ;
+// JR Debug 07.01.2005 : Close the Gates instead of open !!!
+    if ( anInPort->IsGate() ) { // Loop : Close the doors
       GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
       if ( anOutPort ) {
         CORBA::Any * anAny = new CORBA::Any() ;
-        *anAny <<= (long ) 1 ;
+//        *anAny <<= (long ) 1 ;
+        *anAny <<= (long ) 0 ;
         anOutPort->Value( anAny ) ;
-        anInPort->State( SUPERV::ReadyState ) ;
+        anInPort->State( SUPERV::WaitingState ) ;
       }
     }
-    else if ( anInPort->State() != SUPERV::WaitingState ) {
+    else if ( anInPort->State() != SUPERV::WaitingState &&
+              !anInPort->IsDataConnected() ) {
       if ( !docdebug ) {
         cdebug << ThreadNo()
                << " --> GraphExecutor::InNodeThreads::SetWaitingStates " << Name() << endl;
@@ -1746,13 +1824,14 @@ void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
         anInPort->State( SUPERV::WaitingState ) ;
       }
     }
+    cdebug << "               --> " << Name() << "( " << anInPort->PortName() << " ) "
+           << anInPort->PortStatus() << " " << anInPort->State() << endl ;
   }
   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
     for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
       if ( !( IsGOTONode() && anOutPort->IsGate() ) &&
-           !( IsEndLoopNode() && ( anOutPort->IsGate() ||
-              anOutPort->IsLoop() ) ) &&
+           !( IsEndLoopNode() && ( anOutPort->IsGate() || anOutPort->IsLoop() ) ) &&
            !anOutPort->IsDataStream() &&
            !anOutPort->ChangeInPorts( j )->IsDataStream() &&
            !anOutPort->ChangeInPorts( j )->IsExternConnected() ) {
@@ -1812,12 +1891,25 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
     else {
       aGateOutPort = GetNodeOutLoop() ;
     }
+    if ( aGateOutPort->InPortsSize() != 1 ) {
+      cdebug << ThreadNo() << " Successed_SuccessAction aGateOutPort->InPortsSize "
+             << aGateOutPort->InPortsSize() << " != 1 ERROR " << Name() << endl ;
+    }
+    GraphExecutor::InNode * aLabelNode = NULL ;
     for ( i = 0 ; i < aGateOutPort->InPortsSize() ; i++ ) {
       const GraphBase::InPort * anInPort = aGateOutPort->InPorts( i ) ;
-      GraphExecutor::InNode * aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
+      aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
       cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " will Loop to HeadNode "
              << aLabelNode->Name() << " from port " << anInPort->PortName() << endl ;
       aLabelNode->SetWaitingStates( this ) ;
+// JR 07.01.2005 Debug : Open the Gate of the coupledNode closed by SetWaitingStates
+      GraphBase::OutPort * anOutPort = aLabelNode->GetChangeNodeInGate()->GetOutPort() ;
+      if ( anOutPort ) {
+        CORBA::Any * anAny = new CORBA::Any() ;
+        *anAny <<= (long ) 1 ;
+        anOutPort->Value( anAny ) ;
+        aLabelNode->GetChangeNodeInGate()->State( SUPERV::ReadyState ) ;
+      }
       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
         if ( anInPort->GetOutPort() ) {
@@ -1831,7 +1923,8 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
         if ( !aBusParamOutPort->IsGate() ) {
           GraphBase::InPort * aBusParamChangeInPort = NULL ;
           if ( aBusParamOutPort->IsLoop() ) {
-            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
+// For EndLoop do not copy EndLoop(DoLoop) in Loop(InLoop)
+//            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
          }
           else {
             aBusParamChangeInPort = aLabelNode->GetChangeInPort( aBusParamOutPort->PortName() ) ;
@@ -1841,42 +1934,32 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
             cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " ChangeOutPort to HeadNode "
                    << aLabelNode->Name() << "(" << aBusParamChangeInPort->PortName() << ") from port "
                    << aBusParamOutPort->PortName() << endl ;
-            if ( !aLabelNode->IsLockedDataWait() ) {
-              res = aLabelNode->SendSomeDataReady( Name() ) ;
-              if ( res ) {
-                if ( firsttoNode == NULL &&
-                     aLabelNode->ThreadNo() == pthread_self() ) {
-                  firsttoNode = aLabelNode ;
-                  cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
-                         << aLabelNode->Name() << endl ;
-                }
-                else if ( firstzeroNode == NULL &&
-                          aLabelNode->ThreadNo() == 0 ) {
-                  firstzeroNode = aLabelNode ;
-               }
-                else {
-                  SomeDataNodes.push_back( aLabelNode ) ;
-                  cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
-                         << aLabelNode->Name() << " " << SomeDataNodes.size() 
-                         << endl ;
-               }
-             }
-           }
-            else {
-              cdebug << ThreadNo()
-                     << " Successed_SuccessAction Loop to HeadNode "
-                     << aLabelNode->Name() << " with datas from " << Name() << "("
-                     << aBusParamOutPort->PortName() << ") to port "
-                     << aBusParamChangeInPort->PortName() << endl;
-           }
-         }
-          else {
-            cdebug << ThreadNo() << " ERROR in Successed_SuccessAction of " << Name()
-                   << " NO port " << aBusParamOutPort->PortName() << " in "
-                   << aLabelNode->Name() << endl;
          }
+       }
+      }
+    }
+
+    if ( aLabelNode && !aLabelNode->IsLockedDataWait() ) {
+      res = aLabelNode->SendSomeDataReady( Name() ) ;
+      if ( res ) {
+        if ( firsttoNode == NULL &&
+             aLabelNode->ThreadNo() == pthread_self() ) {
+          firsttoNode = aLabelNode ;
+          cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
+                 << aLabelNode->Name() << endl ;
         }
+        else if ( firstzeroNode == NULL &&
+                  aLabelNode->ThreadNo() == 0 ) {
+          firstzeroNode = aLabelNode ;
+        }
+        else {
+          SomeDataNodes.push_back( aLabelNode ) ;
+          cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
+                 << aLabelNode->Name() << " " << SomeDataNodes.size() 
+                 << endl ;
+       }
       }
+
       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
         if ( anInPort->GetOutPort() ) {
@@ -1984,7 +2067,7 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
           LoopOutPort->PortStatus( DataConnected );
           LoopOutPort->State( SUPERV::ReadyState ) ;
           LoopOutPort->Done( true ) ;
-          CORBA::Any * anAny = new CORBA::Any() ;
+          CORBA::Any * anAny = new CORBA::Any() ; // InitLoop
           *anAny <<= (long ) 1 ;
           LoopOutPort->Value( anAny ) ;
           int j ;
@@ -2106,7 +2189,7 @@ int GraphExecutor::InNode::Successed_SuccessAction() {
 bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
   bool RetVal = false ;
   if ( IsDataFlowNode() ) {
-    cdebug << ThreadNo() << " ----> " << Name()
+    cdebug << ThreadNo() << "InNode::SendSomeDataReady ----> " << Name()
          << " send Result to graph " << Name() << endl;
   }
   else {
@@ -2131,6 +2214,12 @@ bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
 //             << ThreadNo() << " " << endl ;
       State( GraphExecutor::DataWaitingState ) ;
     }
+// We begin that LoopNode if SendSomeDataReady does not come from the corresponding EndLoopNode
+    if ( IsLoopNode() && strcmp( LoopNode()->CoupledNodeName() , FromNodeName ) ) {
+      cdebug << ThreadNo() << "InNode::SendSomeDataReady " << Name() << " Set _InitLoop from "
+             << FromNodeName << endl ;
+      _InitLoop = true ;
+    }
     LockDataWait() ;
     DataFromNode( FromNodeName ) ;
     RetVal = !SendEvent( GraphExecutor::SomeDataReadyEvent );
@@ -2325,7 +2414,8 @@ void GraphExecutor::InNode::InParametersSet( bool & Err ,
         *anAny <<= (long ) 0 ;
         theOutPort->Value( anAny ) ;
       }
-      if ( !anInPort->IsDataStream() ) {
+      if ( !anInPort->IsDataStream() &&
+           !anInPort->IsDataConnected() ) {
         anInPort->State( SUPERV::WaitingState ) ;
       }
       D.Name = CORBA::string_dup( anInPort->GetServicesParameter().Parametername ) ;