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