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