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