]> SALOME platform Git repositories - modules/superv.git/blob - src/GraphExecutor/DataFlowExecutor_InNode.cxx
Salome HOME
A bug was fixed: _Loading field is set to "false" (as it normally should be except...
[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   if ( pthread_mutex_lock( &_MutexDataWait ) ) {
390     perror("Ready pthread_mutex_lock ") ;
391     exit( 0 ) ;
392   }
393   _DataWait = true ;
394 }
395 void GraphExecutor::InNode::UnLockDataWait() {
396   _DataWait = false ;
397   if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
398     perror("Ready pthread_mutex_unlock ") ;
399     exit( 0 ) ;
400   }
401 }
402
403 Engines::Component_var GraphExecutor::InNode::Component() const {
404   if ( IsFactoryNode() ) {
405     return _FactoryNode->Component() ;
406   }
407   else {
408     CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
409     CORBA::Object_ptr obj ;
410     try {
411       *anAnyComponent >>= obj ;
412       return Engines::Component::_narrow( obj ) ;
413     }
414     catch( ... ) {
415       cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
416     }
417   }
418   return Engines::Component::_nil() ;
419 }
420
421 Engines::Container_var GraphExecutor::InNode::Container() const {
422   if ( IsFactoryNode() ) {
423     return _FactoryNode->Container() ;
424   }
425   return Engines::Container::_nil() ;
426 }
427
428
429 bool GraphExecutor::InNode::Ping() {
430 //  cdebug_in << "GraphExecutor::InNode::Ping" << endl;
431   bool RetVal ;
432   if ( IsFactoryNode() ) {
433     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
434     if ( RetVal ) {
435       if ( State() != GraphExecutor::SuspendedExecutingState ) {
436         try {
437           _FactoryNode->Component()->ping() ;
438         }
439         catch( ... ) {
440           cdebug << "InNode::Ping() ERROR catched" << endl ;
441           State( GraphExecutor::ErroredState ) ;
442           _OutNode->State( GraphExecutor::ErroredState ) ;
443           RetVal = false ;
444         }
445       }
446       else {
447         RetVal = false ;
448       }
449     }
450   }
451 //  cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
452   return RetVal ;
453 }
454
455 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
456   ThreadNo ( aThread ) ; 
457   if ( aThread )
458     _OutNode->NewThread() ;
459 }
460 void GraphExecutor::InNode::ExitThread() {
461   ThreadNo( 0 ) ;
462   _OutNode->ExitThread() ;
463
464
465 bool GraphExecutor::InNode::Suspend() {
466   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
467             << " " << Automaton()->StateName( State() ) << endl;
468   bool RetVal = false ;
469   if ( IsDone() ) {
470 //If loop we need to suspend also    ControlState( SUPERV::VoidState ) ;
471     ControlState( SUPERV::ToSuspendState ) ;
472     RetVal = true ;
473     if ( _OutNode->IsDone() ) {
474       ControlState( SUPERV::VoidState ) ;
475       RetVal = false ;
476     }
477   }
478   else if ( IsWaiting() || IsReady() ) {
479     ControlState( SUPERV::ToSuspendState ) ;
480     RetVal = true ;
481   }
482   else  if ( IsRunning() ) {
483     ControlState( SUPERV::ToSuspendState ) ;
484     if ( IsFactoryNode() || IsComputingNode() ) {
485 // We have to suspend in the container of that node
486       int TrySuspend = 10 ;
487       while ( TrySuspend ) {
488         if ( !CORBA::is_nil( Component() ) ) {
489 // We can call that component
490           try {
491             RetVal = Component()->Suspend_impl() ;
492           }
493           catch( ... ) {
494             cdebug << "InNode::Suspend() ERROR catched" << endl ;
495             State( GraphExecutor::ErroredState ) ;
496             _OutNode->State( GraphExecutor::ErroredState ) ;
497             RetVal = false ;
498             TrySuspend = 1 ;
499           }
500           cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
501           if ( RetVal ) {
502             if ( IsRunning() ) {
503               cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
504                      << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
505               SendEvent( GraphExecutor::SuspendEvent ) ;
506               cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
507                      << Name() << " --> thread" << ThreadNo() << endl;
508               TrySuspend = 1 ;
509             }
510             else if ( IsDone() ) {
511               ControlState( SUPERV::VoidState ) ;
512               RetVal = false ; // Too late ...
513               TrySuspend = 1 ;
514             }
515             else {
516               cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
517                      << endl ;
518               MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
519               TrySuspend = 1 ;
520             }
521           }
522           else {
523 // Suspend in the Container failed : it is always false if it is a Python Container
524             cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
525                    << endl ;
526             if ( TrySuspend == 1 ) {
527               if ( IsSuspended() ) {
528                 RetVal = true ;
529               }
530               else {
531                 RetVal = false ;
532               }
533             }
534           }
535         }
536         else {
537           cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
538                  << endl ;
539 // Wait for the end of loading of the component
540           while ( IsLoading() ) {
541             sleep( 1 ) ;
542           }
543           if ( TrySuspend == 1 ) {
544             if ( IsSuspended() ) {
545               RetVal = true ;
546             }
547             else {
548               RetVal = false ;
549             }
550           }
551         }
552         TrySuspend -= 1 ;
553         if ( TrySuspend ) {
554           sleep( 1 ) ;
555         }
556       }
557     }
558     else if ( IsMacroNode() ) {
559 // It should be like that but it is not completely implemented
560       GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
561       RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
562       if ( RetVal ) {
563         State( GraphExecutor::SuspendedState ) ;
564       }
565     }
566     else {
567 // Now we can suspend an InLineNode with the handler of the SuperVision Container
568       if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
569         perror("Suspend pthread_kill error") ;
570         State( GraphExecutor::ErroredState ) ;
571         _OutNode->State( GraphExecutor::ErroredState ) ;
572         RetVal = false ;
573       }
574       else {
575         RetVal = true ;
576       }
577       if ( RetVal ) {
578         if ( IsRunning() ) {
579           cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
580                  << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
581           SendEvent( GraphExecutor::SuspendEvent ) ;
582           cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
583                  << Name() << " --> thread" << ThreadNo() << endl;
584         }
585         else if ( IsDone() ) {
586           ControlState( SUPERV::VoidState ) ;
587           RetVal = false ; // Too late ...
588         }
589         else {
590           cdebug << "component Suspended and !IsDone and !IsRunning !"
591                  << endl ;
592         }
593       }
594     }
595   }
596   else {
597     cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
598            << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
599            << " ?" << endl ;
600     RetVal = false ;
601   }
602   cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
603              << Automaton()->StateName( State() ) << endl ;
604   return RetVal ;
605 }
606
607 bool GraphExecutor::InNode::ContainerKill() {
608   cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
609             << ThreadNo() << endl;
610   bool RetVal ;
611   if ( IsFactoryNode() ) {
612     Kill() ;
613     RetVal = Container()->Kill_impl() ;
614   }
615   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
616   return RetVal ;
617 }
618
619 bool GraphExecutor::InNode::Kill() {
620   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
621             << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
622             << " SuspendedThreads " << _OutNode->SuspendedThreads()
623             << " EventQSize " << _OutNode->EventQSize() << endl;
624   bool RetVal ;
625   if ( IsDone() ) {
626     ControlState( SUPERV::ToKillState ) ; // if loop
627     if ( _OutNode->IsDone() ) {
628       ControlState( SUPERV::VoidState ) ;
629     }
630     RetVal = false ;
631   }
632   else {
633     ControlState( SUPERV::ToKillState ) ;
634     if ( IsDone() ) {
635       if ( _OutNode->IsDone() ) {
636         ControlState( SUPERV::VoidState ) ;
637       }
638       RetVal = false ;
639     }
640     else {
641       if ( IsRunning() ) {
642         if ( IsFactoryNode() || IsComputingNode() ) {
643 // We have to suspend in the container of that node
644           int TryKill = 10 ;
645           while ( TryKill ) {
646             if ( !CORBA::is_nil( Component() ) ) {
647 // We can call that component
648               try {
649                 RetVal = Component()->Kill_impl() ;
650               }
651               catch( ... ) {
652                 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
653                 State( GraphExecutor::ErroredState ) ;
654                 _OutNode->State( GraphExecutor::ErroredState ) ;
655                 RetVal = false ;
656                 TryKill = 1 ;
657               }
658               cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
659               if ( RetVal ) {
660                 if ( IsRunning() ) {
661                   cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
662                          << " --> thread" << ThreadNo() << " KillEvent " << endl;
663                   SendEvent( GraphExecutor::KillEvent ) ;
664                   cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
665                          << Name() << " --> thread" << ThreadNo() << endl;
666                   TryKill = 1 ;
667                 }
668                 else if ( IsDone() ) {
669                   ControlState( SUPERV::VoidState ) ;
670                   RetVal = false ; // Too late ...
671                   TryKill = 1 ;
672                 }
673                 else {
674                   cdebug << "Kill component Killed and !IsDone and !IsRunning !"
675                          << endl ;
676                   TryKill = 1 ;
677                 }
678               }
679               else {
680 //  Kill in the Container failed : it is always false if it is a Python Container
681                 cdebug << "InNode::Suspend cannot  Kill component ! Python Component ?"
682                        << endl ;
683                 if ( TryKill == 1 ) {
684                   if ( IsKilled() ) {
685                     RetVal = true ;
686                   }
687                   else {
688                     RetVal = false ;
689                   }
690                 }
691               }
692             }
693             else {
694               cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
695                      << endl ;
696 // Wait for the end of loading of the component
697               while ( IsLoading() ) {
698                 sleep( 1 ) ;
699               }
700               if ( TryKill == 1 ) {
701                 if ( IsKilled() ) {
702                   RetVal = true ;
703                 }
704                 else {
705                   RetVal = false ;
706                 }
707               }
708             }
709             TryKill -= 1 ;
710             if ( TryKill ) {
711               sleep( 1 ) ;
712             }
713           }
714         }
715         else if ( IsMacroNode() ) {
716 // It should be like that but it is not completely implemented
717           GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
718           RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
719           if ( RetVal ) {
720             State( GraphExecutor::KilledState ) ;
721           }
722         }
723         else {
724 //PAL6886
725 // Now we can kill an InLineNode with the handler of the SuperVision Container
726           cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
727                  << _OutNode->MainThreadId() << " :" << endl ;
728           MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
729                  << _OutNode->MainThreadId() << " :" ) ;
730           if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
731 // python signals run only in main thread ...
732             perror("Kill pthread_kill error") ;
733             State( GraphExecutor::ErroredState ) ;
734             _OutNode->State( GraphExecutor::ErroredState ) ;
735             RetVal = false ;
736           }
737           else {
738             cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
739                    << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
740             MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
741                    << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
742             RetVal = true ;
743           }
744         }
745       }
746       else if ( IsSuspended() ) {
747         cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
748                << " --> thread" << ThreadNo() << " Resume()" << endl;
749         if ( Resume() ) {
750           RetVal = Kill() ;
751         }
752         else {
753           RetVal = false ;
754         }
755       }
756       else if ( IsWaiting() ) {
757         RetVal = false ;
758       }
759       else if ( IsReady() ) {
760         RetVal = true ;
761       }
762       else {
763        cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
764               << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
765               << " ?" << endl ;
766         RetVal = false ;
767       }
768     }
769   }
770   cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
771              << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
772              << " SuspendedThreads " << _OutNode->SuspendedThreads()
773              << " EventQSize " << _OutNode->EventQSize() << endl ;
774   return RetVal ;
775 }
776
777 bool GraphExecutor::InNode::KillDone() {
778   cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
779             << endl;
780   bool RetVal ;
781   if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
782     RetVal = false ;
783   }
784   else {
785     ControlState( SUPERV::ToKillDoneState ) ;
786     if ( IsDone() ) {
787       if ( _OutNode->IsDone() ) {
788         ControlState( SUPERV::VoidState ) ;
789       }
790       RetVal = false ;
791     }
792     else {
793       if ( IsRunning() ) {
794         RetVal = true ;
795       }
796       else if ( IsWaiting() ) {
797         RetVal = true ;
798       }
799       else {
800         cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
801                << endl ;
802         RetVal = false ;
803       }
804     }
805   }
806   cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
807   return RetVal ;
808 }
809
810 bool GraphExecutor::InNode::Stop() {
811   cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
812             << endl;
813   bool RetVal ;
814   if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
815     RetVal = false ;
816   }
817   else {
818     ControlState( SUPERV::ToStopState ) ;
819     if ( IsDone() ) {
820       if ( _OutNode->IsDone() ) {
821         ControlState( SUPERV::VoidState ) ;
822       }
823       RetVal = false ;
824     }
825     else {
826       if ( IsRunning() ) {
827         if ( IsFactoryNode() || IsComputingNode() ) {
828           if ( !CORBA::is_nil( Component() ) ) {
829             try {
830               RetVal = Component()->Stop_impl() ;
831             }
832             catch( ... ) {
833               cdebug << "InNode::Stop() ERROR catched" << endl ;
834               State( GraphExecutor::ErroredState ) ;
835               _OutNode->State( GraphExecutor::ErroredState ) ;
836               RetVal = false ;
837             }
838             if ( RetVal ) {
839               if ( IsRunning() ) {
840                 SendEvent( GraphExecutor::StopEvent ) ;
841               }
842               else if ( IsDone() ) {
843                 ControlState( SUPERV::VoidState ) ;
844                 RetVal = false ; // Too late ...
845               }
846               else {
847                 cdebug << "component Suspended and !IsDone and !IsRunning !"
848                        << endl ;
849               }
850             }
851           }
852           else {
853             cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
854             RetVal = false ;
855           }
856         }
857         else {
858           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
859           RetVal = false ;
860         }
861       }
862       else if ( IsWaiting() ) {
863         RetVal = true ;
864       }
865       else {
866         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
867                << endl ;
868         RetVal = false ;
869       }
870     }
871   }
872   cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
873   return RetVal ;
874 }
875
876 bool GraphExecutor::InNode::SuspendDone() {
877   cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
878             << ThreadNo() << endl;
879   bool RetVal ;
880   if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
881     RetVal = false ;
882   }
883   else {
884     ControlState( SUPERV::ToSuspendDoneState ) ;
885     if ( IsDone() ) {
886       if ( _OutNode->IsDone() ) {
887         ControlState( SUPERV::VoidState ) ;
888       }
889       RetVal = false ;
890     }
891     else {
892       RetVal = true ;
893     }
894   }
895   cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
896   return RetVal ;
897 }
898
899 bool GraphExecutor::InNode::Resume() {
900   cdebug_in << pthread_self() << "/" << ThreadNo()
901             << " GraphExecutor::InNode::Resume " << Name() << " "
902             << Automaton()->StateName( State() ) << endl;
903   bool RetVal = false ;
904   if ( IsSuspended() ) {
905     if ( State() == GraphExecutor::SuspendedReadyState ) {
906       ResumeAction( GraphExecutor::ToResumeEvent ) ;
907       RetVal = true ;
908     }
909     else if ( State() == GraphExecutor::SuspendedExecutingState ) {
910       if ( IsFactoryNode() || IsComputingNode() ) {
911         if ( pthread_mutex_lock( &_MutexWait ) ) {
912           perror("ResumeAction pthread_mutex_lock ") ;
913           exit( 0 ) ;
914         }
915         try {
916           RetVal = Component()->Resume_impl() ;
917           if ( RetVal ) {
918             State( GraphExecutor::ExecutingState ) ;
919           }
920         }
921         catch( ... ) {
922           cdebug << "InNode::Resume() ERROR catched" << endl ;
923           State( GraphExecutor::ErroredState ) ;
924           _OutNode->State( GraphExecutor::ErroredState ) ;
925           RetVal = false ;
926         }
927         if ( pthread_mutex_unlock( &_MutexWait ) ) {
928           perror("ResumeAction pthread_mutex_unlock ") ;
929           exit( 0 ) ;
930         }
931       }
932       else if ( IsMacroNode() ) {
933         cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
934         GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
935         RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
936         if ( RetVal ) {
937           State( GraphExecutor::ExecutingState ) ;
938         }
939       }
940       else {
941 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
942         cdebug << ThreadNo() << "/" << pthread_self()
943                << "Resume of InLineNode pthread_kill" << Name() << endl ;
944         if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
945           perror("Resume pthread_kill error") ;
946           State( GraphExecutor::ErroredState ) ;
947           _OutNode->State( GraphExecutor::ErroredState ) ;
948           RetVal = false ;
949         }
950         else {
951           State( GraphExecutor::ExecutingState ) ;
952           RetVal = true ;
953         }
954       }
955     }
956     else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
957       ResumeAction( GraphExecutor::ResumeEvent ) ;
958       RetVal = true ;
959     }
960     else if ( State() == GraphExecutor::SuspendedErroredState ) {
961       ResumeAction( GraphExecutor::ResumeEvent ) ;
962       RetVal = true ;
963     }
964     else {
965       cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
966              << Automaton()->StateName( State() ) << endl ;
967       RetVal = false ;
968     }
969   }
970   else {
971     cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
972            << Automaton()->StateName( State() ) << endl ;
973     RetVal = false ;
974   }
975   if ( ControlState() == SUPERV::ToSuspendStartState ) {
976     ControlState( SUPERV::VoidState ) ;
977   }
978
979 #if 0
980   if ( ControlState() == SUPERV::ToSuspendRunState ||
981        ( ControlState() == SUPERV::ToSuspendState &&
982          State() == GraphExecutor::SuspendedReadyState) ) {
983     if ( IsSuspended() ) {
984       if ( State() == GraphExecutor::SuspendedReadyState ) {
985         ResumeAction() ;
986         RetVal = true ;
987       }
988       else if ( State() == GraphExecutor::SuspendedExecutingState ) {
989         ResumeAction() ;
990         RetVal = Component()->Resume_impl() ;
991       }
992       else {
993         cdebug << "GraphExecutor::InNode::Resume State "
994                << Automaton()->StateName( State() ) << endl ;
995         RetVal = false ;
996       }
997       if ( ControlState() != SUPERV::ToSuspendState ) {
998         ControlState( SUPERV::VoidState ) ;
999       }
1000     }
1001     else if ( IsRunning() ) {
1002       RetVal = true ;
1003     }
1004     else if ( IsWaiting() ) {
1005       ControlState( SUPERV::VoidState ) ;
1006       RetVal = true ;
1007     }
1008     else if ( IsDone() ) {
1009       RetVal = true ;
1010     }
1011   }
1012   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1013             ( ControlState() == SUPERV::ToSuspendState &&
1014               State() == GraphExecutor::SuspendedSuccessedState) ) {
1015     if ( IsSuspended() ) {
1016       if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1017         ResumeAction() ;
1018         RetVal = true ;
1019       }
1020       else if ( State() == GraphExecutor::SuspendedErroredState ) {
1021         ResumeAction() ;
1022         RetVal = true ;
1023       }
1024       else {
1025         cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1026         RetVal = false ;
1027       }
1028       if ( ControlState() != SUPERV::ToSuspendState ) {
1029         ControlState( SUPERV::VoidState ) ;
1030       }
1031     }
1032     else if ( IsRunning() ) {
1033       ControlState( SUPERV::VoidState ) ;
1034       RetVal = true ;
1035     }
1036     else if ( IsWaiting() ) {
1037       ControlState( SUPERV::VoidState ) ;
1038       RetVal = true ;
1039     }
1040     else if ( IsDone() ) {
1041       ControlState( SUPERV::VoidState ) ;
1042       RetVal = true ;
1043     }
1044   }
1045 #endif
1046   cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1047              << Automaton()->StateName( State() ) << endl ;
1048   return RetVal ;
1049 }
1050
1051 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
1052                                      const bool AndSuspend ) {
1053   bool RetVal = false ;
1054   GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetGraphNode( AtNodeName )->GetInNode() ;
1055   cdebug_in << pthread_self() << "/" << ThreadNo()
1056             << " --> GraphExecutor::InNode::ReStartAt( "
1057             << AtNodeName << " , " << AndSuspend << ") " << endl
1058             << "thread " << aRestartNode->ThreadNo() << " "
1059             << Automaton()->StateName( aRestartNode->State() )
1060             << " from " << Name() << " " << Automaton()->StateName( State() )
1061             << endl ;
1062   if ( IsWaiting() && aRestartNode->IsSuspended() ) {
1063     RetVal = aRestartNode->Resume() ;
1064   }
1065   else if ( IsSuspended() ) {
1066     if ( strcmp( AtNodeName , Name() ) ) {
1067       aRestartNode->State( GraphExecutor::SuspendedSuccessedState ) ;
1068     }
1069     if ( AndSuspend ) {
1070       ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
1071     }
1072     else {
1073       ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
1074     }
1075     RetVal = true ;
1076   }
1077   cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << endl ;
1078   return RetVal ;
1079 }
1080
1081 bool GraphExecutor::InNode::IsWaiting() {
1082   bool aret = false ;
1083 //  cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1084   GraphExecutor::AutomatonState aState = State() ;
1085   if ( aState == GraphExecutor::DataUndefState ||
1086        aState == GraphExecutor::DataWaitingState ||
1087        aState == GraphExecutor::SuspendedReadyState )
1088 //       aState == GraphExecutor::SuspendedExecutingState ||
1089 //       aState == GraphExecutor::SuspendedSuccessedState ||
1090 //       aState == GraphExecutor::SuspendedErroredState ||
1091 //       aState == GraphExecutor::SuspendedState
1092     aret = true ;
1093 //  cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1094   return aret ;
1095 }
1096
1097 bool GraphExecutor::InNode::IsReady() {
1098   bool aret = false ;
1099 //  cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1100   GraphExecutor::AutomatonState aState = State() ;
1101 //  if ( aState == GraphExecutor::DataUndefState ||
1102 //       aState == GraphExecutor::DataWaitingState ||
1103   if ( aState == GraphExecutor::DataReadyState ||
1104        aState == GraphExecutor::ResumedReadyState )
1105     aret = true ;
1106 //  cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1107   return aret ;
1108 }
1109
1110 bool GraphExecutor::InNode::IsRunning() {
1111   bool aret = false ;
1112 //  cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1113   GraphExecutor::AutomatonState aState = State() ;
1114   if ( aState == GraphExecutor::ExecutingState ||
1115        aState == GraphExecutor::ResumedExecutingState )
1116     aret = true ;
1117 //  cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1118   return aret ;
1119 }
1120
1121 bool GraphExecutor::InNode::IsDone() {
1122   bool aret = false ;
1123 //  cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1124   GraphExecutor::AutomatonState aState = State() ;
1125   if ( aState == GraphExecutor::KilledReadyState ||
1126        aState == GraphExecutor::StoppedReadyState ||
1127        aState == GraphExecutor::KilledExecutingState ||
1128        aState == GraphExecutor::StoppedExecutingState ||
1129        aState == GraphExecutor::SuspendedSuccessedState ||
1130        aState == GraphExecutor::SuspendedErroredState ||
1131 //       aState == GraphExecutor::SuccessedExecutingState ||
1132 //       aState == GraphExecutor::ErroredExecutingState ||
1133        aState == GraphExecutor::SuccessedState ||
1134        aState == GraphExecutor::ErroredState ||
1135        aState == GraphExecutor::ResumedSuccessedState ||
1136        aState == GraphExecutor::ResumedErroredState ||
1137        aState == GraphExecutor::KilledSuccessedState ||
1138        aState == GraphExecutor::StoppedSuccessedState )
1139     aret = true ;
1140 //  cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1141   return aret ;
1142 }
1143
1144 bool GraphExecutor::InNode::IsSuspended() {
1145   bool aret = false ;
1146 //  cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1147   GraphExecutor::AutomatonState aState = State() ;
1148   if ( aState == GraphExecutor::SuspendedReadyState ||
1149        aState == GraphExecutor::SuspendedExecutingState ||
1150        aState == GraphExecutor::SuspendedSuccessedState ||
1151        aState == GraphExecutor::SuspendedErroredState ||
1152        aState == GraphExecutor::SuspendedState )
1153     aret = true ;
1154 //  cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1155   return aret ;
1156 }
1157 bool GraphExecutor::InNode::IsKilled() {
1158   bool aret = false ;
1159 //  cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1160   GraphExecutor::AutomatonState aState = State() ;
1161   if ( aState == GraphExecutor::KilledReadyState ||
1162        aState == GraphExecutor::KilledExecutingState ||
1163        aState == GraphExecutor::KilledSuccessedState ||
1164        aState == GraphExecutor::KilledErroredState ||
1165        aState == GraphExecutor::KilledState )
1166     aret = true ;
1167 //  cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1168   return aret ;
1169 }
1170 bool GraphExecutor::InNode::IsStopped() {
1171   bool aret = false ;
1172 //  cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1173   GraphExecutor::AutomatonState aState = State() ;
1174   if ( aState == GraphExecutor::StoppedReadyState ||
1175        aState == GraphExecutor::StoppedExecutingState ||
1176        aState == GraphExecutor::StoppedSuccessedState ||
1177        aState == GraphExecutor::StoppedErroredState ||
1178        aState == GraphExecutor::StoppedState )
1179     aret = true ;
1180 //  cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1181   return aret ;
1182 }
1183
1184 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1185   bool RetVal = false ;
1186   if ( pthread_mutex_lock( &_MutexWait ) ) {
1187     perror("pthread_mutex_lock _Wait") ;
1188     exit( 0 ) ;
1189   }
1190   switch ( aState ) {
1191   case SUPERV::ReadyState : {
1192     RetVal = IsReady() ;
1193     cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1194               << " " << Automaton()->StateName( _currentState )
1195               << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1196     while ( !RetVal && !IsDone() ) {
1197       cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1198       pthread_cond_wait( &_ReadyWait , &_MutexWait );
1199       RetVal = IsReady() ;
1200       cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1201              << Automaton()->StateName( _currentState ) << " " << RetVal
1202              << endl ;
1203     }
1204     cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1205                << " " << Automaton()->StateName( _currentState )
1206                << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1207     break ;
1208   }
1209   case SUPERV::RunningState : {
1210     RetVal = IsRunning() ;
1211     cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1212               << " " << Automaton()->StateName( _currentState )
1213               << " pthread_cond_wait _RunningWait " << Name() << endl ;
1214     while ( !RetVal && !IsDone() ) {
1215       cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1216       pthread_cond_wait( &_RunningWait , &_MutexWait );
1217 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1218       RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1219                State() == GraphExecutor::ErroredExecutingState ;
1220       cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1221              << Automaton()->StateName( _currentState ) << " " << RetVal
1222              << " " << Name() << endl ;
1223     }
1224     cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1225                << " " << Automaton()->StateName( _currentState )
1226                << " pthread_cond_wait _RunningWait " << Name() << endl ;
1227     break ;
1228   }
1229   case SUPERV::DoneState : {
1230     RetVal = IsDone() ;
1231     cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1232               << " " << Automaton()->StateName( _currentState )
1233               << " pthread_cond_wait _DoneWait " << Name() << endl ;
1234     while ( !RetVal ) {
1235       cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1236       pthread_cond_wait( &_DoneWait , &_MutexWait );
1237       RetVal = IsDone() ;
1238       cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1239              << Automaton()->StateName( _currentState ) << " " << RetVal
1240              << endl ;
1241     }
1242     cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1243                << " " << Automaton()->StateName( _currentState )
1244                << " pthread_cond_wait _DoneWait " << Name() << endl ;
1245     break ;
1246   }
1247   case SUPERV::SuspendState : {
1248     RetVal = IsSuspended() ;
1249     cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1250               << " " << Automaton()->StateName( _currentState )
1251               << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1252     while ( !RetVal && !IsDone() ) {
1253       cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1254       pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1255       RetVal = IsSuspended() ;
1256       cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1257              << Automaton()->StateName( _currentState ) << " " << RetVal
1258              << endl ;
1259     }
1260     cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1261                << " " << Automaton()->StateName( _currentState )
1262                << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1263     break ;
1264   }
1265   default : {
1266     cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1267            << aState << endl ;
1268   }
1269   }
1270   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1271     perror("pthread_mutex_lock _Wait") ;
1272     exit( 0 ) ;
1273   }
1274   return RetVal ;
1275 }
1276
1277 bool GraphExecutor::InNode::ReadyWait() {
1278 //  cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1279   bool aret ;
1280   aret = StateWait( SUPERV::ReadyState ) ;
1281 //  cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1282   return aret ;
1283 }
1284
1285 bool GraphExecutor::InNode::RunningWait() {
1286   cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1287             << " " << Automaton()->StateName( State() ) << endl;
1288   bool aret ;
1289   aret = StateWait( SUPERV::RunningState ) ;
1290   cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1291              << " " << Automaton()->StateName( State() ) << endl;
1292   return aret ;
1293 }
1294
1295 bool GraphExecutor::InNode::DoneWait() {
1296 //  cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1297   bool aret ;
1298   aret = StateWait( SUPERV::DoneState ) ;
1299   return aret ;
1300 }
1301
1302 bool GraphExecutor::InNode::SuspendedWait() {
1303 //  cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1304   bool aret ;
1305   aret = StateWait( SUPERV::SuspendState ) ;
1306   return aret ;
1307 }
1308
1309 void GraphExecutor::InNode::InitialState()
1310 {
1311   cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1312
1313   int i;
1314   _ControlState = SUPERV::VoidState ;
1315   CreateNewThread( false ) ;
1316   CreateNewThreadIf( false ) ;
1317   _SuspendSync = false ;
1318   _ResumeSync = false ;
1319   IsLoading( true ) ;
1320 //  ThreadNo( pthread_self() ) ;
1321   ThreadNo( 0 ) ;
1322
1323   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1324     if ( GetNodeOutPort(i)->IsDataStream() ) {
1325       GetChangeNodeOutPort(i)->State(  SUPERV::ReadyState ) ;
1326       GetChangeNodeOutPort(i)->Done( true ) ;
1327     }
1328     else if ( i != 0 || !IsGOTONode() ) {
1329       GetChangeNodeOutPort(i)->State(  SUPERV::WaitingState ) ;
1330       GetChangeNodeOutPort(i)->Done( false ) ;
1331     }
1332   }
1333
1334   int Pc = GetNodeInPortsSize() ;
1335   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1336     const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1337     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1338     if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1339       anOutPort->PortStatus( DataConnected );
1340       anOutPort->State( SUPERV::ReadyState ) ;
1341       anOutPort->Done( true ) ;
1342       CORBA::Any * anAny = new CORBA::Any() ;
1343       *anAny <<= (long ) 1 ;
1344       anOutPort->Value( anAny ) ;
1345     }
1346 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1347     else if ( anInPort->IsGate() && anOutPort ) {
1348       anOutPort->State( SUPERV::WaitingState ) ;
1349       anOutPort->Done( false ) ;
1350       const GraphBase::ComputingNode * aFromNode =  _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ; 
1351       if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) { // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.  
1352                                        // before was "else if ( IsOneOfInlineNodes() )"
1353                                        // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1354         anOutPort->PortStatus( DataConnected );
1355         anOutPort->State( SUPERV::ReadyState ) ;
1356         anOutPort->Done( true ) ;
1357       }
1358     }
1359     if ( anInPort->IsGate() && anOutPort == NULL ) {
1360       Pc-- ;
1361       cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected Pc " << Pc << endl ;
1362     }
1363     else if ( anOutPort ) {
1364       if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1365         Pc-- ;
1366         anOutPort->State( SUPERV::ReadyState ) ;
1367         anOutPort->Done( true ) ;
1368         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1369                << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1370       }
1371       else if ( anOutPort->IsPortConnected() ) {
1372         anOutPort->State( SUPERV::WaitingState ) ;
1373         anOutPort->Done( false ) ;
1374         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1375                << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1376       }
1377       else {
1378         cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1379                << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1380                << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1381       }
1382     }
1383     else {
1384       cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1385              << " no corresponding OutPort Pc " << Pc << endl ;
1386     }
1387     if ( anOutPort ) {
1388       if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1389         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1390                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1391                << " with state " << theAutomaton->StateName( anOutPort->State() ) << endl ;
1392         GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1393       }
1394       else if ( anOutPort->IsDataConnected() ) {
1395         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1396                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1397                << " with state ReadyState" << endl ;
1398         GetChangeNodeInPort(i)->State( SUPERV::ReadyState ) ;
1399       }
1400       else {
1401         cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1402                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1403                << " with state " << anOutPort->State() << endl ;
1404       }
1405     }
1406     if ( anOutPort ) {
1407       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1408              << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1409              << " with state " ;
1410       if ( anOutPort->State() == SUPERV::WaitingState ) {
1411         cdebug << "WaitingState" ;
1412       }
1413       else if ( anOutPort->State() == SUPERV::ReadyState ) {
1414         cdebug << "ReadyState" ;
1415       }
1416       else {
1417         cdebug << "???" ;
1418       }
1419       cdebug << " PortConnected("
1420              << anOutPort->IsPortConnected() << ") DataConnected("
1421              << anOutPort->IsDataConnected() << ")" << endl ;
1422     }
1423   }
1424
1425   _currentState = Pc > 0 ? GraphExecutor::DataWaitingState 
1426                          : GraphExecutor::DataReadyState ;
1427   if ( Pc == GetNodeInPortsSize() ) {
1428     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1429                          _currentState ) ; 
1430   }
1431   else if ( Pc != 0 ) {
1432     _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1433                          _currentState ) ; 
1434   }
1435   else {
1436     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1437                          _currentState ) ; 
1438   }
1439
1440   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1441     cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1442            << theAutomaton->StateName( GetChangeNodeOutPort(i)->State() )
1443            << " " << GetNodeOutPort(i)->Kind() << endl ;
1444   }
1445
1446   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1447          << endl;
1448
1449   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1450 }
1451
1452 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1453   cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
1454   bool Err = false ;
1455   if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1456     if ( IsLoopNode() ) {
1457       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1458       PyObject * PyMoreMethod = NULL ;
1459       PyObject * PyNextMethod = NULL ;
1460       if ( PyRunMethod ) {
1461       }
1462       else {
1463         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1464                                        InLineNode()->PythonFunction() ,
1465                                        Err ) ;
1466         InLineNode()->PyRunMethod( PyRunMethod ) ;
1467       }
1468       if ( !Err ) {
1469         PyMoreMethod = LoopNode()->PyMoreMethod() ;
1470         if ( PyMoreMethod ) {
1471         }
1472         else {
1473           PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1474                                           LoopNode()->MorePythonFunction() ,
1475                                           Err ) ;
1476           LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1477         }
1478       }
1479       if ( !Err ) {
1480         PyNextMethod = LoopNode()->PyNextMethod() ;
1481         if ( PyNextMethod ) {
1482         }
1483         else {
1484           PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1485                                           LoopNode()->NextPythonFunction() ,
1486                                           Err ) ;
1487           LoopNode()->PyNextMethod( PyNextMethod ) ;
1488         }
1489       }
1490       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1491              << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1492     }
1493     else if ( IsInLineNode() || IsSwitchNode() ) {
1494       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1495       if ( PyRunMethod ) {
1496       }
1497       else {
1498         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1499                                        InLineNode()->PythonFunction() ,
1500                                        Err ) ;
1501         InLineNode()->PyRunMethod( PyRunMethod ) ;
1502       }
1503       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1504     }
1505     else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1506               (*InLineNode()->PythonFunction()).length() ) {
1507       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1508       if ( PyRunMethod ) {
1509       }
1510       else {
1511         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1512                                        InLineNode()->PythonFunction() ,
1513                                        Err ) ;
1514         InLineNode()->PyRunMethod( PyRunMethod ) ;
1515       }
1516       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1517     }
1518   }
1519   Err = WithErr && Err ;
1520   cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1521   if ( Err ) {
1522     cdebug << " Error " << Err ;
1523   }
1524   cdebug << endl;
1525   return !Err ;
1526 }
1527
1528 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1529   CORBA::Long cpu = 0 ;
1530   cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1531        << theAutomaton->StateName( _currentState ) << endl ;
1532   cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1533   if ( IsOneOfInLineNodes() ) {
1534 //    cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1535 //    cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1536     cpu = PyCpuUsed( tot ) ;
1537   }
1538   else {
1539     if ( !CORBA::is_nil( Component() ) ) {
1540 //      cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1541 //      cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1542       try {
1543         cpu = Component()->CpuUsed_impl() ;
1544       }
1545       catch ( ... ) {
1546         cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1547         State( GraphExecutor::ErroredState ) ;
1548         _OutNode->State( GraphExecutor::ErroredState ) ;
1549         cpu = 0 ;
1550       }
1551     }
1552   }
1553   cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1554   cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1555        << theAutomaton->StateName( _currentState ) << endl ;
1556   return cpu ;
1557 }
1558
1559 #include <sys/time.h>
1560 #include <sys/resource.h>
1561 #include <unistd.h>
1562
1563 long GraphExecutor::InNode::PyCpu() {
1564   struct rusage usage ;
1565   long cpu ;
1566   if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1567     perror("GraphExecutor::InNode::PyCpu") ;
1568     return 0 ;
1569   }
1570 //  return usage.ru_utime.__time_t tv_sec ;
1571 //  cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1572 //         << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1573 //         << endl ;
1574   cpu = usage.ru_utime.tv_sec ;
1575   return cpu ;
1576 }
1577
1578 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1579   long cpu ;
1580   if ( _PyTotCpuUsed == -1 ) {
1581     if ( _Pythread == pthread_self() ) {
1582 //      cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1583 //             << " _PyTotCpuUsed " <<  _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1584 //             << _PyCpuUsed << endl ;
1585       cpu = PyCpu() - _PyCpuUsed ;
1586       if ( tot ) {
1587         _PyTotCpuUsed = cpu ;
1588       }
1589     }
1590     else {
1591       cpu = 0 ;
1592     }
1593   }
1594   else {
1595     cpu = _PyTotCpuUsed ;
1596   }
1597 //  cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1598 //         <<  _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1599   return cpu ;
1600 }
1601
1602 void GraphExecutor::InNode::SetPyCpuUsed() {
1603   _PyTotCpuUsed = -1 ;
1604   _PyCpuUsed = 0 ;
1605   _Pythread = pthread_self() ;
1606   _PyCpuUsed = PyCpu() ;
1607 //  cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1608 //         << _PyCpuUsed << endl ;
1609 }
1610
1611 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1612   _Loading = Loading ;
1613   
1614   // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works: 
1615   // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1616   // after Loading is finished (here below), ExecutingState must be pushed for GUI.  
1617   if ( !Loading )
1618     _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );
1619 }
1620