Salome HOME
In case of error in a Container, Kill_impl() ===> Reset of ThreadId
[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   _RewindStack = 0 ;
81   _ControlState = SUPERV::VoidState ;
82   _currentState = GraphExecutor::UnKnownState ;
83   *_aReStartNode = NULL ;
84   _PyFuncRunned = false ;
85   *_MyPyRunMethod = NULL ;
86   pthread_mutex_init( &_MutexDataWait , NULL ) ;
87   _DataWait = false ;
88   pthread_mutex_init( &_MutexWait , NULL ) ;
89   if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
90     perror("pthread_cond_init( &_ReadyWait , NULL )") ;
91     exit( 0 ) ;
92   }
93   if ( pthread_cond_init( &_RunningWait , NULL ) ) {
94     perror("pthread_cond_init( &_RunningWait , NULL )") ;
95     exit( 0 ) ;
96   }
97   if ( pthread_cond_init( &_DoneWait , NULL ) ) {
98     perror("pthread_cond_init( &_DoneWait , NULL )") ;
99     exit( 0 ) ;
100   }
101   if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
102     perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
103     exit( 0 ) ;
104   }
105   if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
106     perror("pthread_cond_init( &_SuspendWait , NULL )") ;
107     exit( 0 ) ;
108   }
109   _SuspendSync = false ;
110   if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
111     perror("pthread_cond_init( &_ResumeWait , NULL )") ;
112     exit( 0 ) ;
113   }
114   _ResumeSync = false ;
115   if ( pthread_cond_init( &_KillWait , NULL ) ) {
116     perror("pthread_cond_init( &_KillWait , NULL )") ;
117     exit( 0 ) ;
118   }
119   _KillSync = false ;
120   if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
121     perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
122     exit( 0 ) ;
123   }
124   _ThreadStartedSync = false ;
125   if ( pthread_cond_init( &_StopWait , NULL ) ) {
126     perror("pthread_cond_init( &_StopWait , NULL )") ;
127     exit( 0 ) ;
128   }
129   *_Automaton = theAutomaton ;
130   *_Orb = CORBA::ORB::_nil();
131 }
132
133 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
134
135 //GraphExecutor::InNode::InNode() :
136 //     GraphBase::FactoryNode() {
137 GraphExecutor::InNode::InNode() {
138   InitInNode( _RewindStack ,
139               _ControlState ,
140               _currentState ,
141               &_aReStartNode ,
142               _PyFuncRunned ,
143               &_MyPyRunMethod ,
144               _MutexDataWait ,
145               _DataWait ,
146               _MutexWait ,
147               _ReadyWait ,
148               _RunningWait ,
149               _DoneWait ,
150               _SuspendedWait ,
151               _SuspendWait ,
152               _SuspendSync ,
153               _ResumeWait ,
154               _ResumeSync ,
155               _KillWait ,
156               _KillSync ,
157               _ThreadStartedWait ,
158               _ThreadStartedSync ,
159               _StopWait ,
160               &_Automaton ,
161               theAutomaton ,
162               &_Orb ,
163               CORBA::ORB::_nil() ) ;
164 }
165
166 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
167                                SALOME_NamingService* ptrNamingService ,
168                                const SALOME_ModuleCatalog::Service& aService ,
169                                const char * ComponentName ,
170                                const char * NodeInterfaceName ,
171                                const char * NodeName ,
172                                const SUPERV::KindOfNode akind ,
173                                GraphBase::ListOfFuncName aFuncName ,
174                                GraphBase::ListOfPythonFunctions aPythonFunction ,
175                                const SUPERV::SDate NodeFirstCreation ,
176                                const SUPERV::SDate NodeLastModification  ,
177                                const char * NodeEditorRelease ,
178                                const char * NodeAuthor ,
179                                const char * NodeComputer ,
180                                const char * NodeComment ,
181                                const bool   GeneratedName ,
182                                const int NodeX ,
183                                const int NodeY ,
184                                int * Graph_prof_debug,
185                                ofstream * Graph_fdebug) {
186 //               ostream * Graph_fdebug = NULL ) :
187 //             GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
188 //                                     ComponentName , NodeInterfaceName ,
189 //                                     NodeName , akind ,
190 //                                     NodeFirstCreation , NodeLastModification  ,
191 //                                     NodeEditorRelease , NodeAuthor ,
192 //                                     NodeComputer , NodeComment , GeneratedName ,
193 //                                     0 , 0 ,
194 //                                     Graph_prof_debug , Graph_fdebug ) {
195   InitInNode( _RewindStack ,
196               _ControlState ,
197               _currentState ,
198               &_aReStartNode ,
199               _PyFuncRunned ,
200               &_MyPyRunMethod ,
201               _MutexDataWait ,
202               _DataWait ,
203               _MutexWait ,
204               _ReadyWait ,
205               _RunningWait ,
206               _DoneWait ,
207               _SuspendedWait ,
208               _SuspendWait ,
209               _SuspendSync ,
210               _ResumeWait ,
211               _ResumeSync ,
212               _KillWait ,
213               _KillSync ,
214               _ThreadStartedWait ,
215               _ThreadStartedSync ,
216               _StopWait ,
217               &_Automaton ,
218               theAutomaton ,
219               &_Orb ,
220               ORB ) ;
221   SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
222
223   _Loading = false ;
224   _ComputingNode = NULL ;
225   _FactoryNode = NULL ;
226   _InLineNode = NULL ;
227   _GOTONode = NULL ;
228   _LoopNode = NULL ;
229   _EndOfLoopNode = NULL ;
230   _SwitchNode = NULL ;
231   _EndOfSwitchNode = NULL ;
232   switch ( akind ) {
233   case SUPERV::ComputingNode : {
234     cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
235     _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
236                                                    aService ,
237                                                    NodeName , akind ,
238                                                    NodeFirstCreation ,
239                                                    NodeLastModification  ,
240                                                    NodeEditorRelease , NodeAuthor ,
241                                                    NodeComment , GeneratedName ,
242                                                    NodeX , NodeY ,
243                                                    Graph_prof_debug , Graph_fdebug ) ;
244     break ;
245   }
246   case SUPERV::FactoryNode : {
247     cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
248     _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
249                                                ComponentName , NodeInterfaceName ,
250                                                NodeName , akind ,
251                                                NodeFirstCreation ,
252                                                NodeLastModification  ,
253                                                NodeEditorRelease , NodeAuthor ,
254                                                NodeComputer , NodeComment ,
255                                                GeneratedName , NodeX , NodeY ,
256                                                Graph_prof_debug , Graph_fdebug ) ;
257     _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
258     break ;
259   }
260   case SUPERV::InLineNode : {
261     cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
262     _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
263                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
264                                              NodeName , akind ,
265                                              NodeFirstCreation , NodeLastModification  ,
266                                              NodeEditorRelease , NodeAuthor ,
267                                              NodeComment , GeneratedName ,
268                                              NodeX , NodeY ,
269                                              Graph_prof_debug , Graph_fdebug ) ;
270     _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
271     break ;
272   }
273   case SUPERV::MacroNode : {
274     cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
275     _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
276 //                                            aFuncName[0].c_str() , *aPythonFunction[0] ,
277                                             NodeName , akind ,
278 //                                            NodeFirstCreation , NodeLastModification  ,
279 //                                            NodeEditorRelease , NodeAuthor ,
280 //                                            NodeComment , GeneratedName ,
281 //                                            NodeX , NodeY ,
282                                             Graph_prof_debug , Graph_fdebug ) ;
283     _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
284     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
285     _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
286     _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
287     break ;
288   }
289   case SUPERV::GOTONode : {
290     cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
291     _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
292                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
293                                          NodeName , akind ,
294                                          NodeFirstCreation , NodeLastModification  ,
295                                          NodeEditorRelease , NodeAuthor ,
296                                          NodeComment , GeneratedName ,
297                                          NodeX , NodeY ,
298                                          Graph_prof_debug , Graph_fdebug ) ;
299     _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
300     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
301     break ;
302   }
303   case SUPERV::LoopNode : {
304     cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
305     _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
306                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
307                                          aFuncName[1].c_str() , *aPythonFunction[1] ,
308                                          aFuncName[2].c_str() , *aPythonFunction[2] ,
309                                          NodeName , akind ,
310                                          NodeFirstCreation , NodeLastModification  ,
311                                          NodeEditorRelease , NodeAuthor ,
312                                          NodeComment , GeneratedName ,
313                                          NodeX , NodeY ,
314                                          Graph_prof_debug , Graph_fdebug ) ;
315     _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
316     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
317     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
318     break ;
319   }
320   case SUPERV::EndLoopNode : {
321     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
322     _EndOfLoopNode = new GraphBase::EndOfLoopNode(
323                                          ORB , ptrNamingService ,
324                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
325                                          NodeName , akind ,
326                                          NodeFirstCreation , NodeLastModification  ,
327                                          NodeEditorRelease , NodeAuthor ,
328                                          NodeComment , GeneratedName ,
329                                          NodeX , NodeY ,
330                                          Graph_prof_debug , Graph_fdebug ) ;
331     _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
332     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
333     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
334     break ;
335   }
336   case SUPERV::SwitchNode : {
337     cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
338     _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
339                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
340                                              NodeName , akind ,
341                                              NodeFirstCreation , NodeLastModification  ,
342                                              NodeEditorRelease , NodeAuthor ,
343                                              NodeComment , GeneratedName ,
344                                              NodeX , NodeY ,
345                                              Graph_prof_debug , Graph_fdebug ) ;
346     _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
347     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
348     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
349     break ;
350   }
351   case SUPERV::EndSwitchNode : {
352     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
353     _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
354                                              ORB , ptrNamingService ,
355                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
356                                              NodeName , akind ,
357                                              NodeFirstCreation , NodeLastModification  ,
358                                              NodeEditorRelease , NodeAuthor ,
359                                              NodeComment , GeneratedName ,
360                                              NodeX , NodeY ,
361                                              Graph_prof_debug , Graph_fdebug ) ;
362     _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
363     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
364     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
365     break ;
366   }
367   case SUPERV::DataFlowGraph : {
368     cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
369   }
370   case SUPERV::DataStreamGraph : {
371     cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
372   }
373   case SUPERV::UnknownNode : {
374     cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
375   }
376   }
377   cdebug << "GraphExecutor::InNode::InNode "  << (void *) this
378          << " _ComputingNode " << (void *) _ComputingNode  ;
379   _ComputingNode->InNode( this ) ;
380 }
381
382 GraphExecutor::InNode::~InNode() {
383 }
384
385 void GraphExecutor::InNode::LockDataWait() {
386   if ( pthread_mutex_lock( &_MutexDataWait ) ) {
387     perror("Ready pthread_mutex_lock ") ;
388     exit( 0 ) ;
389   }
390   _DataWait = true ;
391 }
392 void GraphExecutor::InNode::UnLockDataWait() {
393   _DataWait = false ;
394   if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
395     perror("Ready pthread_mutex_unlock ") ;
396     exit( 0 ) ;
397   }
398 }
399
400 Engines::Component_var GraphExecutor::InNode::Component() const {
401   if ( IsFactoryNode() ) {
402     return _FactoryNode->Component() ;
403   }
404   else {
405     CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
406     CORBA::Object_ptr obj ;
407     try {
408       *anAnyComponent >>= obj ;
409       return Engines::Component::_narrow( obj ) ;
410     }
411     catch( ... ) {
412       cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
413     }
414   }
415   return Engines::Component::_nil() ;
416 }
417
418 Engines::Container_var GraphExecutor::InNode::Container() const {
419   if ( IsFactoryNode() ) {
420     return _FactoryNode->Container() ;
421   }
422   return Engines::Container::_nil() ;
423 }
424
425
426 bool GraphExecutor::InNode::Ping() {
427 //  cdebug_in << "GraphExecutor::InNode::Ping" << endl;
428   bool RetVal ;
429   if ( IsFactoryNode() ) {
430     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
431     if ( RetVal ) {
432       if ( State() != GraphExecutor::SuspendedExecutingState ) {
433         try {
434           _FactoryNode->Component()->ping() ;
435         }
436         catch( ... ) {
437           cdebug << "InNode::Ping() ERROR catched" << endl ;
438           State( GraphExecutor::ErroredState ) ;
439           _OutNode->State( GraphExecutor::ErroredState ) ;
440           RetVal = false ;
441         }
442       }
443       else {
444         RetVal = false ;
445       }
446     }
447   }
448 //  cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
449   return RetVal ;
450 }
451
452 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
453   ThreadNo ( aThread ) ; 
454   if ( aThread )
455     _OutNode->NewThread() ;
456 }
457 void GraphExecutor::InNode::ExitThread() {
458   ThreadNo( 0 ) ;
459   _OutNode->ExitThread() ;
460
461
462 bool GraphExecutor::InNode::Suspend() {
463   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
464             << " " << Automaton()->StateName( State() ) << endl;
465   bool RetVal = false ;
466   if ( IsDone() ) {
467 //If loop we need to suspend also    ControlState( SUPERV::VoidState ) ;
468     ControlState( SUPERV::ToSuspendState ) ;
469     RetVal = true ;
470     if ( _OutNode->IsDone() ) {
471       ControlState( SUPERV::VoidState ) ;
472       RetVal = false ;
473     }
474   }
475   else if ( IsWaiting() || IsReady() ) {
476     ControlState( SUPERV::ToSuspendState ) ;
477     RetVal = true ;
478   }
479   else  if ( IsRunning() ) {
480     ControlState( SUPERV::ToSuspendState ) ;
481     if ( IsFactoryNode() || IsComputingNode() ) {
482 // We have to suspend in the container of that node
483       int TrySuspend = 10 ;
484       while ( TrySuspend ) {
485         if ( !CORBA::is_nil( Component() ) ) {
486 // We can call that component
487           try {
488             RetVal = Component()->Suspend_impl() ;
489           }
490           catch( ... ) {
491             cdebug << "InNode::Suspend() ERROR catched" << endl ;
492             State( GraphExecutor::ErroredState ) ;
493             _OutNode->State( GraphExecutor::ErroredState ) ;
494             RetVal = false ;
495             TrySuspend = 1 ;
496           }
497           cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
498           if ( RetVal ) {
499             if ( IsRunning() ) {
500               cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
501                      << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
502               SendEvent( GraphExecutor::SuspendEvent ) ;
503               cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
504                      << Name() << " --> thread" << ThreadNo() << endl;
505               TrySuspend = 1 ;
506             }
507             else if ( IsDone() ) {
508               ControlState( SUPERV::VoidState ) ;
509               RetVal = false ; // Too late ...
510               TrySuspend = 1 ;
511             }
512             else {
513               cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
514                      << endl ;
515               MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
516               TrySuspend = 1 ;
517             }
518           }
519           else {
520 // Suspend in the Container failed : it is always false if it is a Python Container
521             cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
522                    << endl ;
523             if ( TrySuspend == 1 ) {
524               if ( IsSuspended() ) {
525                 RetVal = true ;
526               }
527               else {
528                 RetVal = false ;
529               }
530             }
531           }
532         }
533         else {
534           cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
535                  << endl ;
536 // Wait for the end of loading of the component
537           while ( IsLoading() ) {
538             sleep( 1 ) ;
539           }
540           if ( TrySuspend == 1 ) {
541             if ( IsSuspended() ) {
542               RetVal = true ;
543             }
544             else {
545               RetVal = false ;
546             }
547           }
548         }
549         TrySuspend -= 1 ;
550         if ( TrySuspend ) {
551           sleep( 1 ) ;
552         }
553       }
554     }
555     else if ( IsMacroNode() ) {
556 // It should be like that but it is not completely implemented
557       GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
558       RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
559       if ( RetVal ) {
560         State( GraphExecutor::SuspendedState ) ;
561       }
562     }
563     else {
564 // Now we can suspend an InLineNode with the handler of the SuperVision Container
565       if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
566         perror("Suspend pthread_kill error") ;
567         State( GraphExecutor::ErroredState ) ;
568         _OutNode->State( GraphExecutor::ErroredState ) ;
569         RetVal = false ;
570       }
571       else {
572         RetVal = true ;
573       }
574       if ( RetVal ) {
575         if ( IsRunning() ) {
576           cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
577                  << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
578           SendEvent( GraphExecutor::SuspendEvent ) ;
579           cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
580                  << Name() << " --> thread" << ThreadNo() << endl;
581         }
582         else if ( IsDone() ) {
583           ControlState( SUPERV::VoidState ) ;
584           RetVal = false ; // Too late ...
585         }
586         else {
587           cdebug << "component Suspended and !IsDone and !IsRunning !"
588                  << endl ;
589         }
590       }
591     }
592   }
593   else {
594     cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
595            << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
596            << " ?" << endl ;
597     RetVal = false ;
598   }
599   cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
600              << Automaton()->StateName( State() ) << endl ;
601   return RetVal ;
602 }
603
604 bool GraphExecutor::InNode::ContainerKill() {
605   cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
606             << ThreadNo() << endl;
607   bool RetVal ;
608   if ( IsFactoryNode() ) {
609     Kill() ;
610     RetVal = Container()->Kill_impl() ;
611   }
612   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
613   return RetVal ;
614 }
615
616 bool GraphExecutor::InNode::Kill() {
617   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
618             << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
619             << " SuspendedThreads " << _OutNode->SuspendedThreads()
620             << " EventQSize " << _OutNode->EventQSize() << endl;
621   bool RetVal ;
622   if ( IsDone() ) {
623     ControlState( SUPERV::ToKillState ) ; // if loop
624     if ( _OutNode->IsDone() ) {
625       ControlState( SUPERV::VoidState ) ;
626     }
627     RetVal = false ;
628   }
629   else {
630     ControlState( SUPERV::ToKillState ) ;
631     if ( IsDone() ) {
632       if ( _OutNode->IsDone() ) {
633         ControlState( SUPERV::VoidState ) ;
634       }
635       RetVal = false ;
636     }
637     else {
638       if ( IsRunning() ) {
639         if ( IsFactoryNode() || IsComputingNode() ) {
640 // We have to suspend in the container of that node
641           int TryKill = 10 ;
642           while ( TryKill ) {
643             if ( !CORBA::is_nil( Component() ) ) {
644 // We can call that component
645               try {
646                 RetVal = Component()->Kill_impl() ;
647               }
648               catch( ... ) {
649                 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
650                 State( GraphExecutor::ErroredState ) ;
651                 _OutNode->State( GraphExecutor::ErroredState ) ;
652                 RetVal = false ;
653                 TryKill = 1 ;
654               }
655               cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
656               if ( RetVal ) {
657                 if ( IsRunning() ) {
658                   cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
659                          << " --> thread" << ThreadNo() << " KillEvent " << endl;
660                   SendEvent( GraphExecutor::KillEvent ) ;
661                   cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
662                          << Name() << " --> thread" << ThreadNo() << endl;
663                   TryKill = 1 ;
664                 }
665                 else if ( IsDone() ) {
666                   ControlState( SUPERV::VoidState ) ;
667                   RetVal = false ; // Too late ...
668                   TryKill = 1 ;
669                 }
670                 else {
671                   cdebug << "Kill component Killed and !IsDone and !IsRunning !"
672                          << endl ;
673                   TryKill = 1 ;
674                 }
675               }
676               else {
677 //  Kill in the Container failed : it is always false if it is a Python Container
678                 cdebug << "InNode::Suspend cannot  Kill component ! Python Component ?"
679                        << endl ;
680                 if ( TryKill == 1 ) {
681                   if ( IsKilled() ) {
682                     RetVal = true ;
683                   }
684                   else {
685                     RetVal = false ;
686                   }
687                 }
688               }
689             }
690             else {
691               cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
692                      << endl ;
693 // Wait for the end of loading of the component
694               while ( IsLoading() ) {
695                 sleep( 1 ) ;
696               }
697               if ( TryKill == 1 ) {
698                 if ( IsKilled() ) {
699                   RetVal = true ;
700                 }
701                 else {
702                   RetVal = false ;
703                 }
704               }
705             }
706             TryKill -= 1 ;
707             if ( TryKill ) {
708               sleep( 1 ) ;
709             }
710           }
711         }
712         else if ( IsMacroNode() ) {
713 // It should be like that but it is not completely implemented
714           GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
715           RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
716           if ( RetVal ) {
717             State( GraphExecutor::KilledState ) ;
718           }
719         }
720         else {
721 //PAL6886
722 // Now we can kill an InLineNode with the handler of the SuperVision Container
723           cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
724                  << _OutNode->MainThreadId() << " :" << endl ;
725           MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
726                  << _OutNode->MainThreadId() << " :" ) ;
727           if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
728 // python signals run only in main thread ...
729             perror("Kill pthread_kill error") ;
730             State( GraphExecutor::ErroredState ) ;
731             _OutNode->State( GraphExecutor::ErroredState ) ;
732             RetVal = false ;
733           }
734           else {
735             cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
736                    << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
737             MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
738                    << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
739             RetVal = true ;
740           }
741         }
742       }
743       else if ( IsSuspended() ) {
744         cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
745                << " --> thread" << ThreadNo() << " Resume()" << endl;
746         if ( Resume() ) {
747           RetVal = Kill() ;
748         }
749         else {
750           RetVal = false ;
751         }
752       }
753       else if ( IsWaiting() ) {
754         RetVal = false ;
755       }
756       else if ( IsReady() ) {
757         RetVal = true ;
758       }
759       else {
760        cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
761               << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
762               << " ?" << endl ;
763         RetVal = false ;
764       }
765     }
766   }
767   cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
768              << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
769              << " SuspendedThreads " << _OutNode->SuspendedThreads()
770              << " EventQSize " << _OutNode->EventQSize() << endl ;
771   return RetVal ;
772 }
773
774 bool GraphExecutor::InNode::KillDone() {
775   cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
776             << endl;
777   bool RetVal ;
778   if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
779     RetVal = false ;
780   }
781   else {
782     ControlState( SUPERV::ToKillDoneState ) ;
783     if ( IsDone() ) {
784       if ( _OutNode->IsDone() ) {
785         ControlState( SUPERV::VoidState ) ;
786       }
787       RetVal = false ;
788     }
789     else {
790       if ( IsRunning() ) {
791         RetVal = true ;
792       }
793       else if ( IsWaiting() ) {
794         RetVal = true ;
795       }
796       else {
797         cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
798                << endl ;
799         RetVal = false ;
800       }
801     }
802   }
803   cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
804   return RetVal ;
805 }
806
807 bool GraphExecutor::InNode::Stop() {
808   cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
809             << endl;
810   bool RetVal ;
811   if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
812     RetVal = false ;
813   }
814   else {
815     ControlState( SUPERV::ToStopState ) ;
816     if ( IsDone() ) {
817       if ( _OutNode->IsDone() ) {
818         ControlState( SUPERV::VoidState ) ;
819       }
820       RetVal = false ;
821     }
822     else {
823       if ( IsRunning() ) {
824         if ( IsFactoryNode() || IsComputingNode() ) {
825           if ( !CORBA::is_nil( Component() ) ) {
826             try {
827               RetVal = Component()->Stop_impl() ;
828             }
829             catch( ... ) {
830               cdebug << "InNode::Stop() ERROR catched" << endl ;
831               State( GraphExecutor::ErroredState ) ;
832               _OutNode->State( GraphExecutor::ErroredState ) ;
833               RetVal = false ;
834             }
835             if ( RetVal ) {
836               if ( IsRunning() ) {
837                 SendEvent( GraphExecutor::StopEvent ) ;
838               }
839               else if ( IsDone() ) {
840                 ControlState( SUPERV::VoidState ) ;
841                 RetVal = false ; // Too late ...
842               }
843               else {
844                 cdebug << "component Suspended and !IsDone and !IsRunning !"
845                        << endl ;
846               }
847             }
848           }
849           else {
850             cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
851             RetVal = false ;
852           }
853         }
854         else {
855           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
856           RetVal = false ;
857         }
858       }
859       else if ( IsWaiting() ) {
860         RetVal = true ;
861       }
862       else {
863         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
864                << endl ;
865         RetVal = false ;
866       }
867     }
868   }
869   cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
870   return RetVal ;
871 }
872
873 bool GraphExecutor::InNode::SuspendDone() {
874   cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
875             << ThreadNo() << endl;
876   bool RetVal ;
877   if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
878     RetVal = false ;
879   }
880   else {
881     ControlState( SUPERV::ToSuspendDoneState ) ;
882     if ( IsDone() ) {
883       if ( _OutNode->IsDone() ) {
884         ControlState( SUPERV::VoidState ) ;
885       }
886       RetVal = false ;
887     }
888     else {
889       RetVal = true ;
890     }
891   }
892   cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
893   return RetVal ;
894 }
895
896 bool GraphExecutor::InNode::Resume() {
897   cdebug_in << pthread_self() << "/" << ThreadNo()
898             << " GraphExecutor::InNode::Resume " << Name() << " "
899             << Automaton()->StateName( State() ) << endl;
900   bool RetVal = false ;
901   if ( IsSuspended() ) {
902     if ( State() == GraphExecutor::SuspendedReadyState ) {
903       ResumeAction( GraphExecutor::ToResumeEvent ) ;
904       RetVal = true ;
905     }
906     else if ( State() == GraphExecutor::SuspendedExecutingState ) {
907       if ( IsFactoryNode() || IsComputingNode() ) {
908         if ( pthread_mutex_lock( &_MutexWait ) ) {
909           perror("ResumeAction pthread_mutex_lock ") ;
910           exit( 0 ) ;
911         }
912         try {
913           RetVal = Component()->Resume_impl() ;
914           if ( RetVal ) {
915             State( GraphExecutor::ExecutingState ) ;
916           }
917         }
918         catch( ... ) {
919           cdebug << "InNode::Resume() ERROR catched" << endl ;
920           State( GraphExecutor::ErroredState ) ;
921           _OutNode->State( GraphExecutor::ErroredState ) ;
922           RetVal = false ;
923         }
924         if ( pthread_mutex_unlock( &_MutexWait ) ) {
925           perror("ResumeAction pthread_mutex_unlock ") ;
926           exit( 0 ) ;
927         }
928       }
929       else if ( IsMacroNode() ) {
930         cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
931         GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
932         RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
933         if ( RetVal ) {
934           State( GraphExecutor::ExecutingState ) ;
935         }
936       }
937       else {
938 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
939         cdebug << ThreadNo() << "/" << pthread_self()
940                << "Resume of InLineNode pthread_kill" << Name() << endl ;
941         if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
942           perror("Resume pthread_kill error") ;
943           State( GraphExecutor::ErroredState ) ;
944           _OutNode->State( GraphExecutor::ErroredState ) ;
945           RetVal = false ;
946         }
947         else {
948           State( GraphExecutor::ExecutingState ) ;
949           RetVal = true ;
950         }
951       }
952     }
953     else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
954       ResumeAction( GraphExecutor::ResumeEvent ) ;
955       RetVal = true ;
956     }
957     else if ( State() == GraphExecutor::SuspendedErroredState ) {
958       ResumeAction( GraphExecutor::ResumeEvent ) ;
959       RetVal = true ;
960     }
961     else {
962       cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
963              << Automaton()->StateName( State() ) << endl ;
964       RetVal = false ;
965     }
966   }
967   else {
968     cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
969            << Automaton()->StateName( State() ) << endl ;
970     RetVal = false ;
971   }
972   if ( ControlState() == SUPERV::ToSuspendStartState ) {
973     ControlState( SUPERV::VoidState ) ;
974   }
975
976 #if 0
977   if ( ControlState() == SUPERV::ToSuspendRunState ||
978        ( ControlState() == SUPERV::ToSuspendState &&
979          State() == GraphExecutor::SuspendedReadyState) ) {
980     if ( IsSuspended() ) {
981       if ( State() == GraphExecutor::SuspendedReadyState ) {
982         ResumeAction() ;
983         RetVal = true ;
984       }
985       else if ( State() == GraphExecutor::SuspendedExecutingState ) {
986         ResumeAction() ;
987         RetVal = Component()->Resume_impl() ;
988       }
989       else {
990         cdebug << "GraphExecutor::InNode::Resume State "
991                << Automaton()->StateName( State() ) << endl ;
992         RetVal = false ;
993       }
994       if ( ControlState() != SUPERV::ToSuspendState ) {
995         ControlState( SUPERV::VoidState ) ;
996       }
997     }
998     else if ( IsRunning() ) {
999       RetVal = true ;
1000     }
1001     else if ( IsWaiting() ) {
1002       ControlState( SUPERV::VoidState ) ;
1003       RetVal = true ;
1004     }
1005     else if ( IsDone() ) {
1006       RetVal = true ;
1007     }
1008   }
1009   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1010             ( ControlState() == SUPERV::ToSuspendState &&
1011               State() == GraphExecutor::SuspendedSuccessedState) ) {
1012     if ( IsSuspended() ) {
1013       if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1014         ResumeAction() ;
1015         RetVal = true ;
1016       }
1017       else if ( State() == GraphExecutor::SuspendedErroredState ) {
1018         ResumeAction() ;
1019         RetVal = true ;
1020       }
1021       else {
1022         cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1023         RetVal = false ;
1024       }
1025       if ( ControlState() != SUPERV::ToSuspendState ) {
1026         ControlState( SUPERV::VoidState ) ;
1027       }
1028     }
1029     else if ( IsRunning() ) {
1030       ControlState( SUPERV::VoidState ) ;
1031       RetVal = true ;
1032     }
1033     else if ( IsWaiting() ) {
1034       ControlState( SUPERV::VoidState ) ;
1035       RetVal = true ;
1036     }
1037     else if ( IsDone() ) {
1038       ControlState( SUPERV::VoidState ) ;
1039       RetVal = true ;
1040     }
1041   }
1042 #endif
1043   cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1044              << Automaton()->StateName( State() ) << endl ;
1045   return RetVal ;
1046 }
1047
1048 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
1049                                      const bool AndSuspend ) {
1050   bool RetVal = false ;
1051   GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetGraphNode( AtNodeName )->GetInNode() ;
1052   cdebug_in << pthread_self() << "/" << ThreadNo()
1053             << " --> GraphExecutor::InNode::ReStartAt( "
1054             << AtNodeName << " , " << AndSuspend << ") " << endl
1055             << "thread " << aRestartNode->ThreadNo() << " "
1056             << Automaton()->StateName( aRestartNode->State() )
1057             << " from " << Name() << " " << Automaton()->StateName( State() )
1058             << endl ;
1059   if ( IsWaiting() && aRestartNode->IsSuspended() ) {
1060     RetVal = aRestartNode->Resume() ;
1061   }
1062   else if ( IsSuspended() ) {
1063     if ( strcmp( AtNodeName , Name() ) ) {
1064       aRestartNode->State( GraphExecutor::SuspendedSuccessedState ) ;
1065     }
1066     if ( AndSuspend ) {
1067       ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
1068     }
1069     else {
1070       ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
1071     }
1072     RetVal = true ;
1073   }
1074   cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << 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   IsLoading( true ) ;
1317 //  ThreadNo( pthread_self() ) ;
1318   ThreadNo( 0 ) ;
1319
1320   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1321     if ( GetNodeOutPort(i)->IsDataStream() ) {
1322       GetChangeNodeOutPort(i)->State(  SUPERV::ReadyState ) ;
1323       GetChangeNodeOutPort(i)->Done( true ) ;
1324     }
1325     else if ( i != 0 || !IsGOTONode() ) {
1326       GetChangeNodeOutPort(i)->State(  SUPERV::WaitingState ) ;
1327       GetChangeNodeOutPort(i)->Done( false ) ;
1328     }
1329   }
1330
1331   int Pc = GetNodeInPortsSize() ;
1332   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1333     const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1334     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1335     if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1336       anOutPort->PortStatus( DataConnected );
1337       anOutPort->State( SUPERV::ReadyState ) ;
1338       anOutPort->Done( true ) ;
1339       CORBA::Any * anAny = new CORBA::Any() ;
1340       *anAny <<= (long ) 1 ;
1341       anOutPort->Value( anAny ) ;
1342     }
1343 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1344     else if ( anInPort->IsGate() && anOutPort ) {
1345       anOutPort->State( SUPERV::WaitingState ) ;
1346       anOutPort->Done( false ) ;
1347       const GraphBase::ComputingNode * aFromNode =  _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ; 
1348       if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) { // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.  
1349                                        // before was "else if ( IsOneOfInlineNodes() )"
1350                                        // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1351         anOutPort->PortStatus( DataConnected );
1352         anOutPort->State( SUPERV::ReadyState ) ;
1353         anOutPort->Done( true ) ;
1354       }
1355     }
1356     if ( anInPort->IsGate() && anOutPort == NULL ) {
1357       Pc-- ;
1358       cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected Pc " << Pc << endl ;
1359     }
1360     else if ( anOutPort ) {
1361       if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1362         Pc-- ;
1363         anOutPort->State( SUPERV::ReadyState ) ;
1364         anOutPort->Done( true ) ;
1365         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1366                << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1367       }
1368       else if ( anOutPort->IsPortConnected() ) {
1369         anOutPort->State( SUPERV::WaitingState ) ;
1370         anOutPort->Done( false ) ;
1371         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1372                << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1373       }
1374       else {
1375         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1376                << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1377                << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1378       }
1379     }
1380     else {
1381       cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1382              << " no corresponding OutPort Pc " << Pc << endl ;
1383     }
1384     if ( anOutPort ) {
1385       if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1386         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1387                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1388                << " with state " << theAutomaton->StateName( anOutPort->State() ) << endl ;
1389         GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1390       }
1391       else if ( anOutPort->IsDataConnected() ) {
1392         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1393                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1394                << " with state ReadyState" << endl ;
1395         GetChangeNodeInPort(i)->State( SUPERV::ReadyState ) ;
1396       }
1397       else {
1398         cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1399                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1400                << " with state " << anOutPort->State() << endl ;
1401       }
1402     }
1403     if ( anOutPort ) {
1404       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1405              << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1406              << " with state " ;
1407       if ( anOutPort->State() == SUPERV::WaitingState ) {
1408         cdebug << "WaitingState" ;
1409       }
1410       else if ( anOutPort->State() == SUPERV::ReadyState ) {
1411         cdebug << "ReadyState" ;
1412       }
1413       else {
1414         cdebug << "???" ;
1415       }
1416       cdebug << " PortConnected("
1417              << anOutPort->IsPortConnected() << ") DataConnected("
1418              << anOutPort->IsDataConnected() << ")" << endl ;
1419     }
1420   }
1421
1422   _currentState = Pc > 0 ? GraphExecutor::DataWaitingState 
1423                          : GraphExecutor::DataReadyState ;
1424   if ( Pc == GetNodeInPortsSize() ) {
1425     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1426                          _currentState ) ; 
1427   }
1428   else if ( Pc != 0 ) {
1429     _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1430                          _currentState ) ; 
1431   }
1432   else {
1433     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1434                          _currentState ) ; 
1435   }
1436
1437   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1438     cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1439            << theAutomaton->StateName( GetChangeNodeOutPort(i)->State() )
1440            << " " << GetNodeOutPort(i)->Kind() << endl ;
1441   }
1442
1443   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1444          << endl;
1445
1446   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1447 }
1448
1449 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1450   cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
1451   bool Err = false ;
1452   if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1453     if ( IsLoopNode() ) {
1454       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1455       PyObject * PyMoreMethod = NULL ;
1456       PyObject * PyNextMethod = NULL ;
1457       if ( PyRunMethod ) {
1458       }
1459       else {
1460         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1461                                        InLineNode()->PythonFunction() ,
1462                                        Err ) ;
1463         InLineNode()->PyRunMethod( PyRunMethod ) ;
1464       }
1465       if ( !Err ) {
1466         PyMoreMethod = LoopNode()->PyMoreMethod() ;
1467         if ( PyMoreMethod ) {
1468         }
1469         else {
1470           PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1471                                           LoopNode()->MorePythonFunction() ,
1472                                           Err ) ;
1473           LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1474         }
1475       }
1476       if ( !Err ) {
1477         PyNextMethod = LoopNode()->PyNextMethod() ;
1478         if ( PyNextMethod ) {
1479         }
1480         else {
1481           PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1482                                           LoopNode()->NextPythonFunction() ,
1483                                           Err ) ;
1484           LoopNode()->PyNextMethod( PyNextMethod ) ;
1485         }
1486       }
1487       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1488              << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1489     }
1490     else if ( IsInLineNode() || IsSwitchNode() ) {
1491       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1492       if ( PyRunMethod ) {
1493       }
1494       else {
1495         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1496                                        InLineNode()->PythonFunction() ,
1497                                        Err ) ;
1498         InLineNode()->PyRunMethod( PyRunMethod ) ;
1499       }
1500       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1501     }
1502     else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1503               (*InLineNode()->PythonFunction()).length() ) {
1504       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1505       if ( PyRunMethod ) {
1506       }
1507       else {
1508         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1509                                        InLineNode()->PythonFunction() ,
1510                                        Err ) ;
1511         InLineNode()->PyRunMethod( PyRunMethod ) ;
1512       }
1513       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1514     }
1515   }
1516   Err = WithErr && Err ;
1517   cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1518   if ( Err ) {
1519     cdebug << " Error " << Err ;
1520   }
1521   cdebug << endl;
1522   return !Err ;
1523 }
1524
1525 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1526   CORBA::Long cpu = 0 ;
1527   cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1528        << theAutomaton->StateName( _currentState ) << endl ;
1529   cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1530   if ( IsOneOfInLineNodes() ) {
1531 //    cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1532 //    cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1533     cpu = PyCpuUsed( tot ) ;
1534   }
1535   else {
1536     if ( !CORBA::is_nil( Component() ) ) {
1537 //      cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1538 //      cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1539       try {
1540         cpu = Component()->CpuUsed_impl() ;
1541       }
1542       catch ( ... ) {
1543         cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1544         State( GraphExecutor::ErroredState ) ;
1545         _OutNode->State( GraphExecutor::ErroredState ) ;
1546         cpu = 0 ;
1547       }
1548     }
1549   }
1550   cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1551   cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1552        << theAutomaton->StateName( _currentState ) << endl ;
1553   return cpu ;
1554 }
1555
1556 #include <sys/time.h>
1557 #include <sys/resource.h>
1558 #include <unistd.h>
1559
1560 long GraphExecutor::InNode::PyCpu() {
1561   struct rusage usage ;
1562   long cpu ;
1563   if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1564     perror("GraphExecutor::InNode::PyCpu") ;
1565     return 0 ;
1566   }
1567 //  return usage.ru_utime.__time_t tv_sec ;
1568 //  cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1569 //         << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1570 //         << endl ;
1571   cpu = usage.ru_utime.tv_sec ;
1572   return cpu ;
1573 }
1574
1575 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1576   long cpu ;
1577   if ( _PyTotCpuUsed == -1 ) {
1578     if ( _Pythread == pthread_self() ) {
1579 //      cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1580 //             << " _PyTotCpuUsed " <<  _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1581 //             << _PyCpuUsed << endl ;
1582       cpu = PyCpu() - _PyCpuUsed ;
1583       if ( tot ) {
1584         _PyTotCpuUsed = cpu ;
1585       }
1586     }
1587     else {
1588       cpu = 0 ;
1589     }
1590   }
1591   else {
1592     cpu = _PyTotCpuUsed ;
1593   }
1594 //  cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1595 //         <<  _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1596   return cpu ;
1597 }
1598
1599 void GraphExecutor::InNode::SetPyCpuUsed() {
1600   _PyTotCpuUsed = -1 ;
1601   _PyCpuUsed = 0 ;
1602   _Pythread = pthread_self() ;
1603   _PyCpuUsed = PyCpu() ;
1604 //  cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1605 //         << _PyCpuUsed << endl ;
1606 }
1607
1608 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1609   _Loading = Loading ;
1610   
1611   // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works: 
1612   // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1613   // after Loading is finished (here below), ExecutingState must be pushed for GUI.  
1614   if ( !Loading )
1615     _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );
1616 }
1617