Salome HOME
Bug fix: don't set "Loading" state for MacroNodes in InitialState() function (called...
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNode.cxx
index 8663bad398e2d1a1ff9f102c7881f8798db16078..e03187981ecf14869adaff2be373016473aad782 100644 (file)
@@ -32,6 +32,7 @@ using namespace std;
 #include <iostream>
 #include <unistd.h>
 #include <stdio.h>
+#include <errno.h>
 
 #include "OpUtil.hxx"
 
@@ -47,11 +48,12 @@ using namespace std;
 #include "DataFlowBase_SwitchNode.hxx"
 #include "DataFlowBase_EndOfSwitchNode.hxx"
 
-#include "DataFlowExecutor_OutNode.hxx"
+#include "DataFlowExecutor_DataFlow.hxx"
+#include "DataFlowEditor_DataFlow.hxx"   // GraphEditor package must be built BEFORE
 
 static void InitInNode( int &_RewindStack ,
                         SUPERV::ControlState &_ControlState ,
-                        SUPERV::AutomatonState &_currentState ,
+                        GraphExecutor::AutomatonState &_currentState ,
                         GraphExecutor::InNode ** _aReStartNode ,
                         bool & _PyFuncRunned ,
                         PyObject ** _MyPyRunMethod ,
@@ -68,14 +70,17 @@ static void InitInNode( int &_RewindStack ,
                         bool &_ResumeSync ,
                         pthread_cond_t &_KillWait ,
                         bool &_KillSync ,
+                        pthread_cond_t &_ThreadStartedWait ,
+                        bool &_ThreadStartedSync ,
                         pthread_cond_t &_StopWait ,
                         GraphExecutor::FiniteStateMachine ** _Automaton ,
                         GraphExecutor::FiniteStateMachine * theAutomaton ,
                         CORBA::ORB_ptr * _Orb ,
-                        CORBA::ORB_ptr ORB ) {
+                        CORBA::ORB_ptr ORB,
+                       bool &_Loading ) {
   _RewindStack = 0 ;
   _ControlState = SUPERV::VoidState ;
-  _currentState = SUPERV::UnKnownState ;
+  _currentState = GraphExecutor::UnKnownState ;
   *_aReStartNode = NULL ;
   _PyFuncRunned = false ;
   *_MyPyRunMethod = NULL ;
@@ -113,16 +118,21 @@ static void InitInNode( int &_RewindStack ,
     exit( 0 ) ;
   }
   _KillSync = false ;
+  if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
+    perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
+    exit( 0 ) ;
+  }
+  _ThreadStartedSync = false ;
   if ( pthread_cond_init( &_StopWait , NULL ) ) {
     perror("pthread_cond_init( &_StopWait , NULL )") ;
     exit( 0 ) ;
   }
   *_Automaton = theAutomaton ;
   *_Orb = CORBA::ORB::_nil();
+  _Loading = false;
 }
 
-GraphExecutor::FiniteStateMachine * theAutomaton = new
-                                        GraphExecutor::FiniteStateMachine() ;
+GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
 
 //GraphExecutor::InNode::InNode() :
 //     GraphBase::FactoryNode() {
@@ -146,33 +156,36 @@ GraphExecutor::InNode::InNode() {
               _ResumeSync ,
               _KillWait ,
               _KillSync ,
+              _ThreadStartedWait ,
+              _ThreadStartedSync ,
               _StopWait ,
               &_Automaton ,
               theAutomaton ,
               &_Orb ,
-              CORBA::ORB::_nil() ) ;
+              CORBA::ORB::_nil(),
+             _Loading ) ;
 }
 
-GraphExecutor::InNode::InNode(CORBA::ORB_ptr ORB,
-               SALOME_NamingService* ptrNamingService ,
-               const SALOME_ModuleCatalog::Service& aService ,
-               const char * ComponentName ,
-               const char * NodeInterfaceName ,
-               const char * NodeName ,
-               const SUPERV::KindOfNode akind ,
-               GraphBase::ListOfFuncName aFuncName ,
-               GraphBase::ListOfPythonFunctions aPythonFunction ,
-               const SUPERV::SDate NodeFirstCreation ,
-               const SUPERV::SDate NodeLastModification  ,
-               const char * NodeEditorRelease ,
-               const char * NodeAuthor ,
-               const char * NodeComputer ,
-               const char * NodeComment ,
-               const bool   GeneratedName ,
-               const int NodeX ,
-               const int NodeY ,
-               int * Graph_prof_debug,
-               ofstream * Graph_fdebug) {
+GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
+                               SALOME_NamingService* ptrNamingService ,
+                               const SALOME_ModuleCatalog::Service& aService ,
+                               const char * ComponentName ,
+                               const char * NodeInterfaceName ,
+                               const char * NodeName ,
+                               const SUPERV::KindOfNode akind ,
+                               GraphBase::ListOfFuncName aFuncName ,
+                               GraphBase::ListOfPythonFunctions aPythonFunction ,
+                               const SUPERV::SDate NodeFirstCreation ,
+                               const SUPERV::SDate NodeLastModification  ,
+                               const char * NodeEditorRelease ,
+                               const char * NodeAuthor ,
+                               const char * NodeComputer ,
+                               const char * NodeComment ,
+                               const bool   GeneratedName ,
+                               const int NodeX ,
+                               const int NodeY ,
+                               int * Graph_prof_debug,
+                               ofstream * Graph_fdebug) {
 //               ostream * Graph_fdebug = NULL ) :
 //             GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
 //                                     ComponentName , NodeInterfaceName ,
@@ -201,11 +214,14 @@ GraphExecutor::InNode::InNode(CORBA::ORB_ptr ORB,
               _ResumeSync ,
               _KillWait ,
               _KillSync ,
+              _ThreadStartedWait ,
+              _ThreadStartedSync ,
               _StopWait ,
               &_Automaton ,
               theAutomaton ,
               &_Orb ,
-              ORB ) ;
+              ORB,
+             _Loading ) ;
   SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
 
   _ComputingNode = NULL ;
@@ -257,6 +273,22 @@ GraphExecutor::InNode::InNode(CORBA::ORB_ptr ORB,
     _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
     break ;
   }
+  case SUPERV::MacroNode : {
+    cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
+    _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
+//                                            aFuncName[0].c_str() , *aPythonFunction[0] ,
+                                            NodeName , akind ,
+//                                            NodeFirstCreation , NodeLastModification  ,
+//                                            NodeEditorRelease , NodeAuthor ,
+//                                            NodeComment , GeneratedName ,
+//                                            NodeX , NodeY ,
+                                            Graph_prof_debug , Graph_fdebug ) ;
+    _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
+    _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
+    _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
+    _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
+    break ;
+  }
   case SUPERV::GOTONode : {
     cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
     _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
@@ -335,8 +367,11 @@ GraphExecutor::InNode::InNode(CORBA::ORB_ptr ORB,
     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
     break ;
   }
-  case SUPERV::DataFlowNode : {
-    cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowNode ERROR : " << NodeName ;
+  case SUPERV::DataFlowGraph : {
+    cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
+  }
+  case SUPERV::DataStreamGraph : {
+    cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
   }
   case SUPERV::UnknownNode : {
     cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
@@ -397,8 +432,16 @@ bool GraphExecutor::InNode::Ping() {
   if ( IsFactoryNode() ) {
     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
     if ( RetVal ) {
-      if ( State() != SUPERV::SuspendedExecutingState ) {
-        _FactoryNode->Component()->ping() ;
+      if ( State() != GraphExecutor::SuspendedExecutingState ) {
+        try {
+          _FactoryNode->Component()->ping() ;
+       }
+        catch( ... ) {
+          cdebug << "InNode::Ping() ERROR catched" << endl ;
+          State( GraphExecutor::ErroredState ) ;
+          _OutNode->State( GraphExecutor::ErroredState ) ;
+          RetVal = false ;
+       }
       }
       else {
         RetVal = false ;
@@ -421,11 +464,16 @@ void GraphExecutor::InNode::ExitThread() {
 
 bool GraphExecutor::InNode::Suspend() {
   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
-            << endl;
-  bool RetVal ;
+            << " " << Automaton()->StateName( State() ) << endl;
+  bool RetVal = false ;
   if ( IsDone() ) {
-    ControlState( SUPERV::VoidState ) ;
-    RetVal = false ;
+//If loop we need to suspend also    ControlState( SUPERV::VoidState ) ;
+    ControlState( SUPERV::ToSuspendState ) ;
+    RetVal = true ;
+    if ( _OutNode->IsDone() ) {
+      ControlState( SUPERV::VoidState ) ;
+      RetVal = false ;
+    }
   }
   else if ( IsWaiting() || IsReady() ) {
     ControlState( SUPERV::ToSuspendState ) ;
@@ -433,39 +481,126 @@ bool GraphExecutor::InNode::Suspend() {
   }
   else  if ( IsRunning() ) {
     ControlState( SUPERV::ToSuspendState ) ;
-    if ( IsFactoryNode() ) {
-      if ( !CORBA::is_nil( Component() ) ) {
-        RetVal = Component()->Suspend_impl() ;
-        if ( RetVal ) {
-          if ( IsRunning() ) {
-            SendEvent( GraphExecutor::SuspendEvent ) ;
-          }
-          else if ( IsDone() ) {
-            ControlState( SUPERV::VoidState ) ;
-            RetVal = false ; // Too late ...
+    if ( IsFactoryNode() || IsComputingNode() ) {
+// We have to suspend in the container of that node
+      int TrySuspend = 10 ;
+      while ( TrySuspend ) {
+        if ( !CORBA::is_nil( Component() ) ) {
+// We can call that component
+          try {
+            RetVal = Component()->Suspend_impl() ;
+         }
+          catch( ... ) {
+            cdebug << "InNode::Suspend() ERROR catched" << endl ;
+            State( GraphExecutor::ErroredState ) ;
+            _OutNode->State( GraphExecutor::ErroredState ) ;
+            RetVal = false ;
+            TrySuspend = 1 ;
+         }
+          cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
+          if ( RetVal ) {
+            if ( IsRunning() ) {
+              cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
+                     << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
+              SendEvent( GraphExecutor::SuspendEvent ) ;
+              cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
+                     << Name() << " --> thread" << ThreadNo() << endl;
+              TrySuspend = 1 ;
+            }
+            else if ( IsDone() ) {
+              ControlState( SUPERV::VoidState ) ;
+              RetVal = false ; // Too late ...
+              TrySuspend = 1 ;
+            }
+            else {
+              cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
+                     << endl ;
+              MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
+              TrySuspend = 1 ;
+           }
           }
           else {
-            cdebug << "component Suspended and !IsDone and !IsRunning !"
+// Suspend in the Container failed : it is always false if it is a Python Container
+            cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
                    << endl ;
+            if ( TrySuspend == 1 ) {
+              if ( IsSuspended() ) {
+                RetVal = true ;
+             }
+              else {
+                RetVal = false ;
+             }
+           }
+          }
+        }
+        else {
+          cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
+                 << endl ;
+// Wait for the end of loading of the component
+          while ( IsLoading() ) {
+            sleep( 1 ) ;
+         }
+          if ( TrySuspend == 1 ) {
+            if ( IsSuspended() ) {
+              RetVal = true ;
+           }
+            else {
+              RetVal = false ;
+           }
          }
         }
+        TrySuspend -= 1 ;
+        if ( TrySuspend ) {
+          sleep( 1 ) ;
+       }
       }
-      else {
-        cdebug << "Suspend cannot Suspend component !" << endl ;
-        RetVal = false ;
+    }
+    else if ( IsMacroNode() ) {
+// It should be like that but it is not completely implemented
+      GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
+      RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
+      if ( RetVal ) {
+        State( GraphExecutor::SuspendedState ) ;
       }
     }
     else {
-      cdebug << "Suspend with nilComponent while RunningState !" << endl ;
-      RetVal = false ;
+// Now we can suspend an InLineNode with the handler of the SuperVision Container
+      if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
+        perror("Suspend pthread_kill error") ;
+        State( GraphExecutor::ErroredState ) ;
+        _OutNode->State( GraphExecutor::ErroredState ) ;
+        RetVal = false ;
+      }
+      else {
+        RetVal = true ;
+      }
+      if ( RetVal ) {
+        if ( IsRunning() ) {
+          cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
+                 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
+          SendEvent( GraphExecutor::SuspendEvent ) ;
+          cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
+                 << Name() << " --> thread" << ThreadNo() << endl;
+        }
+        else if ( IsDone() ) {
+          ControlState( SUPERV::VoidState ) ;
+          RetVal = false ; // Too late ...
+        }
+        else {
+          cdebug << "component Suspended and !IsDone and !IsRunning !"
+                 << endl ;
+       }
+      }
     }
   }
   else {
-    cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
-           << endl ;
+    cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
+           << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
+           << " ?" << endl ;
     RetVal = false ;
   }
-  cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << endl ;
+  cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
+             << Automaton()->StateName( State() ) << endl ;
   return RetVal ;
 }
 
@@ -475,7 +610,7 @@ bool GraphExecutor::InNode::ContainerKill() {
   bool RetVal ;
   if ( IsFactoryNode() ) {
     Kill() ;
-    Container()->Kill_impl() ;
+    RetVal = Container()->Kill_impl() ;
   }
   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
   return RetVal ;
@@ -483,62 +618,159 @@ bool GraphExecutor::InNode::ContainerKill() {
 
 bool GraphExecutor::InNode::Kill() {
   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
-            << Automaton()->StateName( State() ) << endl;
+            << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
+            << " SuspendedThreads " << _OutNode->SuspendedThreads()
+            << " EventQSize " << _OutNode->EventQSize() << endl;
   bool RetVal ;
-  if ( ControlState() == SUPERV::ToKillState || IsDone() ) {
+  if ( IsDone() ) {
+    ControlState( SUPERV::ToKillState ) ; // if loop
+    if ( _OutNode->IsDone() ) {
+      ControlState( SUPERV::VoidState ) ;
+    }
     RetVal = false ;
   }
   else {
     ControlState( SUPERV::ToKillState ) ;
     if ( IsDone() ) {
-      ControlState( SUPERV::VoidState ) ;
+      if ( _OutNode->IsDone() ) {
+        ControlState( SUPERV::VoidState ) ;
+      }
       RetVal = false ;
     }
     else {
       if ( IsRunning() ) {
-        if ( IsFactoryNode() ) {
-          if ( !CORBA::is_nil( Component() ) ) {
-            RetVal = Component()->Kill_impl() ;
-            if ( RetVal ) {
-              if ( IsRunning() ) {
-                SendEvent( GraphExecutor::KillEvent ) ;
+        if ( IsFactoryNode() || IsComputingNode() ) {
+// We have to suspend in the container of that node
+          int TryKill = 10 ;
+          while ( TryKill ) {
+            if ( !CORBA::is_nil( Component() ) ) {
+// We can call that component
+              try {
+                RetVal = Component()->Kill_impl() ;
              }
-              else if ( IsDone() ) {
-                ControlState( SUPERV::VoidState ) ;
-                RetVal = false ; // Too late ...
+              catch( ... ) {
+                cdebug << "InNode::Kill_impl ERROR catched" << endl ;
+                State( GraphExecutor::ErroredState ) ;
+                _OutNode->State( GraphExecutor::ErroredState ) ;
+                RetVal = false ;
+                TryKill = 1 ;
+             }
+              cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
+              if ( RetVal ) {
+                if ( IsRunning() ) {
+                  cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
+                         << " --> thread" << ThreadNo() << " KillEvent " << endl;
+                  SendEvent( GraphExecutor::KillEvent ) ;
+                  cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
+                         << Name() << " --> thread" << ThreadNo() << endl;
+                  TryKill = 1 ;
+               }
+                else if ( IsDone() ) {
+                  ControlState( SUPERV::VoidState ) ;
+                  RetVal = false ; // Too late ...
+                  TryKill = 1 ;
+               }
+                else {
+                  cdebug << "Kill component Killed and !IsDone and !IsRunning !"
+                         << endl ;
+                  TryKill = 1 ;
+               }
              }
               else {
-                cdebug << "component Killed and !IsDone and !IsRunning !"
+//  Kill in the Container failed : it is always false if it is a Python Container
+                cdebug << "InNode::Suspend cannot  Kill component ! Python Component ?"
                        << endl ;
+                if ( TryKill == 1 ) {
+                  if ( IsKilled() ) {
+                    RetVal = true ;
+                 }
+                  else {
+                    RetVal = false ;
+                 }
+               }
+             }
+           }
+            else {
+              cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
+                     << endl ;
+// Wait for the end of loading of the component
+              while ( IsLoading() ) {
+                sleep( 1 ) ;
+             }
+              if ( TryKill == 1 ) {
+                if ( IsKilled() ) {
+                  RetVal = true ;
+               }
+                else {
+                  RetVal = false ;
+               }
              }
            }
+            TryKill -= 1 ;
+            if ( TryKill ) {
+              sleep( 1 ) ;
+            }
          }
-          else {
-            cdebug << "Kill cannot Kill component !" << endl ;
-            RetVal = false ;
+       }
+        else if ( IsMacroNode() ) {
+// It should be like that but it is not completely implemented
+          GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
+          RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
+          if ( RetVal ) {
+            State( GraphExecutor::KilledState ) ;
          }
        }
         else {
-          cdebug << "Kill with nilComponent while RunningState !" << endl ;
-          SendEvent( GraphExecutor::KillEvent ) ;
-          RetVal = IsKilled() ;
-        }
+//PAL6886
+// Now we can kill an InLineNode with the handler of the SuperVision Container
+          cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
+                 << _OutNode->MainThreadId() << " :" << endl ;
+          MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
+                 << _OutNode->MainThreadId() << " :" ) ;
+          if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
+// python signals run only in main thread ...
+            perror("Kill pthread_kill error") ;
+            State( GraphExecutor::ErroredState ) ;
+            _OutNode->State( GraphExecutor::ErroredState ) ;
+            RetVal = false ;
+         }
+          else {
+            cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
+                   << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
+            MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
+                   << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
+            RetVal = true ;
+         }
+       }
       }
       else if ( IsSuspended() ) {
-        SendEvent( GraphExecutor::KillEvent ) ;
-        RetVal = true ;
+        cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
+               << " --> thread" << ThreadNo() << " Resume()" << endl;
+        if ( Resume() ) {
+          RetVal = Kill() ;
+       }
+        else {
+          RetVal = false ;
+       }
       }
       else if ( IsWaiting() ) {
+        RetVal = false ;
+      }
+      else if ( IsReady() ) {
         RetVal = true ;
       }
       else {
-        cdebug << "Kill and !IsDone and !IsRunning and !IsWaiting ?"
-               << endl ;
+       cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
+              << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
+              << " ?" << endl ;
         RetVal = false ;
       }
     }
   }
-  cdebug_out << "GraphExecutor::InNode::Kill" << endl ;
+  cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
+             << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
+             << " SuspendedThreads " << _OutNode->SuspendedThreads()
+             << " EventQSize " << _OutNode->EventQSize() << endl ;
   return RetVal ;
 }
 
@@ -552,43 +784,20 @@ bool GraphExecutor::InNode::KillDone() {
   else {
     ControlState( SUPERV::ToKillDoneState ) ;
     if ( IsDone() ) {
-      ControlState( SUPERV::VoidState ) ;
+      if ( _OutNode->IsDone() ) {
+        ControlState( SUPERV::VoidState ) ;
+      }
       RetVal = false ;
     }
     else {
       if ( IsRunning() ) {
-        if ( IsFactoryNode() ) {
-          if ( !CORBA::is_nil( Component() ) ) {
-            RetVal = Component()->Kill_impl() ;
-            if ( RetVal ) {
-              if ( IsRunning() ) {
-                SendEvent( GraphExecutor::SuspendEvent ) ;
-             }
-              else if ( IsDone() ) {
-                ControlState( SUPERV::VoidState ) ;
-                RetVal = false ; // Too late ...
-             }
-              else {
-                cdebug << "component Suspended and !IsDone and !IsRunning !"
-                       << endl ;
-             }
-           }
-         }
-          else {
-            cdebug << "Suspend cannot Suspend component !" << endl ;
-            RetVal = false ;
-         }
-       }
-        else {
-          cdebug << "Suspend with nilComponent while RunningState !" << endl ;
-          RetVal = false ;
-        }
+        RetVal = true ;
       }
       else if ( IsWaiting() ) {
         RetVal = true ;
       }
       else {
-        cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
+        cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
                << endl ;
         RetVal = false ;
       }
@@ -608,17 +817,27 @@ bool GraphExecutor::InNode::Stop() {
   else {
     ControlState( SUPERV::ToStopState ) ;
     if ( IsDone() ) {
-      ControlState( SUPERV::VoidState ) ;
+      if ( _OutNode->IsDone() ) {
+        ControlState( SUPERV::VoidState ) ;
+      }
       RetVal = false ;
     }
     else {
       if ( IsRunning() ) {
-        if ( IsFactoryNode() ) {
+        if ( IsFactoryNode() || IsComputingNode() ) {
           if ( !CORBA::is_nil( Component() ) ) {
-            RetVal = Component()->Stop_impl() ;
+            try {
+              RetVal = Component()->Stop_impl() ;
+           }
+            catch( ... ) {
+              cdebug << "InNode::Stop() ERROR catched" << endl ;
+              State( GraphExecutor::ErroredState ) ;
+              _OutNode->State( GraphExecutor::ErroredState ) ;
+              RetVal = false ;
+           }
             if ( RetVal ) {
               if ( IsRunning() ) {
-                SendEvent( GraphExecutor::SuspendEvent ) ;
+                SendEvent( GraphExecutor::StopEvent ) ;
              }
               else if ( IsDone() ) {
                 ControlState( SUPERV::VoidState ) ;
@@ -631,7 +850,7 @@ bool GraphExecutor::InNode::Stop() {
            }
          }
           else {
-            cdebug << "Suspend cannot Suspend component !" << endl ;
+            cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
             RetVal = false ;
          }
        }
@@ -664,7 +883,9 @@ bool GraphExecutor::InNode::SuspendDone() {
   else {
     ControlState( SUPERV::ToSuspendDoneState ) ;
     if ( IsDone() ) {
-      ControlState( SUPERV::VoidState ) ;
+      if ( _OutNode->IsDone() ) {
+        ControlState( SUPERV::VoidState ) ;
+      }
       RetVal = false ;
     }
     else {
@@ -681,21 +902,63 @@ bool GraphExecutor::InNode::Resume() {
             << Automaton()->StateName( State() ) << endl;
   bool RetVal = false ;
   if ( IsSuspended() ) {
-    if ( State() == SUPERV::SuspendedReadyState ) {
+    if ( State() == GraphExecutor::SuspendedReadyState ) {
       ResumeAction( GraphExecutor::ToResumeEvent ) ;
       RetVal = true ;
     }
-    else if ( State() == SUPERV::SuspendedExecutingState ) {
-      if ( IsFactoryNode() ) {
-        RetVal = Component()->Resume_impl() ;
+    else if ( State() == GraphExecutor::SuspendedExecutingState ) {
+      if ( IsFactoryNode() || IsComputingNode() ) {
+        if ( pthread_mutex_lock( &_MutexWait ) ) {
+          perror("ResumeAction pthread_mutex_lock ") ;
+          exit( 0 ) ;
+        }
+        try {
+          RetVal = Component()->Resume_impl() ;
+          if ( RetVal ) {
+            State( GraphExecutor::ExecutingState ) ;
+         }
+       }
+        catch( ... ) {
+          cdebug << "InNode::Resume() ERROR catched" << endl ;
+          State( GraphExecutor::ErroredState ) ;
+          _OutNode->State( GraphExecutor::ErroredState ) ;
+          RetVal = false ;
+       }
+        if ( pthread_mutex_unlock( &_MutexWait ) ) {
+          perror("ResumeAction pthread_mutex_unlock ") ;
+          exit( 0 ) ;
+        }
+      }
+      else if ( IsMacroNode() ) {
+        cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
+        GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
+        RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
+        if ( RetVal ) {
+          State( GraphExecutor::ExecutingState ) ;
+       }
+      }
+      else {
+// Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
+        cdebug << ThreadNo() << "/" << pthread_self()
+               << "Resume of InLineNode pthread_kill" << Name() << endl ;
+        if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
+          perror("Resume pthread_kill error") ;
+          State( GraphExecutor::ErroredState ) ;
+          _OutNode->State( GraphExecutor::ErroredState ) ;
+          RetVal = false ;
+        }
+        else {
+          State( GraphExecutor::ExecutingState ) ;
+          RetVal = true ;
+        }
       }
     }
-    else if ( State() == SUPERV::SuspendedSuccessedState ) {
-      ResumeAction( GraphExecutor::ToResumeEvent ) ;
+    else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
+      ResumeAction( GraphExecutor::ResumeEvent ) ;
       RetVal = true ;
     }
-    else if ( State() == SUPERV::SuspendedErroredState ) {
-      ResumeAction( GraphExecutor::ToResumeEvent ) ;
+    else if ( State() == GraphExecutor::SuspendedErroredState ) {
+      ResumeAction( GraphExecutor::ResumeEvent ) ;
       RetVal = true ;
     }
     else {
@@ -716,13 +979,13 @@ bool GraphExecutor::InNode::Resume() {
 #if 0
   if ( ControlState() == SUPERV::ToSuspendRunState ||
        ( ControlState() == SUPERV::ToSuspendState &&
-         State() == SUPERV::SuspendedReadyState) ) {
+         State() == GraphExecutor::SuspendedReadyState) ) {
     if ( IsSuspended() ) {
-      if ( State() == SUPERV::SuspendedReadyState ) {
+      if ( State() == GraphExecutor::SuspendedReadyState ) {
         ResumeAction() ;
         RetVal = true ;
       }
-      else if ( State() == SUPERV::SuspendedExecutingState ) {
+      else if ( State() == GraphExecutor::SuspendedExecutingState ) {
         ResumeAction() ;
         RetVal = Component()->Resume_impl() ;
       }
@@ -748,13 +1011,13 @@ bool GraphExecutor::InNode::Resume() {
   }
   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
             ( ControlState() == SUPERV::ToSuspendState &&
-              State() == SUPERV::SuspendedSuccessedState) ) {
+              State() == GraphExecutor::SuspendedSuccessedState) ) {
     if ( IsSuspended() ) {
-      if ( State() == SUPERV::SuspendedSuccessedState ) {
+      if ( State() == GraphExecutor::SuspendedSuccessedState ) {
         ResumeAction() ;
         RetVal = true ;
       }
-      else if ( State() == SUPERV::SuspendedErroredState ) {
+      else if ( State() == GraphExecutor::SuspendedErroredState ) {
         ResumeAction() ;
         RetVal = true ;
       }
@@ -780,14 +1043,15 @@ bool GraphExecutor::InNode::Resume() {
     }
   }
 #endif
-  cdebug_out << "GraphExecutor::InNode::Resume " << RetVal << endl ;
+  cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
+             << Automaton()->StateName( State() ) << endl ;
   return RetVal ;
 }
 
 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
                                      const bool AndSuspend ) {
   bool RetVal = false ;
-  GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->GetGraphNode( AtNodeName )->GetInNode() ;
+  GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetGraphNode( AtNodeName )->GetInNode() ;
   cdebug_in << pthread_self() << "/" << ThreadNo()
             << " --> GraphExecutor::InNode::ReStartAt( "
             << AtNodeName << " , " << AndSuspend << ") " << endl
@@ -800,7 +1064,7 @@ bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
   }
   else if ( IsSuspended() ) {
     if ( strcmp( AtNodeName , Name() ) ) {
-      aRestartNode->State( SUPERV::SuspendedSuccessedState ) ;
+      aRestartNode->State( GraphExecutor::SuspendedSuccessedState ) ;
     }
     if ( AndSuspend ) {
       ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
@@ -817,14 +1081,14 @@ bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
 bool GraphExecutor::InNode::IsWaiting() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::DataUndefState ||
-       aState == SUPERV::DataWaitingState ||
-       aState == SUPERV::SuspendedReadyState )
-//       aState == SUPERV::SuspendedExecutingState ||
-//       aState == SUPERV::SuspendedSuccessedState ||
-//       aState == SUPERV::SuspendedErroredState ||
-//       aState == SUPERV::SuspendedState
+  GraphExecutor::AutomatonState aState = State() ;
+  if ( aState == GraphExecutor::DataUndefState ||
+       aState == GraphExecutor::DataWaitingState ||
+       aState == GraphExecutor::SuspendedReadyState )
+//       aState == GraphExecutor::SuspendedExecutingState ||
+//       aState == GraphExecutor::SuspendedSuccessedState ||
+//       aState == GraphExecutor::SuspendedErroredState ||
+//       aState == GraphExecutor::SuspendedState
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
   return aret ;
@@ -833,11 +1097,11 @@ bool GraphExecutor::InNode::IsWaiting() {
 bool GraphExecutor::InNode::IsReady() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::DataUndefState ||
-       aState == SUPERV::DataWaitingState ||
-       aState == SUPERV::DataReadyState ||
-       aState == SUPERV::ResumedReadyState )
+  GraphExecutor::AutomatonState aState = State() ;
+//  if ( aState == GraphExecutor::DataUndefState ||
+//       aState == GraphExecutor::DataWaitingState ||
+  if ( aState == GraphExecutor::DataReadyState ||
+       aState == GraphExecutor::ResumedReadyState )
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
   return aret ;
@@ -846,9 +1110,9 @@ bool GraphExecutor::InNode::IsReady() {
 bool GraphExecutor::InNode::IsRunning() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::ExecutingState ||
-       aState == SUPERV::ResumedExecutingState )
+  GraphExecutor::AutomatonState aState = State() ;
+  if ( aState == GraphExecutor::ExecutingState ||
+       aState == GraphExecutor::ResumedExecutingState )
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
   return aret ;
@@ -857,21 +1121,21 @@ bool GraphExecutor::InNode::IsRunning() {
 bool GraphExecutor::InNode::IsDone() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::KilledReadyState ||
-       aState == SUPERV::StoppedReadyState ||
-       aState == SUPERV::KilledExecutingState ||
-       aState == SUPERV::StoppedExecutingState ||
-       aState == SUPERV::SuspendedSuccessedState ||
-       aState == SUPERV::SuspendedErroredState ||
-//       aState == SUPERV::SuccessedExecutingState ||
-//       aState == SUPERV::ErroredExecutingState ||
-       aState == SUPERV::SuccessedState ||
-       aState == SUPERV::ErroredState ||
-       aState == SUPERV::ResumedSuccessedState ||
-       aState == SUPERV::ResumedErroredState ||
-       aState == SUPERV::KilledSuccessedState ||
-       aState == SUPERV::StoppedSuccessedState )
+  GraphExecutor::AutomatonState aState = State() ;
+  if ( aState == GraphExecutor::KilledReadyState ||
+       aState == GraphExecutor::StoppedReadyState ||
+       aState == GraphExecutor::KilledExecutingState ||
+       aState == GraphExecutor::StoppedExecutingState ||
+       aState == GraphExecutor::SuspendedSuccessedState ||
+       aState == GraphExecutor::SuspendedErroredState ||
+//       aState == GraphExecutor::SuccessedExecutingState ||
+//       aState == GraphExecutor::ErroredExecutingState ||
+       aState == GraphExecutor::SuccessedState ||
+       aState == GraphExecutor::ErroredState ||
+       aState == GraphExecutor::ResumedSuccessedState ||
+       aState == GraphExecutor::ResumedErroredState ||
+       aState == GraphExecutor::KilledSuccessedState ||
+       aState == GraphExecutor::StoppedSuccessedState )
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
   return aret ;
@@ -880,11 +1144,12 @@ bool GraphExecutor::InNode::IsDone() {
 bool GraphExecutor::InNode::IsSuspended() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::SuspendedReadyState ||
-       aState == SUPERV::SuspendedExecutingState ||
-       aState == SUPERV::SuspendedSuccessedState ||
-       aState == SUPERV::SuspendedErroredState )
+  GraphExecutor::AutomatonState aState = State() ;
+  if ( aState == GraphExecutor::SuspendedReadyState ||
+       aState == GraphExecutor::SuspendedExecutingState ||
+       aState == GraphExecutor::SuspendedSuccessedState ||
+       aState == GraphExecutor::SuspendedErroredState ||
+       aState == GraphExecutor::SuspendedState )
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
   return aret ;
@@ -892,12 +1157,12 @@ bool GraphExecutor::InNode::IsSuspended() {
 bool GraphExecutor::InNode::IsKilled() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::KilledReadyState ||
-       aState == SUPERV::KilledExecutingState ||
-       aState == SUPERV::KilledSuccessedState ||
-       aState == SUPERV::KilledErroredState ||
-       aState == SUPERV::KilledState )
+  GraphExecutor::AutomatonState aState = State() ;
+  if ( aState == GraphExecutor::KilledReadyState ||
+       aState == GraphExecutor::KilledExecutingState ||
+       aState == GraphExecutor::KilledSuccessedState ||
+       aState == GraphExecutor::KilledErroredState ||
+       aState == GraphExecutor::KilledState )
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
   return aret ;
@@ -905,12 +1170,12 @@ bool GraphExecutor::InNode::IsKilled() {
 bool GraphExecutor::InNode::IsStopped() {
   bool aret = false ;
 //  cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
-  SUPERV::AutomatonState aState = State() ;
-  if ( aState == SUPERV::StoppedReadyState ||
-       aState == SUPERV::StoppedExecutingState ||
-       aState == SUPERV::StoppedSuccessedState ||
-       aState == SUPERV::StoppedErroredState ||
-       aState == SUPERV::StoppedState )
+  GraphExecutor::AutomatonState aState = State() ;
+  if ( aState == GraphExecutor::StoppedReadyState ||
+       aState == GraphExecutor::StoppedExecutingState ||
+       aState == GraphExecutor::StoppedSuccessedState ||
+       aState == GraphExecutor::StoppedErroredState ||
+       aState == GraphExecutor::StoppedState )
     aret = true ;
 //  cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
   return aret ;
@@ -947,12 +1212,14 @@ bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
               << " " << Automaton()->StateName( _currentState )
               << " pthread_cond_wait _RunningWait " << Name() << endl ;
     while ( !RetVal && !IsDone() ) {
-      cdebug << pthread_self() << " pthread_cond_wait RunningWait" << endl ;
+      cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
       pthread_cond_wait( &_RunningWait , &_MutexWait );
-      RetVal = IsRunning() ;
+//We may have pthread_cond_waited but !IsRunning and !IsDone :
+      RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
+               State() == GraphExecutor::ErroredExecutingState ;
       cdebug << pthread_self() << " pthread_cond_waited RunningWait "
              << Automaton()->StateName( _currentState ) << " " << RetVal
-             << endl ;
+             << " " << Name() << endl ;
     }
     cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
                << " " << Automaton()->StateName( _currentState )
@@ -996,7 +1263,7 @@ bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
     break ;
   }
   default : {
-    cdebug << " GraphExecutor::OutNode::StateWait Error Undefined State : "
+    cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
            << aState << endl ;
   }
   }
@@ -1016,9 +1283,12 @@ bool GraphExecutor::InNode::ReadyWait() {
 }
 
 bool GraphExecutor::InNode::RunningWait() {
-//  cdebug_in << "GraphExecutor::InNode::RunningWait " << Name() << endl;
+  cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
+            << " " << Automaton()->StateName( State() ) << endl;
   bool aret ;
   aret = StateWait( SUPERV::RunningState ) ;
+  cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
+             << " " << Automaton()->StateName( State() ) << endl;
   return aret ;
 }
 
@@ -1036,23 +1306,30 @@ bool GraphExecutor::InNode::SuspendedWait() {
   return aret ;
 }
 
-void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
+void GraphExecutor::InNode::InitialState()
 {
   cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
 
-  _OutNode = theOutNode ;
-
   int i;
   _ControlState = SUPERV::VoidState ;
   CreateNewThread( false ) ;
   CreateNewThreadIf( false ) ;
   _SuspendSync = false ;
   _ResumeSync = false ;
+
+  // asv : 13.12.04 : "Loading" state is ON (and OFF eventially) only for Computing, Factory, Inline nodes
+  if ( !IsMacroNode() )
+    IsLoading( true ) ;
+
 //  ThreadNo( pthread_self() ) ;
   ThreadNo( 0 ) ;
 
   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
-    if ( i != 0 || !IsGOTONode() ) {
+    if ( GetNodeOutPort(i)->IsDataStream() ) {
+      GetChangeNodeOutPort(i)->State(  SUPERV::ReadyState ) ;
+      GetChangeNodeOutPort(i)->Done( true ) ;
+    }
+    else if ( i != 0 || !IsGOTONode() ) {
       GetChangeNodeOutPort(i)->State(  SUPERV::WaitingState ) ;
       GetChangeNodeOutPort(i)->Done( false ) ;
     }
@@ -1070,36 +1347,65 @@ void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
       *anAny <<= (long ) 1 ;
       anOutPort->Value( anAny ) ;
     }
+// JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
     else if ( anInPort->IsGate() && anOutPort ) {
-      if ( IsComputingNode() || IsFactoryNode() ) {
-        anOutPort->State( SUPERV::WaitingState ) ;
-        anOutPort->Done( false ) ;
-      }
-      else if ( IsOneOfInLineNodes() ) {
+      anOutPort->State( SUPERV::WaitingState ) ;
+      anOutPort->Done( false ) ;
+      const GraphBase::ComputingNode * aFromNode =  _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ; 
+      if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) { // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.  
+                                       // before was "else if ( IsOneOfInlineNodes() )"
+                                      // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
         anOutPort->PortStatus( DataConnected );
         anOutPort->State( SUPERV::ReadyState ) ;
         anOutPort->Done( true ) ;
       }
     }
-//    if ( ( anInPort->IsGate() || anInPort->IsBus() ) && anOutPort == NULL ) {
     if ( anInPort->IsGate() && anOutPort == NULL ) {
       Pc-- ;
+      cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected Pc " << Pc << endl ;
     }
-    else {
-      if ( anOutPort->IsDataConnected() ) {
+    else if ( anOutPort ) {
+      if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
         Pc-- ;
+        anOutPort->State( SUPERV::ReadyState ) ;
+        anOutPort->Done( true ) ;
+        cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
+               << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
       }
-      if ( anOutPort->IsPortConnected() ) {
+      else if ( anOutPort->IsPortConnected() ) {
         anOutPort->State( SUPERV::WaitingState ) ;
         anOutPort->Done( false ) ;
+        cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
+               << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
       }
-      else if ( anOutPort->IsDataConnected() ) {
-        anOutPort->State( SUPERV::ReadyState ) ;
-        anOutPort->Done( true ) ;
+      else {
+        cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
+               << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
+               << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
       }
     }
+    else {
+      cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
+             << " no corresponding OutPort Pc " << Pc << endl ;
+    }
     if ( anOutPort ) {
-      GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
+      if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
+        cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
+               << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
+               << " with state " << theAutomaton->StateName( anOutPort->State() ) << endl ;
+        GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
+      }
+      else if ( anOutPort->IsDataConnected() ) {
+        cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
+               << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
+               << " with state ReadyState" << endl ;
+        GetChangeNodeInPort(i)->State( SUPERV::ReadyState ) ;
+      }
+      else {
+        cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
+               << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
+               << " with state " << anOutPort->State() << endl ;
+      }
     }
     if ( anOutPort ) {
       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
@@ -1118,45 +1424,10 @@ void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
              << anOutPort->IsPortConnected() << ") DataConnected("
              << anOutPort->IsDataConnected() << ")" << endl ;
     }
-
-    if ( !PyFuncRunned() ) {
-      bool Err = false ;
-      if ( IsLoopNode()  ) {
-        PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
-                                                  InLineNode()->PythonFunction() ) ;
-        InLineNode()->PyRunMethod( PyRunMethod ) ;
-        PyObject * PyMoreMethod = NULL ;
-        if ( PyRunMethod ) {
-          PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
-                                          LoopNode()->MorePythonFunction() ) ;
-          LoopNode()->PyMoreMethod( PyMoreMethod ) ;
-        }
-        PyObject * PyNextMethod = NULL ;
-        if ( PyMoreMethod ) {
-          PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
-                                          LoopNode()->NextPythonFunction() ) ;
-          LoopNode()->PyNextMethod( PyNextMethod ) ;
-       }
-        Err = !PyRunMethod || !PyMoreMethod || !PyNextMethod ;
-      }
-      else if ( IsInLineNode() || IsSwitchNode() ) {
-        PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
-                                                  InLineNode()->PythonFunction() ) ;
-        InLineNode()->PyRunMethod( PyRunMethod ) ;
-        Err = !PyRunMethod ;
-      }
-      else if ( ( IsEndSwitchNode() || IsGOTONode() ) &&
-                (*InLineNode()->PythonFunction()).length() ) {
-        PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
-                                                  InLineNode()->PythonFunction() ) ;
-        InLineNode()->PyRunMethod( PyRunMethod ) ;
-        Err = !PyRunMethod ;
-      }
-    }
   }
 
-  _currentState = Pc > 0 ? SUPERV::DataWaitingState 
-                         : SUPERV::DataReadyState ;
+  _currentState = Pc > 0 ? GraphExecutor::DataWaitingState 
+                         : GraphExecutor::DataReadyState ;
   if ( Pc == GetNodeInPortsSize() ) {
     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
                          _currentState ) ; 
@@ -1169,15 +1440,100 @@ void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
                          _currentState ) ; 
   }
+
+  for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
+    cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
+           << theAutomaton->StateName( GetChangeNodeOutPort(i)->State() )
+           << " " << GetNodeOutPort(i)->Kind() << endl ;
+  }
+
   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
          << endl;
 
   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
 }
 
+bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
+  cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
+  bool Err = false ;
+  if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
+    if ( IsLoopNode() ) {
+      PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
+      PyObject * PyMoreMethod = NULL ;
+      PyObject * PyNextMethod = NULL ;
+      if ( PyRunMethod ) {
+      }
+      else {
+        PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
+                                       InLineNode()->PythonFunction() ,
+                                       Err ) ;
+        InLineNode()->PyRunMethod( PyRunMethod ) ;
+      }
+      if ( !Err ) {
+        PyMoreMethod = LoopNode()->PyMoreMethod() ;
+        if ( PyMoreMethod ) {
+        }
+        else {
+          PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
+                                          LoopNode()->MorePythonFunction() ,
+                                          Err ) ;
+          LoopNode()->PyMoreMethod( PyMoreMethod ) ;
+        }
+      }
+      if ( !Err ) {
+        PyNextMethod = LoopNode()->PyNextMethod() ;
+        if ( PyNextMethod ) {
+        }
+        else {
+          PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
+                                          LoopNode()->NextPythonFunction() ,
+                                          Err ) ;
+          LoopNode()->PyNextMethod( PyNextMethod ) ;
+        }
+      }
+      cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
+             << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
+    }
+    else if ( IsInLineNode() || IsSwitchNode() ) {
+      PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
+      if ( PyRunMethod ) {
+      }
+      else {
+       PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
+                                       InLineNode()->PythonFunction() ,
+                                       Err ) ;
+        InLineNode()->PyRunMethod( PyRunMethod ) ;
+      }
+      cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
+    }
+    else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
+              (*InLineNode()->PythonFunction()).length() ) {
+      PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
+      if ( PyRunMethod ) {
+      }
+      else {
+        PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
+                                       InLineNode()->PythonFunction() ,
+                                       Err ) ;
+        InLineNode()->PyRunMethod( PyRunMethod ) ;
+      }
+      cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
+    }
+  }
+  Err = WithErr && Err ;
+  cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
+  if ( Err ) {
+    cdebug << " Error " << Err ;
+  }
+  cdebug << endl;
+  return !Err ;
+}
+
 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
   CORBA::Long cpu = 0 ;
-//  cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
+  cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
+       << theAutomaton->StateName( _currentState ) << endl ;
+  cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
   if ( IsOneOfInLineNodes() ) {
 //    cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
 //    cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
@@ -1192,12 +1548,15 @@ const long GraphExecutor::InNode::CpuUsed( bool tot ) {
       }
       catch ( ... ) {
         cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
+        State( GraphExecutor::ErroredState ) ;
+        _OutNode->State( GraphExecutor::ErroredState ) ;
         cpu = 0 ;
       }
     }
   }
-//  cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
-//  cout << "CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
+  cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
+  cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
+       << theAutomaton->StateName( _currentState ) << endl ;
   return cpu ;
 }
 
@@ -1253,3 +1612,13 @@ void GraphExecutor::InNode::SetPyCpuUsed() {
 //         << _PyCpuUsed << endl ;
 }
 
+void GraphExecutor::InNode::IsLoading( bool Loading ) {
+  _Loading = Loading ;
+  
+  // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works: 
+  // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
+  // after Loading is finished (here below), ExecutingState must be pushed for GUI.  
+  if ( !Loading )
+    _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );
+}
+