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