Salome HOME
*** empty log message ***
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNode.cxx
1 //  SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : DataFlowExecutor_InNode.cxx
25 //  Author : Jean Rahuel, CEA
26 //  Module : SUPERV
27 //  $Header:
28
29 using namespace std;
30
31 #include <stdlib.h>
32 #include <iostream>
33 #include <unistd.h>
34 #include <stdio.h>
35 #include <errno.h>
36
37 #include "OpUtil.hxx"
38
39 #include <SALOMEconfig.h>
40 #include CORBA_CLIENT_HEADER(SALOME_Component)
41 //#include "SALOME_NamingService.hxx"
42 #include "SALOME_LifeCycleCORBA.hxx"
43
44 #include "DataFlowBase_FactoryNode.hxx"
45 #include "DataFlowBase_GOTONode.hxx"
46 #include "DataFlowBase_LoopNode.hxx"
47 #include "DataFlowBase_EndOfLoopNode.hxx"
48 #include "DataFlowBase_SwitchNode.hxx"
49 #include "DataFlowBase_EndOfSwitchNode.hxx"
50
51 #include "DataFlowExecutor_DataFlow.hxx"
52 #include "DataFlowEditor_DataFlow.hxx"   // GraphEditor package must be built BEFORE
53
54 static void InitInNode( int &_RewindStack ,
55                         SUPERV::ControlState &_ControlState ,
56                         GraphExecutor::AutomatonState &_currentState ,
57                         GraphExecutor::InNode ** _aReStartNode ,
58                         bool & _PyFuncRunned ,
59                         PyObject ** _MyPyRunMethod ,
60                         pthread_mutex_t &_MutexDataWait ,
61                         bool &_DataWait ,
62                         pthread_mutex_t &_MutexWait ,
63                         pthread_cond_t &_ReadyWait ,
64                         pthread_cond_t &_RunningWait ,
65                         pthread_cond_t &_DoneWait ,
66                         pthread_cond_t &_SuspendedWait ,
67                         pthread_cond_t &_SuspendWait ,
68                         bool &_SuspendSync ,
69                         pthread_cond_t &_ResumeWait ,
70                         bool &_ResumeSync ,
71                         pthread_cond_t &_KillWait ,
72                         bool &_KillSync ,
73                         pthread_cond_t &_ThreadStartedWait ,
74                         bool &_ThreadStartedSync ,
75                         pthread_cond_t &_StopWait ,
76                         GraphExecutor::FiniteStateMachine ** _Automaton ,
77                         GraphExecutor::FiniteStateMachine * theAutomaton ,
78                         CORBA::ORB_ptr * _Orb ,
79                         CORBA::ORB_ptr ORB,
80                         bool &_Loading ) {
81   _RewindStack = 0 ;
82   _ControlState = SUPERV::VoidState ;
83   _currentState = GraphExecutor::UnKnownState ;
84   *_aReStartNode = NULL ;
85   _PyFuncRunned = false ;
86   *_MyPyRunMethod = NULL ;
87   pthread_mutex_init( &_MutexDataWait , NULL ) ;
88   _DataWait = false ;
89   pthread_mutex_init( &_MutexWait , NULL ) ;
90   if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
91     perror("pthread_cond_init( &_ReadyWait , NULL )") ;
92     exit( 0 ) ;
93   }
94   if ( pthread_cond_init( &_RunningWait , NULL ) ) {
95     perror("pthread_cond_init( &_RunningWait , NULL )") ;
96     exit( 0 ) ;
97   }
98   if ( pthread_cond_init( &_DoneWait , NULL ) ) {
99     perror("pthread_cond_init( &_DoneWait , NULL )") ;
100     exit( 0 ) ;
101   }
102   if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
103     perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
104     exit( 0 ) ;
105   }
106   if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
107     perror("pthread_cond_init( &_SuspendWait , NULL )") ;
108     exit( 0 ) ;
109   }
110   _SuspendSync = false ;
111   if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
112     perror("pthread_cond_init( &_ResumeWait , NULL )") ;
113     exit( 0 ) ;
114   }
115   _ResumeSync = false ;
116   if ( pthread_cond_init( &_KillWait , NULL ) ) {
117     perror("pthread_cond_init( &_KillWait , NULL )") ;
118     exit( 0 ) ;
119   }
120   _KillSync = false ;
121   if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
122     perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
123     exit( 0 ) ;
124   }
125   _ThreadStartedSync = false ;
126   if ( pthread_cond_init( &_StopWait , NULL ) ) {
127     perror("pthread_cond_init( &_StopWait , NULL )") ;
128     exit( 0 ) ;
129   }
130   *_Automaton = theAutomaton ;
131   *_Orb = CORBA::ORB::_nil();
132   _Loading = false;
133 }
134
135 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
136
137 //GraphExecutor::InNode::InNode() :
138 //     GraphBase::FactoryNode() {
139 GraphExecutor::InNode::InNode() {
140   InitInNode( _RewindStack ,
141               _ControlState ,
142               _currentState ,
143               &_aReStartNode ,
144               _PyFuncRunned ,
145               &_MyPyRunMethod ,
146               _MutexDataWait ,
147               _DataWait ,
148               _MutexWait ,
149               _ReadyWait ,
150               _RunningWait ,
151               _DoneWait ,
152               _SuspendedWait ,
153               _SuspendWait ,
154               _SuspendSync ,
155               _ResumeWait ,
156               _ResumeSync ,
157               _KillWait ,
158               _KillSync ,
159               _ThreadStartedWait ,
160               _ThreadStartedSync ,
161               _StopWait ,
162               &_Automaton ,
163               theAutomaton ,
164               &_Orb ,
165               CORBA::ORB::_nil(),
166               _Loading ) ;
167 }
168
169 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
170                                SALOME_NamingService* ptrNamingService ,
171                                const SALOME_ModuleCatalog::Service& aService ,
172                                const char * ComponentName ,
173                                const char * NodeInterfaceName ,
174                                const char * NodeName ,
175                                const SUPERV::KindOfNode akind ,
176                                GraphBase::ListOfFuncName aFuncName ,
177                                GraphBase::ListOfPythonFunctions aPythonFunction ,
178                                const SUPERV::SDate NodeFirstCreation ,
179                                const SUPERV::SDate NodeLastModification  ,
180                                const char * NodeEditorRelease ,
181                                const char * NodeAuthor ,
182                                const char * NodeComputer ,
183                                const char * NodeComment ,
184                                const bool   GeneratedName ,
185                                const int NodeX ,
186                                const int NodeY ,
187                                int * Graph_prof_debug,
188                                ofstream * Graph_fdebug) {
189 //               ostream * Graph_fdebug = NULL ) :
190 //             GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
191 //                                     ComponentName , NodeInterfaceName ,
192 //                                     NodeName , akind ,
193 //                                     NodeFirstCreation , NodeLastModification  ,
194 //                                     NodeEditorRelease , NodeAuthor ,
195 //                                     NodeComputer , NodeComment , GeneratedName ,
196 //                                     0 , 0 ,
197 //                                     Graph_prof_debug , Graph_fdebug ) {
198   InitInNode( _RewindStack ,
199               _ControlState ,
200               _currentState ,
201               &_aReStartNode ,
202               _PyFuncRunned ,
203               &_MyPyRunMethod ,
204               _MutexDataWait ,
205               _DataWait ,
206               _MutexWait ,
207               _ReadyWait ,
208               _RunningWait ,
209               _DoneWait ,
210               _SuspendedWait ,
211               _SuspendWait ,
212               _SuspendSync ,
213               _ResumeWait ,
214               _ResumeSync ,
215               _KillWait ,
216               _KillSync ,
217               _ThreadStartedWait ,
218               _ThreadStartedSync ,
219               _StopWait ,
220               &_Automaton ,
221               theAutomaton ,
222               &_Orb ,
223               ORB,
224               _Loading ) ;
225   SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
226
227   _ComputingNode = NULL ;
228   _FactoryNode = NULL ;
229   _InLineNode = NULL ;
230   _GOTONode = NULL ;
231   _LoopNode = NULL ;
232   _EndOfLoopNode = NULL ;
233   _SwitchNode = NULL ;
234   _EndOfSwitchNode = NULL ;
235   switch ( akind ) {
236   case SUPERV::ComputingNode : {
237     cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
238     _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
239                                                    aService ,
240                                                    NodeName , akind ,
241                                                    NodeFirstCreation ,
242                                                    NodeLastModification  ,
243                                                    NodeEditorRelease , NodeAuthor ,
244                                                    NodeComment , GeneratedName ,
245                                                    NodeX , NodeY ,
246                                                    Graph_prof_debug , Graph_fdebug ) ;
247     break ;
248   }
249   case SUPERV::FactoryNode : {
250     cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
251     _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
252                                                ComponentName , NodeInterfaceName ,
253                                                NodeName , akind ,
254                                                NodeFirstCreation ,
255                                                NodeLastModification  ,
256                                                NodeEditorRelease , NodeAuthor ,
257                                                NodeComputer , NodeComment ,
258                                                GeneratedName , NodeX , NodeY ,
259                                                Graph_prof_debug , Graph_fdebug ) ;
260     _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
261     break ;
262   }
263   case SUPERV::InLineNode : {
264     cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
265     _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
266                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
267                                              NodeName , akind ,
268                                              NodeFirstCreation , NodeLastModification  ,
269                                              NodeEditorRelease , NodeAuthor ,
270                                              NodeComment , GeneratedName ,
271                                              NodeX , NodeY ,
272                                              Graph_prof_debug , Graph_fdebug ) ;
273     _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
274     break ;
275   }
276   case SUPERV::MacroNode : {
277     cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
278     _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
279 //                                            aFuncName[0].c_str() , *aPythonFunction[0] ,
280                                             NodeName , akind ,
281 //                                            NodeFirstCreation , NodeLastModification  ,
282 //                                            NodeEditorRelease , NodeAuthor ,
283 //                                            NodeComment , GeneratedName ,
284 //                                            NodeX , NodeY ,
285                                             Graph_prof_debug , Graph_fdebug ) ;
286     _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
287     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
288     _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
289     _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
290     break ;
291   }
292   case SUPERV::GOTONode : {
293     cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
294     _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
295                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
296                                          NodeName , akind ,
297                                          NodeFirstCreation , NodeLastModification  ,
298                                          NodeEditorRelease , NodeAuthor ,
299                                          NodeComment , GeneratedName ,
300                                          NodeX , NodeY ,
301                                          Graph_prof_debug , Graph_fdebug ) ;
302     _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
303     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
304     break ;
305   }
306   case SUPERV::LoopNode : {
307     cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
308     _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
309                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
310                                          aFuncName[1].c_str() , *aPythonFunction[1] ,
311                                          aFuncName[2].c_str() , *aPythonFunction[2] ,
312                                          NodeName , akind ,
313                                          NodeFirstCreation , NodeLastModification  ,
314                                          NodeEditorRelease , NodeAuthor ,
315                                          NodeComment , GeneratedName ,
316                                          NodeX , NodeY ,
317                                          Graph_prof_debug , Graph_fdebug ) ;
318     _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
319     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
320     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
321     break ;
322   }
323   case SUPERV::EndLoopNode : {
324     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
325     _EndOfLoopNode = new GraphBase::EndOfLoopNode(
326                                          ORB , ptrNamingService ,
327                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
328                                          NodeName , akind ,
329                                          NodeFirstCreation , NodeLastModification  ,
330                                          NodeEditorRelease , NodeAuthor ,
331                                          NodeComment , GeneratedName ,
332                                          NodeX , NodeY ,
333                                          Graph_prof_debug , Graph_fdebug ) ;
334     _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
335     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
336     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
337     break ;
338   }
339   case SUPERV::SwitchNode : {
340     cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
341     _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
342                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
343                                              NodeName , akind ,
344                                              NodeFirstCreation , NodeLastModification  ,
345                                              NodeEditorRelease , NodeAuthor ,
346                                              NodeComment , GeneratedName ,
347                                              NodeX , NodeY ,
348                                              Graph_prof_debug , Graph_fdebug ) ;
349     _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
350     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
351     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
352     break ;
353   }
354   case SUPERV::EndSwitchNode : {
355     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
356     _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
357                                              ORB , ptrNamingService ,
358                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
359                                              NodeName , akind ,
360                                              NodeFirstCreation , NodeLastModification  ,
361                                              NodeEditorRelease , NodeAuthor ,
362                                              NodeComment , GeneratedName ,
363                                              NodeX , NodeY ,
364                                              Graph_prof_debug , Graph_fdebug ) ;
365     _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
366     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
367     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
368     break ;
369   }
370   case SUPERV::DataFlowGraph : {
371     cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
372   }
373   case SUPERV::DataStreamGraph : {
374     cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
375   }
376   case SUPERV::UnknownNode : {
377     cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
378   }
379   }
380   cdebug << "GraphExecutor::InNode::InNode "  << (void *) this
381          << " _ComputingNode " << (void *) _ComputingNode  ;
382   _ComputingNode->InNode( this ) ;
383 }
384
385 GraphExecutor::InNode::~InNode() {
386 }
387
388 void GraphExecutor::InNode::LockDataWait() {
389   cdebug_in << "GraphExecutor::InNode::LockDataWait " << endl ;
390   if ( pthread_mutex_lock( &_MutexDataWait ) ) {
391     perror("Ready pthread_mutex_lock ") ;
392     exit( 0 ) ;
393   }
394   _DataWait = true ;
395   cdebug_out << "GraphExecutor::InNode::LockDataWait " << endl ;
396 }
397 void GraphExecutor::InNode::UnLockDataWait() {
398   cdebug_in << "GraphExecutor::InNode::UnLockDataWait " << endl ;
399   _DataWait = false ;
400   if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
401     perror("Ready pthread_mutex_unlock ") ;
402     exit( 0 ) ;
403   }
404   cdebug_out << "GraphExecutor::InNode::UnLockDataWait " << endl ;
405 }
406
407 Engines::Component_var GraphExecutor::InNode::Component() const {
408   if ( IsFactoryNode() ) {
409     return _FactoryNode->Component() ;
410   }
411   else {
412     CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
413     CORBA::Object_ptr obj ;
414     try {
415       *anAnyComponent >>= obj ;
416       return Engines::Component::_narrow( obj ) ;
417     }
418     catch( ... ) {
419       cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
420     }
421   }
422   return Engines::Component::_nil() ;
423 }
424
425 Engines::Container_var GraphExecutor::InNode::Container() const {
426   if ( IsFactoryNode() ) {
427     return _FactoryNode->Container() ;
428   }
429   return Engines::Container::_nil() ;
430 }
431
432
433 bool GraphExecutor::InNode::Ping() {
434 //  cdebug_in << "GraphExecutor::InNode::Ping" << endl;
435   bool RetVal ;
436   if ( IsFactoryNode() ) {
437     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
438     if ( RetVal ) {
439       if ( State() != GraphExecutor::SuspendedExecutingState ) {
440         try {
441           _FactoryNode->Component()->ping() ;
442         }
443         catch( ... ) {
444           cdebug << "InNode::Ping() ERROR catched" << endl ;
445           State( GraphExecutor::ErroredState ) ;
446           _OutNode->State( GraphExecutor::ErroredState ) ;
447           RetVal = false ;
448         }
449       }
450       else {
451         RetVal = false ;
452       }
453     }
454   }
455 //  cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
456   return RetVal ;
457 }
458
459 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
460   ThreadNo ( aThread ) ; 
461   if ( aThread )
462     _OutNode->NewThread() ;
463 }
464 void GraphExecutor::InNode::ExitThread() {
465   ThreadNo( 0 ) ;
466   _OutNode->ExitThread() ;
467
468
469 bool GraphExecutor::InNode::Suspend() {
470   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
471             << " " << Automaton()->StateName( State() ) << endl;
472   bool RetVal = false ;
473   if ( IsDone() ) {
474 //If loop we need to suspend also    ControlState( SUPERV::VoidState ) ;
475     ControlState( SUPERV::ToSuspendState ) ;
476     RetVal = true ;
477     if ( _OutNode->IsDone() ) {
478       ControlState( SUPERV::VoidState ) ;
479       RetVal = false ;
480     }
481   }
482   else if ( IsWaiting() || IsReady() ) {
483     ControlState( SUPERV::ToSuspendState ) ;
484     RetVal = true ;
485   }
486   else  if ( IsRunning() ) {
487     ControlState( SUPERV::ToSuspendState ) ;
488     if ( IsFactoryNode() || IsComputingNode() ) {
489 // We have to suspend in the container of that node
490       int TrySuspend = 10 ;
491       while ( TrySuspend ) {
492         if ( !CORBA::is_nil( Component() ) ) {
493 // We can call that component
494           try {
495             RetVal = Component()->Suspend_impl() ;
496           }
497           catch( ... ) {
498             cdebug << "InNode::Suspend() ERROR catched" << endl ;
499             State( GraphExecutor::ErroredState ) ;
500             _OutNode->State( GraphExecutor::ErroredState ) ;
501             RetVal = false ;
502             TrySuspend = 1 ;
503           }
504           cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
505           if ( RetVal ) {
506             if ( IsRunning() ) {
507               cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
508                      << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
509               SendEvent( GraphExecutor::SuspendEvent ) ;
510               cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
511                      << Name() << " --> thread" << ThreadNo() << endl;
512               TrySuspend = 1 ;
513             }
514             else if ( IsDone() ) {
515               ControlState( SUPERV::VoidState ) ;
516               RetVal = false ; // Too late ...
517               TrySuspend = 1 ;
518             }
519             else {
520               cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
521                      << endl ;
522               MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
523               TrySuspend = 1 ;
524             }
525           }
526           else {
527 // Suspend in the Container failed : it is always false if it is a Python Container
528             cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
529                    << endl ;
530             if ( TrySuspend == 1 ) {
531               if ( IsSuspended() ) {
532                 RetVal = true ;
533               }
534               else {
535                 RetVal = false ;
536               }
537             }
538           }
539         }
540         else {
541           cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
542                  << endl ;
543 // Wait for the end of loading of the component
544           while ( IsLoading() ) {
545             sleep( 1 ) ;
546           }
547           if ( TrySuspend == 1 ) {
548             if ( IsSuspended() ) {
549               RetVal = true ;
550             }
551             else {
552               RetVal = false ;
553             }
554           }
555         }
556         TrySuspend -= 1 ;
557         if ( TrySuspend ) {
558           sleep( 1 ) ;
559         }
560       }
561     }
562     else if ( IsMacroNode() ) {
563 // It should be like that but it is not completely implemented
564       GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
565       RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
566       if ( RetVal ) {
567         State( GraphExecutor::SuspendedState ) ;
568       }
569     }
570     else {
571 // Now we can suspend an InLineNode with the handler of the SuperVision Container
572       // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL 
573       State( GraphExecutor::ErroredState ) ;
574       _OutNode->State( GraphExecutor::ErroredState ) ;      RetVal = false;
575       cdebug << "Suspend of InLine nodes is NOT implemented." << endl;
576       MESSAGE( "Suspend of InLine nodes is NOT implemented." );
577       /*   
578       if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
579         perror("Suspend pthread_kill error") ;
580         State( GraphExecutor::ErroredState ) ;
581         _OutNode->State( GraphExecutor::ErroredState ) ;
582         RetVal = false ;
583       }
584       else {
585         RetVal = true ;
586       }
587       if ( RetVal ) {
588         if ( IsRunning() ) {
589           cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
590                  << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
591           SendEvent( GraphExecutor::SuspendEvent ) ;
592           cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
593                  << Name() << " --> thread" << ThreadNo() << endl;
594         }
595         else if ( IsDone() ) {
596           ControlState( SUPERV::VoidState ) ;
597           RetVal = false ; // Too late ...
598         }
599         else {
600           cdebug << "component Suspended and !IsDone and !IsRunning !"
601                  << endl ;
602         }
603       }
604       */
605     }
606   }
607   else {
608     cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
609            << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
610            << " ?" << endl ;
611     RetVal = false ;
612   }
613   cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
614              << Automaton()->StateName( State() ) << endl ;
615   return RetVal ;
616 }
617
618 bool GraphExecutor::InNode::ContainerKill() {
619   cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
620             << ThreadNo() << endl;
621   bool RetVal ;
622   if ( IsFactoryNode() ) {
623     Kill() ;
624     RetVal = Container()->Kill_impl() ;
625   }
626   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
627   return RetVal ;
628 }
629
630 bool GraphExecutor::InNode::Kill() {
631   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
632             << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
633             << " SuspendedThreads " << _OutNode->SuspendedThreads()
634             << " EventQSize " << _OutNode->EventQSize() << endl;
635   bool RetVal ;
636   if ( IsDone() ) {
637     ControlState( SUPERV::ToKillState ) ; // if loop
638     if ( _OutNode->IsDone() ) {
639       ControlState( SUPERV::VoidState ) ;
640     }
641     RetVal = false ;
642   }
643   else {
644     ControlState( SUPERV::ToKillState ) ;
645     if ( IsDone() ) {
646       if ( _OutNode->IsDone() ) {
647         ControlState( SUPERV::VoidState ) ;
648       }
649       RetVal = false ;
650     }
651     else {
652       if ( IsRunning() ) {
653         if ( IsFactoryNode() || IsComputingNode() ) {
654 // We have to suspend in the container of that node
655           int TryKill = 10 ;
656           while ( TryKill ) {
657             if ( !CORBA::is_nil( Component() ) ) {
658 // We can call that component
659               try {
660                 RetVal = Component()->Kill_impl() ;
661               }
662               catch( ... ) {
663                 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
664                 State( GraphExecutor::ErroredState ) ;
665                 _OutNode->State( GraphExecutor::ErroredState ) ;
666                 RetVal = false ;
667                 TryKill = 1 ;
668               }
669               cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
670               if ( RetVal ) {
671                 if ( IsRunning() ) {
672                   cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
673                          << " --> thread" << ThreadNo() << " KillEvent " << endl;
674                   SendEvent( GraphExecutor::KillEvent ) ;
675                   cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
676                          << Name() << " --> thread" << ThreadNo() << endl;
677                   TryKill = 1 ;
678                 }
679                 else if ( IsDone() ) {
680                   ControlState( SUPERV::VoidState ) ;
681                   RetVal = false ; // Too late ...
682                   TryKill = 1 ;
683                 }
684                 else {
685                   cdebug << "Kill component Killed and !IsDone and !IsRunning !"
686                          << endl ;
687                   TryKill = 1 ;
688                 }
689               }
690               else {
691 //  Kill in the Container failed : it is always false if it is a Python Container
692                 cdebug << "InNode::Suspend cannot  Kill component ! Python Component ?"
693                        << endl ;
694                 if ( TryKill == 1 ) {
695                   if ( IsKilled() ) {
696                     RetVal = true ;
697                   }
698                   else {
699                     RetVal = false ;
700                   }
701                 }
702               }
703             }
704             else {
705               cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
706                      << endl ;
707 // Wait for the end of loading of the component
708               while ( IsLoading() ) {
709                 sleep( 1 ) ;
710               }
711               if ( TryKill == 1 ) {
712                 if ( IsKilled() ) {
713                   RetVal = true ;
714                 }
715                 else {
716                   RetVal = false ;
717                 }
718               }
719             }
720             TryKill -= 1 ;
721             if ( TryKill ) {
722               sleep( 1 ) ;
723             }
724           }
725         }
726         else if ( IsMacroNode() ) {
727 // It should be like that but it is not completely implemented
728           GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
729           RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
730           if ( RetVal ) {
731             State( GraphExecutor::KilledState ) ;
732           }
733         }
734         else {
735 //PAL6886
736 // Now we can kill an InLineNode with the handler of the SuperVision Container
737           // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
738           State( GraphExecutor::ErroredState ) ;
739           _OutNode->State( GraphExecutor::ErroredState ) ;
740           RetVal = false ;
741           cdebug << "Kill of InLine nodes is NOT implemented." << endl;
742           MESSAGE( "Kill of InLine nodes is NOT implemented." );
743           /*
744           cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
745                  << _OutNode->MainThreadId() << " :" << endl ;
746           MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
747                  << _OutNode->MainThreadId() << " :" ) ;
748           if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
749 // python signals run only in main thread ...
750             perror("Kill pthread_kill error") ;
751             State( GraphExecutor::ErroredState ) ;
752             _OutNode->State( GraphExecutor::ErroredState ) ;
753             RetVal = false ;
754           }
755           else {
756             cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
757                    << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
758             MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
759                    << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
760             RetVal = true ;
761           }
762           */
763         }
764       }
765       else if ( IsSuspended() ) {
766         cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
767                << " --> thread" << ThreadNo() << " Resume()" << endl;
768         if ( Resume() ) {
769           RetVal = Kill() ;
770         }
771         else {
772           RetVal = false ;
773         }
774       }
775       else if ( IsWaiting() ) {
776         RetVal = false ;
777       }
778       else if ( IsReady() ) {
779         RetVal = true ;
780       }
781       else {
782        cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
783               << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
784               << " ?" << endl ;
785         RetVal = false ;
786       }
787     }
788   }
789   cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
790              << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
791              << " SuspendedThreads " << _OutNode->SuspendedThreads()
792              << " EventQSize " << _OutNode->EventQSize() << endl ;
793   return RetVal ;
794 }
795
796 bool GraphExecutor::InNode::KillDone() {
797   cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
798             << endl;
799   bool RetVal ;
800   if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
801     RetVal = false ;
802   }
803   else {
804     ControlState( SUPERV::ToKillDoneState ) ;
805     if ( IsDone() ) {
806       if ( _OutNode->IsDone() ) {
807         ControlState( SUPERV::VoidState ) ;
808       }
809       RetVal = false ;
810     }
811     else {
812       if ( IsRunning() ) {
813         RetVal = true ;
814       }
815       else if ( IsWaiting() ) {
816         RetVal = true ;
817       }
818       else {
819         cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
820                << endl ;
821         RetVal = false ;
822       }
823     }
824   }
825   cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
826   return RetVal ;
827 }
828
829 bool GraphExecutor::InNode::Stop() {
830   cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
831             << endl;
832   bool RetVal ;
833   if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
834     RetVal = false ;
835   }
836   else {
837     ControlState( SUPERV::ToStopState ) ;
838     if ( IsDone() ) {
839       if ( _OutNode->IsDone() ) {
840         ControlState( SUPERV::VoidState ) ;
841       }
842       RetVal = false ;
843     }
844     else {
845       if ( IsRunning() ) {
846         if ( IsFactoryNode() || IsComputingNode() ) {
847           if ( !CORBA::is_nil( Component() ) ) {
848             try {
849               RetVal = Component()->Stop_impl() ;
850             }
851             catch( ... ) {
852               cdebug << "InNode::Stop() ERROR catched" << endl ;
853               State( GraphExecutor::ErroredState ) ;
854               _OutNode->State( GraphExecutor::ErroredState ) ;
855               RetVal = false ;
856             }
857             if ( RetVal ) {
858               if ( IsRunning() ) {
859                 SendEvent( GraphExecutor::StopEvent ) ;
860               }
861               else if ( IsDone() ) {
862                 ControlState( SUPERV::VoidState ) ;
863                 RetVal = false ; // Too late ...
864               }
865               else {
866                 cdebug << "component Suspended and !IsDone and !IsRunning !"
867                        << endl ;
868               }
869             }
870           }
871           else {
872             cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
873             RetVal = false ;
874           }
875         }
876         else {
877           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
878           RetVal = false ;
879         }
880       }
881       else if ( IsWaiting() ) {
882         RetVal = true ;
883       }
884       else {
885         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
886                << endl ;
887         RetVal = false ;
888       }
889     }
890   }
891   cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
892   return RetVal ;
893 }
894
895 bool GraphExecutor::InNode::SuspendDone() {
896   cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
897             << ThreadNo() << endl;
898   bool RetVal ;
899   if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
900     RetVal = false ;
901   }
902   else {
903     ControlState( SUPERV::ToSuspendDoneState ) ;
904     if ( IsDone() ) {
905       if ( _OutNode->IsDone() ) {
906         ControlState( SUPERV::VoidState ) ;
907       }
908       RetVal = false ;
909     }
910     else {
911       RetVal = true ;
912     }
913   }
914   cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
915   return RetVal ;
916 }
917
918 bool GraphExecutor::InNode::Resume() {
919   cdebug_in << pthread_self() << "/" << ThreadNo()
920             << " GraphExecutor::InNode::Resume " << Name() << " "
921             << Automaton()->StateName( State() ) << endl;
922   bool RetVal = false ;
923   if ( IsSuspended() ) {
924     if ( State() == GraphExecutor::SuspendedReadyState ) {
925       ResumeAction( GraphExecutor::ToResumeEvent ) ;
926       RetVal = true ;
927     }
928     else if ( State() == GraphExecutor::SuspendedExecutingState ) {
929       if ( IsFactoryNode() || IsComputingNode() ) {
930         if ( pthread_mutex_lock( &_MutexWait ) ) {
931           perror("ResumeAction pthread_mutex_lock ") ;
932           exit( 0 ) ;
933         }
934         try {
935           RetVal = Component()->Resume_impl() ;
936           if ( RetVal ) {
937             State( GraphExecutor::ExecutingState ) ;
938           }
939         }
940         catch( ... ) {
941           cdebug << "InNode::Resume() ERROR catched" << endl ;
942           State( GraphExecutor::ErroredState ) ;
943           _OutNode->State( GraphExecutor::ErroredState ) ;
944           RetVal = false ;
945         }
946         if ( pthread_mutex_unlock( &_MutexWait ) ) {
947           perror("ResumeAction pthread_mutex_unlock ") ;
948           exit( 0 ) ;
949         }
950       }
951       else if ( IsMacroNode() ) {
952         cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
953         GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
954         RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
955         if ( RetVal ) {
956           State( GraphExecutor::ExecutingState ) ;
957         }
958       }
959       else {
960 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
961         // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
962         State( GraphExecutor::ErroredState ) ;
963         _OutNode->State( GraphExecutor::ErroredState ) ;
964         RetVal = false ;
965         cdebug << "Resume of InLine nodes is NOT implemented." << endl;
966         MESSAGE( "Resume of InLine nodes is NOT implemented." );
967         /*
968         cdebug << ThreadNo() << "/" << pthread_self()
969                << "Resume of InLineNode pthread_kill" << Name() << endl ;
970         if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
971           perror("Resume pthread_kill error") ;
972           State( GraphExecutor::ErroredState ) ;
973           _OutNode->State( GraphExecutor::ErroredState ) ;
974           RetVal = false ;
975         }
976         else {
977           State( GraphExecutor::ExecutingState ) ;
978           RetVal = true ;
979         }
980         */
981       }
982     }
983     else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
984       ResumeAction( GraphExecutor::ResumeEvent ) ;
985       RetVal = true ;
986     }
987     else if ( State() == GraphExecutor::SuspendedErroredState ) {
988       ResumeAction( GraphExecutor::ResumeEvent ) ;
989       RetVal = true ;
990     }
991     else {
992       cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
993              << Automaton()->StateName( State() ) << endl ;
994       RetVal = false ;
995     }
996   }
997   else {
998     cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
999            << Automaton()->StateName( State() ) << endl ;
1000     RetVal = false ;
1001   }
1002   if ( ControlState() == SUPERV::ToSuspendStartState ) {
1003     ControlState( SUPERV::VoidState ) ;
1004   }
1005
1006 #if 0
1007   if ( ControlState() == SUPERV::ToSuspendRunState ||
1008        ( ControlState() == SUPERV::ToSuspendState &&
1009          State() == GraphExecutor::SuspendedReadyState) ) {
1010     if ( IsSuspended() ) {
1011       if ( State() == GraphExecutor::SuspendedReadyState ) {
1012         ResumeAction() ;
1013         RetVal = true ;
1014       }
1015       else if ( State() == GraphExecutor::SuspendedExecutingState ) {
1016         ResumeAction() ;
1017         RetVal = Component()->Resume_impl() ;
1018       }
1019       else {
1020         cdebug << "GraphExecutor::InNode::Resume State "
1021                << Automaton()->StateName( State() ) << endl ;
1022         RetVal = false ;
1023       }
1024       if ( ControlState() != SUPERV::ToSuspendState ) {
1025         ControlState( SUPERV::VoidState ) ;
1026       }
1027     }
1028     else if ( IsRunning() ) {
1029       RetVal = true ;
1030     }
1031     else if ( IsWaiting() ) {
1032       ControlState( SUPERV::VoidState ) ;
1033       RetVal = true ;
1034     }
1035     else if ( IsDone() ) {
1036       RetVal = true ;
1037     }
1038   }
1039   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1040             ( ControlState() == SUPERV::ToSuspendState &&
1041               State() == GraphExecutor::SuspendedSuccessedState) ) {
1042     if ( IsSuspended() ) {
1043       if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1044         ResumeAction() ;
1045         RetVal = true ;
1046       }
1047       else if ( State() == GraphExecutor::SuspendedErroredState ) {
1048         ResumeAction() ;
1049         RetVal = true ;
1050       }
1051       else {
1052         cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1053         RetVal = false ;
1054       }
1055       if ( ControlState() != SUPERV::ToSuspendState ) {
1056         ControlState( SUPERV::VoidState ) ;
1057       }
1058     }
1059     else if ( IsRunning() ) {
1060       ControlState( SUPERV::VoidState ) ;
1061       RetVal = true ;
1062     }
1063     else if ( IsWaiting() ) {
1064       ControlState( SUPERV::VoidState ) ;
1065       RetVal = true ;
1066     }
1067     else if ( IsDone() ) {
1068       ControlState( SUPERV::VoidState ) ;
1069       RetVal = true ;
1070     }
1071   }
1072 #endif
1073   cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1074              << Automaton()->StateName( State() ) << endl ;
1075   return RetVal ;
1076 }
1077
1078 bool GraphExecutor::InNode::IsWaiting() {
1079   bool aret = false ;
1080 //  cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1081   GraphExecutor::AutomatonState aState = State() ;
1082   if ( aState == GraphExecutor::DataUndefState ||
1083        aState == GraphExecutor::DataWaitingState ||
1084        aState == GraphExecutor::SuspendedReadyState )
1085 //       aState == GraphExecutor::SuspendedExecutingState ||
1086 //       aState == GraphExecutor::SuspendedSuccessedState ||
1087 //       aState == GraphExecutor::SuspendedErroredState ||
1088 //       aState == GraphExecutor::SuspendedState
1089     aret = true ;
1090 //  cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1091   return aret ;
1092 }
1093
1094 bool GraphExecutor::InNode::IsReady() {
1095   bool aret = false ;
1096 //  cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1097   GraphExecutor::AutomatonState aState = State() ;
1098 //  if ( aState == GraphExecutor::DataUndefState ||
1099 //       aState == GraphExecutor::DataWaitingState ||
1100   if ( aState == GraphExecutor::DataReadyState ||
1101        aState == GraphExecutor::ResumedReadyState )
1102     aret = true ;
1103 //  cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1104   return aret ;
1105 }
1106
1107 bool GraphExecutor::InNode::IsRunning() {
1108   bool aret = false ;
1109 //  cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1110   GraphExecutor::AutomatonState aState = State() ;
1111   if ( aState == GraphExecutor::ExecutingState ||
1112        aState == GraphExecutor::ResumedExecutingState )
1113     aret = true ;
1114 //  cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1115   return aret ;
1116 }
1117
1118 bool GraphExecutor::InNode::IsDone() {
1119   bool aret = false ;
1120 //  cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1121   GraphExecutor::AutomatonState aState = State() ;
1122   if ( aState == GraphExecutor::KilledReadyState ||
1123        aState == GraphExecutor::StoppedReadyState ||
1124        aState == GraphExecutor::KilledExecutingState ||
1125        aState == GraphExecutor::StoppedExecutingState ||
1126        aState == GraphExecutor::SuspendedSuccessedState ||
1127        aState == GraphExecutor::SuspendedErroredState ||
1128 //       aState == GraphExecutor::SuccessedExecutingState ||
1129 //       aState == GraphExecutor::ErroredExecutingState ||
1130        aState == GraphExecutor::SuccessedState ||
1131        aState == GraphExecutor::ErroredState ||
1132        aState == GraphExecutor::ResumedSuccessedState ||
1133        aState == GraphExecutor::ResumedErroredState ||
1134        aState == GraphExecutor::KilledSuccessedState ||
1135        aState == GraphExecutor::StoppedSuccessedState )
1136     aret = true ;
1137 //  cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1138   return aret ;
1139 }
1140
1141 bool GraphExecutor::InNode::IsSuspended() {
1142   bool aret = false ;
1143 //  cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1144   GraphExecutor::AutomatonState aState = State() ;
1145   if ( aState == GraphExecutor::SuspendedReadyState ||
1146        aState == GraphExecutor::SuspendedExecutingState ||
1147        aState == GraphExecutor::SuspendedSuccessedState ||
1148        aState == GraphExecutor::SuspendedErroredState ||
1149        aState == GraphExecutor::SuspendedState )
1150     aret = true ;
1151 //  cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1152   return aret ;
1153 }
1154 bool GraphExecutor::InNode::IsKilled() {
1155   bool aret = false ;
1156 //  cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1157   GraphExecutor::AutomatonState aState = State() ;
1158   if ( aState == GraphExecutor::KilledReadyState ||
1159        aState == GraphExecutor::KilledExecutingState ||
1160        aState == GraphExecutor::KilledSuccessedState ||
1161        aState == GraphExecutor::KilledErroredState ||
1162        aState == GraphExecutor::KilledState )
1163     aret = true ;
1164 //  cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1165   return aret ;
1166 }
1167 bool GraphExecutor::InNode::IsStopped() {
1168   bool aret = false ;
1169 //  cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1170   GraphExecutor::AutomatonState aState = State() ;
1171   if ( aState == GraphExecutor::StoppedReadyState ||
1172        aState == GraphExecutor::StoppedExecutingState ||
1173        aState == GraphExecutor::StoppedSuccessedState ||
1174        aState == GraphExecutor::StoppedErroredState ||
1175        aState == GraphExecutor::StoppedState )
1176     aret = true ;
1177 //  cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1178   return aret ;
1179 }
1180
1181 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1182   bool RetVal = false ;
1183   if ( pthread_mutex_lock( &_MutexWait ) ) {
1184     perror("pthread_mutex_lock _Wait") ;
1185     exit( 0 ) ;
1186   }
1187   switch ( aState ) {
1188   case SUPERV::ReadyState : {
1189     RetVal = IsReady() ;
1190     cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1191               << " " << Automaton()->StateName( _currentState )
1192               << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1193     while ( !RetVal && !IsDone() ) {
1194       cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1195       pthread_cond_wait( &_ReadyWait , &_MutexWait );
1196       RetVal = IsReady() ;
1197       cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1198              << Automaton()->StateName( _currentState ) << " " << RetVal
1199              << endl ;
1200     }
1201     cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1202                << " " << Automaton()->StateName( _currentState )
1203                << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1204     break ;
1205   }
1206   case SUPERV::RunningState : {
1207     RetVal = IsRunning() ;
1208     cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1209               << " " << Automaton()->StateName( _currentState )
1210               << " pthread_cond_wait _RunningWait " << Name() << endl ;
1211     while ( !RetVal && !IsDone() ) {
1212       cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1213       pthread_cond_wait( &_RunningWait , &_MutexWait );
1214 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1215       RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1216                State() == GraphExecutor::ErroredExecutingState ;
1217       cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1218              << Automaton()->StateName( _currentState ) << " " << RetVal
1219              << " " << Name() << endl ;
1220     }
1221     cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1222                << " " << Automaton()->StateName( _currentState )
1223                << " pthread_cond_wait _RunningWait " << Name() << endl ;
1224     break ;
1225   }
1226   case SUPERV::DoneState : {
1227     RetVal = IsDone() ;
1228     cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1229               << " " << Automaton()->StateName( _currentState )
1230               << " pthread_cond_wait _DoneWait " << Name() << endl ;
1231     while ( !RetVal ) {
1232       cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1233       pthread_cond_wait( &_DoneWait , &_MutexWait );
1234       RetVal = IsDone() ;
1235       cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1236              << Automaton()->StateName( _currentState ) << " " << RetVal
1237              << endl ;
1238     }
1239     cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1240                << " " << Automaton()->StateName( _currentState )
1241                << " pthread_cond_wait _DoneWait " << Name() << endl ;
1242     break ;
1243   }
1244   case SUPERV::SuspendState : {
1245     RetVal = IsSuspended() ;
1246     cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1247               << " " << Automaton()->StateName( _currentState )
1248               << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1249     while ( !RetVal && !IsDone() ) {
1250       cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1251       pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1252       RetVal = IsSuspended() ;
1253       cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1254              << Automaton()->StateName( _currentState ) << " " << RetVal
1255              << endl ;
1256     }
1257     cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1258                << " " << Automaton()->StateName( _currentState )
1259                << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1260     break ;
1261   }
1262   default : {
1263     cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1264            << aState << endl ;
1265   }
1266   }
1267   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1268     perror("pthread_mutex_lock _Wait") ;
1269     exit( 0 ) ;
1270   }
1271   return RetVal ;
1272 }
1273
1274 bool GraphExecutor::InNode::ReadyWait() {
1275 //  cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1276   bool aret ;
1277   aret = StateWait( SUPERV::ReadyState ) ;
1278 //  cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1279   return aret ;
1280 }
1281
1282 bool GraphExecutor::InNode::RunningWait() {
1283   cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1284             << " " << Automaton()->StateName( State() ) << endl;
1285   bool aret ;
1286   aret = StateWait( SUPERV::RunningState ) ;
1287   cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1288              << " " << Automaton()->StateName( State() ) << endl;
1289   return aret ;
1290 }
1291
1292 bool GraphExecutor::InNode::DoneWait() {
1293 //  cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1294   bool aret ;
1295   aret = StateWait( SUPERV::DoneState ) ;
1296   return aret ;
1297 }
1298
1299 bool GraphExecutor::InNode::SuspendedWait() {
1300 //  cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1301   bool aret ;
1302   aret = StateWait( SUPERV::SuspendState ) ;
1303   return aret ;
1304 }
1305
1306 void GraphExecutor::InNode::InitialState()
1307 {
1308   cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1309
1310   int i;
1311   _ControlState = SUPERV::VoidState ;
1312   CreateNewThread( false ) ;
1313   CreateNewThreadIf( false ) ;
1314   _SuspendSync = false ;
1315   _ResumeSync = false ;
1316   _InitLoop = false ;
1317
1318   // asv : 13.12.04 : Decided to set "Loading" state for factory and computing nodes ONLY.
1319   //                  See extended comment in p.2.19 of "Bugs and Improvements" about IsLoading for InLine.
1320   if ( IsComputingNode() || IsFactoryNode() ) {
1321     IsLoading( true ) ;
1322   }
1323
1324 //  ThreadNo( pthread_self() ) ;
1325   ThreadNo( 0 ) ;
1326
1327   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1328     if ( GetNodeOutPort(i)->IsDataStream() ) {
1329       GetChangeNodeOutPort(i)->PortState(  SUPERV::ReadyState ) ;
1330       GetChangeNodeOutPort(i)->PortDone( true ) ;
1331     }
1332     else if ( i != 0 || !IsGOTONode() ) {
1333       GetChangeNodeOutPort(i)->PortState(  SUPERV::WaitingState ) ;
1334       GetChangeNodeOutPort(i)->PortDone( false ) ;
1335     }
1336   }
1337
1338   int Pc = GetNodeInPortsSize() ;
1339   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1340     const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1341     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1342     if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1343       anOutPort->PortStatus( DataConnected );
1344       anOutPort->PortState( SUPERV::ReadyState ) ;
1345       anOutPort->PortDone( true ) ;
1346 //JR 21.02.2005 Debug Memory leak :      CORBA::Any * anAny = new CORBA::Any() ;
1347       CORBA::Any anAny = CORBA::Any() ;
1348 //JR 21.02.2005 Debug Memory leak :      *anAny <<= (long ) 1 ;
1349       anAny <<= (long ) 1 ;
1350       anOutPort->Value( anAny ) ;
1351       _InitLoop = true ;
1352       cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1353              << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1354              << " InitLoop HeadNode" << endl ;
1355     }
1356 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1357     else if ( anInPort->IsGate() && anOutPort ) {
1358       anOutPort->PortState( SUPERV::WaitingState ) ;
1359       anOutPort->PortDone( false ) ;
1360       const GraphBase::ComputingNode * aFromNode =  _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ; 
1361 //JR      if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) {
1362       if ( aFromNode->IsGOTONode() || ( IsLoopNode() && CoupledNode() == aFromNode ) ) {
1363 // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.  
1364 // before was "else if ( IsOneOfInlineNodes() )"
1365 // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1366         anOutPort->PortStatus( DataConnected );
1367         anOutPort->PortState( SUPERV::ReadyState ) ;
1368         anOutPort->PortDone( true ) ;
1369       }
1370       cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1371              << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1372              << " Gate HeadNode" << endl ;
1373     }
1374     else {
1375       cdebug << Name() << " IsHeadNode " << IsHeadNode() << " InPort" << i << " " << anInPort->PortName()
1376              << " " << anInPort->PortStatus() << endl ;
1377     }
1378     if ( anInPort->IsGate() && anOutPort == NULL ) {
1379       Pc-- ;
1380       cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected Pc " << Pc << endl ;
1381     }
1382     else if ( anOutPort ) {
1383       if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1384         Pc-- ;
1385         anOutPort->PortState( SUPERV::ReadyState ) ;
1386         anOutPort->PortDone( true ) ;
1387         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1388                << " " << theAutomaton->StateName( anOutPort->PortState() ) << " Pc " << Pc << endl ;
1389       }
1390       else if ( anOutPort->IsPortConnected() ) {
1391         anOutPort->PortState( SUPERV::WaitingState ) ;
1392         anOutPort->PortDone( false ) ;
1393         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1394                << " " << theAutomaton->StateName( anOutPort->PortState() ) << " Pc " << Pc << endl ;
1395       }
1396       else {
1397         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1398                << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1399                << theAutomaton->StateName( anOutPort->PortState() ) << " Pc " << Pc << endl ;
1400       }
1401     }
1402     else {
1403       cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1404              << " no corresponding OutPort Pc " << Pc << endl ;
1405     }
1406     if ( anOutPort ) {
1407       if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1408         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1409                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1410                << " with state of OutPort : " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1411         GetChangeNodeInPort(i)->PortState( anOutPort->PortState() ) ;
1412       }
1413       else if ( anOutPort->IsDataConnected() ) {
1414         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1415                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1416                << " with state ReadyState" << endl ;
1417         GetChangeNodeInPort(i)->PortState( SUPERV::ReadyState ) ;
1418       }
1419       else {
1420         cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1421                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1422                << " with state " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1423       }
1424     }
1425     if ( anOutPort ) {
1426       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1427              << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1428              << " with state " ;
1429       if ( anOutPort->PortState() == SUPERV::WaitingState ) {
1430         cdebug << "WaitingState" ;
1431       }
1432       else if ( anOutPort->PortState() == SUPERV::ReadyState ) {
1433         cdebug << "ReadyState" ;
1434       }
1435       else {
1436         cdebug << "???" ;
1437       }
1438       cdebug << " OutPortStatus " << anOutPort->PortStatus() << " State "
1439              << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1440     }
1441   }
1442
1443   _currentState = Pc > 0 ? GraphExecutor::DataWaitingState 
1444                          : GraphExecutor::DataReadyState ;
1445   if ( Pc == GetNodeInPortsSize() ) {
1446     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1447                          _currentState ) ; 
1448   }
1449   else if ( Pc != 0 ) {
1450     _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1451                          _currentState ) ; 
1452   }
1453   else {
1454     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1455                          _currentState ) ; 
1456   }
1457
1458   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1459     cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1460            << theAutomaton->StateName( GetChangeNodeOutPort(i)->PortState() )
1461            << " " << GetNodeOutPort(i)->Kind() << endl ;
1462   }
1463
1464   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1465          << endl;
1466
1467   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1468 }
1469
1470 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1471   cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " WithErr " << WithErr
1472             << " PyFuncRunned() " << PyFuncRunned() << endl;
1473   bool Err = false ;
1474   if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1475     if ( IsLoopNode() ) {
1476       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1477       PyObject * PyMoreMethod = NULL ;
1478       PyObject * PyNextMethod = NULL ;
1479       if ( PyRunMethod ) {
1480       }
1481       else {
1482         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1483                                        InLineNode()->PythonFunction() ,
1484                                        Err ) ;
1485         InLineNode()->PyRunMethod( PyRunMethod ) ;
1486       }
1487       if ( !Err ) {
1488         PyMoreMethod = LoopNode()->PyMoreMethod() ;
1489         if ( PyMoreMethod ) {
1490         }
1491         else {
1492           PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1493                                           LoopNode()->MorePythonFunction() ,
1494                                           Err ) ;
1495           LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1496         }
1497       }
1498       if ( !Err ) {
1499         PyNextMethod = LoopNode()->PyNextMethod() ;
1500         if ( PyNextMethod ) {
1501         }
1502         else {
1503           PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1504                                           LoopNode()->NextPythonFunction() ,
1505                                           Err ) ;
1506           LoopNode()->PyNextMethod( PyNextMethod ) ;
1507         }
1508       }
1509       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1510              << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1511     }
1512     else if ( IsInLineNode() || IsSwitchNode() ) {
1513       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1514       if ( PyRunMethod ) {
1515       }
1516       else {
1517         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1518                                        InLineNode()->PythonFunction() ,
1519                                        Err ) ;
1520         InLineNode()->PyRunMethod( PyRunMethod ) ;
1521       }
1522       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1523     }
1524     else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1525               (*InLineNode()->PythonFunction()).length() ) {
1526       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1527       if ( PyRunMethod ) {
1528       }
1529       else {
1530         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1531                                        InLineNode()->PythonFunction() ,
1532                                        Err ) ;
1533         InLineNode()->PyRunMethod( PyRunMethod ) ;
1534       }
1535       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1536     }
1537   }
1538   Err = WithErr && Err ;
1539   cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1540   if ( Err ) {
1541     cdebug << " Error " << Err ;
1542   }
1543   cdebug << endl;
1544   return !Err ;
1545 }
1546
1547 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1548   CORBA::Long cpu = 0 ;
1549 //  cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1550 //       << theAutomaton->StateName( _currentState ) << endl ;
1551 //  cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1552   if ( IsOneOfInLineNodes() ) {
1553 //    cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1554 //    cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1555     cpu = PyCpuUsed( tot ) ;
1556   }
1557   else {
1558     if ( !CORBA::is_nil( Component() ) ) {
1559 //      cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1560 //      cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1561       try {
1562         cpu = Component()->CpuUsed_impl() ;
1563       }
1564       catch ( ... ) {
1565         cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1566         State( GraphExecutor::ErroredState ) ;
1567         _OutNode->State( GraphExecutor::ErroredState ) ;
1568         cpu = 0 ;
1569       }
1570     }
1571   }
1572 //  cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1573 //  cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1574 //       << theAutomaton->StateName( _currentState ) << endl ;
1575   return cpu ;
1576 }
1577
1578 #include <sys/time.h>
1579 #include <sys/resource.h>
1580 #include <unistd.h>
1581
1582 long GraphExecutor::InNode::PyCpu() {
1583   struct rusage usage ;
1584   long cpu ;
1585   if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1586     perror("GraphExecutor::InNode::PyCpu") ;
1587     return 0 ;
1588   }
1589 //  return usage.ru_utime.__time_t tv_sec ;
1590 //  cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1591 //         << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1592 //         << endl ;
1593   cpu = usage.ru_utime.tv_sec ;
1594   return cpu ;
1595 }
1596
1597 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1598   long cpu ;
1599   if ( _PyTotCpuUsed == -1 ) {
1600     if ( _Pythread == pthread_self() ) {
1601 //      cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1602 //             << " _PyTotCpuUsed " <<  _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1603 //             << _PyCpuUsed << endl ;
1604       cpu = PyCpu() - _PyCpuUsed ;
1605       if ( tot ) {
1606         _PyTotCpuUsed = cpu ;
1607       }
1608     }
1609     else {
1610       cpu = 0 ;
1611     }
1612   }
1613   else {
1614     cpu = _PyTotCpuUsed ;
1615   }
1616 //  cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1617 //         <<  _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1618   return cpu ;
1619 }
1620
1621 void GraphExecutor::InNode::SetPyCpuUsed() {
1622   _PyTotCpuUsed = -1 ;
1623   _PyCpuUsed = 0 ;
1624   _Pythread = pthread_self() ;
1625   _PyCpuUsed = PyCpu() ;
1626 //  cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1627 //         << _PyCpuUsed << endl ;
1628 }
1629
1630 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1631   _Loading = Loading ;
1632   
1633   // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works: 
1634   // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1635   // after Loading is finished (here below), ExecutingState must be pushed for GUI.  
1636   if ( !Loading )
1637     _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );
1638 }
1639