Salome HOME
MPV: Merge V1_2d
[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
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_OutNode.hxx"
51
52 static void InitInNode( int &_RewindStack ,
53                         SUPERV::ControlState &_ControlState ,
54                         SUPERV::AutomatonState &_currentState ,
55                         GraphExecutor::InNode ** _aReStartNode ,
56                         bool & _PyFuncRunned ,
57                         PyObject ** _MyPyRunMethod ,
58                         pthread_mutex_t &_MutexDataWait ,
59                         bool &_DataWait ,
60                         pthread_mutex_t &_MutexWait ,
61                         pthread_cond_t &_ReadyWait ,
62                         pthread_cond_t &_RunningWait ,
63                         pthread_cond_t &_DoneWait ,
64                         pthread_cond_t &_SuspendedWait ,
65                         pthread_cond_t &_SuspendWait ,
66                         bool &_SuspendSync ,
67                         pthread_cond_t &_ResumeWait ,
68                         bool &_ResumeSync ,
69                         pthread_cond_t &_KillWait ,
70                         bool &_KillSync ,
71                         pthread_cond_t &_ThreadStartedWait ,
72                         bool &_ThreadStartedSync ,
73                         pthread_cond_t &_StopWait ,
74                         GraphExecutor::FiniteStateMachine ** _Automaton ,
75                         GraphExecutor::FiniteStateMachine * theAutomaton ,
76                         CORBA::ORB_ptr * _Orb ,
77                         CORBA::ORB_ptr ORB ) {
78   _RewindStack = 0 ;
79   _ControlState = SUPERV::VoidState ;
80   _currentState = SUPERV::UnKnownState ;
81   *_aReStartNode = NULL ;
82   _PyFuncRunned = false ;
83   *_MyPyRunMethod = NULL ;
84   pthread_mutex_init( &_MutexDataWait , NULL ) ;
85   _DataWait = false ;
86   pthread_mutex_init( &_MutexWait , NULL ) ;
87   if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
88     perror("pthread_cond_init( &_ReadyWait , NULL )") ;
89     exit( 0 ) ;
90   }
91   if ( pthread_cond_init( &_RunningWait , NULL ) ) {
92     perror("pthread_cond_init( &_RunningWait , NULL )") ;
93     exit( 0 ) ;
94   }
95   if ( pthread_cond_init( &_DoneWait , NULL ) ) {
96     perror("pthread_cond_init( &_DoneWait , NULL )") ;
97     exit( 0 ) ;
98   }
99   if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
100     perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
101     exit( 0 ) ;
102   }
103   if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
104     perror("pthread_cond_init( &_SuspendWait , NULL )") ;
105     exit( 0 ) ;
106   }
107   _SuspendSync = false ;
108   if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
109     perror("pthread_cond_init( &_ResumeWait , NULL )") ;
110     exit( 0 ) ;
111   }
112   _ResumeSync = false ;
113   if ( pthread_cond_init( &_KillWait , NULL ) ) {
114     perror("pthread_cond_init( &_KillWait , NULL )") ;
115     exit( 0 ) ;
116   }
117   _KillSync = false ;
118   if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
119     perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
120     exit( 0 ) ;
121   }
122   _ThreadStartedSync = false ;
123   if ( pthread_cond_init( &_StopWait , NULL ) ) {
124     perror("pthread_cond_init( &_StopWait , NULL )") ;
125     exit( 0 ) ;
126   }
127   *_Automaton = theAutomaton ;
128   *_Orb = CORBA::ORB::_nil();
129 }
130
131 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
132
133 //GraphExecutor::InNode::InNode() :
134 //     GraphBase::FactoryNode() {
135 GraphExecutor::InNode::InNode() {
136   InitInNode( _RewindStack ,
137               _ControlState ,
138               _currentState ,
139               &_aReStartNode ,
140               _PyFuncRunned ,
141               &_MyPyRunMethod ,
142               _MutexDataWait ,
143               _DataWait ,
144               _MutexWait ,
145               _ReadyWait ,
146               _RunningWait ,
147               _DoneWait ,
148               _SuspendedWait ,
149               _SuspendWait ,
150               _SuspendSync ,
151               _ResumeWait ,
152               _ResumeSync ,
153               _KillWait ,
154               _KillSync ,
155               _ThreadStartedWait ,
156               _ThreadStartedSync ,
157               _StopWait ,
158               &_Automaton ,
159               theAutomaton ,
160               &_Orb ,
161               CORBA::ORB::_nil() ) ;
162 }
163
164 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
165                                SALOME_NamingService* ptrNamingService ,
166                                const SALOME_ModuleCatalog::Service& aService ,
167                                const char * ComponentName ,
168                                const char * NodeInterfaceName ,
169                                const char * NodeName ,
170                                const SUPERV::KindOfNode akind ,
171                                GraphBase::ListOfFuncName aFuncName ,
172                                GraphBase::ListOfPythonFunctions aPythonFunction ,
173                                const SUPERV::SDate NodeFirstCreation ,
174                                const SUPERV::SDate NodeLastModification  ,
175                                const char * NodeEditorRelease ,
176                                const char * NodeAuthor ,
177                                const char * NodeComputer ,
178                                const char * NodeComment ,
179                                const bool   GeneratedName ,
180                                const int NodeX ,
181                                const int NodeY ,
182                                int * Graph_prof_debug,
183                                ofstream * Graph_fdebug) {
184 //               ostream * Graph_fdebug = NULL ) :
185 //             GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
186 //                                     ComponentName , NodeInterfaceName ,
187 //                                     NodeName , akind ,
188 //                                     NodeFirstCreation , NodeLastModification  ,
189 //                                     NodeEditorRelease , NodeAuthor ,
190 //                                     NodeComputer , NodeComment , GeneratedName ,
191 //                                     0 , 0 ,
192 //                                     Graph_prof_debug , Graph_fdebug ) {
193   InitInNode( _RewindStack ,
194               _ControlState ,
195               _currentState ,
196               &_aReStartNode ,
197               _PyFuncRunned ,
198               &_MyPyRunMethod ,
199               _MutexDataWait ,
200               _DataWait ,
201               _MutexWait ,
202               _ReadyWait ,
203               _RunningWait ,
204               _DoneWait ,
205               _SuspendedWait ,
206               _SuspendWait ,
207               _SuspendSync ,
208               _ResumeWait ,
209               _ResumeSync ,
210               _KillWait ,
211               _KillSync ,
212               _ThreadStartedWait ,
213               _ThreadStartedSync ,
214               _StopWait ,
215               &_Automaton ,
216               theAutomaton ,
217               &_Orb ,
218               ORB ) ;
219   SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
220
221   _ComputingNode = NULL ;
222   _FactoryNode = NULL ;
223   _InLineNode = NULL ;
224   _GOTONode = NULL ;
225   _LoopNode = NULL ;
226   _EndOfLoopNode = NULL ;
227   _SwitchNode = NULL ;
228   _EndOfSwitchNode = NULL ;
229   switch ( akind ) {
230   case SUPERV::ComputingNode : {
231     cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
232     _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
233                                                    aService ,
234                                                    NodeName , akind ,
235                                                    NodeFirstCreation ,
236                                                    NodeLastModification  ,
237                                                    NodeEditorRelease , NodeAuthor ,
238                                                    NodeComment , GeneratedName ,
239                                                    NodeX , NodeY ,
240                                                    Graph_prof_debug , Graph_fdebug ) ;
241     break ;
242   }
243   case SUPERV::FactoryNode : {
244     cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
245     _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
246                                                ComponentName , NodeInterfaceName ,
247                                                NodeName , akind ,
248                                                NodeFirstCreation ,
249                                                NodeLastModification  ,
250                                                NodeEditorRelease , NodeAuthor ,
251                                                NodeComputer , NodeComment ,
252                                                GeneratedName , NodeX , NodeY ,
253                                                Graph_prof_debug , Graph_fdebug ) ;
254     _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
255     break ;
256   }
257   case SUPERV::InLineNode : {
258     cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
259     _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
260                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
261                                              NodeName , akind ,
262                                              NodeFirstCreation , NodeLastModification  ,
263                                              NodeEditorRelease , NodeAuthor ,
264                                              NodeComment , GeneratedName ,
265                                              NodeX , NodeY ,
266                                              Graph_prof_debug , Graph_fdebug ) ;
267     _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
268     break ;
269   }
270   case SUPERV::GOTONode : {
271     cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
272     _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
273                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
274                                          NodeName , akind ,
275                                          NodeFirstCreation , NodeLastModification  ,
276                                          NodeEditorRelease , NodeAuthor ,
277                                          NodeComment , GeneratedName ,
278                                          NodeX , NodeY ,
279                                          Graph_prof_debug , Graph_fdebug ) ;
280     _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
281     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
282     break ;
283   }
284   case SUPERV::LoopNode : {
285     cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
286     _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
287                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
288                                          aFuncName[1].c_str() , *aPythonFunction[1] ,
289                                          aFuncName[2].c_str() , *aPythonFunction[2] ,
290                                          NodeName , akind ,
291                                          NodeFirstCreation , NodeLastModification  ,
292                                          NodeEditorRelease , NodeAuthor ,
293                                          NodeComment , GeneratedName ,
294                                          NodeX , NodeY ,
295                                          Graph_prof_debug , Graph_fdebug ) ;
296     _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
297     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
298     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
299     break ;
300   }
301   case SUPERV::EndLoopNode : {
302     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
303     _EndOfLoopNode = new GraphBase::EndOfLoopNode(
304                                          ORB , ptrNamingService ,
305                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
306                                          NodeName , akind ,
307                                          NodeFirstCreation , NodeLastModification  ,
308                                          NodeEditorRelease , NodeAuthor ,
309                                          NodeComment , GeneratedName ,
310                                          NodeX , NodeY ,
311                                          Graph_prof_debug , Graph_fdebug ) ;
312     _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
313     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
314     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
315     break ;
316   }
317   case SUPERV::SwitchNode : {
318     cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
319     _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
320                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
321                                              NodeName , akind ,
322                                              NodeFirstCreation , NodeLastModification  ,
323                                              NodeEditorRelease , NodeAuthor ,
324                                              NodeComment , GeneratedName ,
325                                              NodeX , NodeY ,
326                                              Graph_prof_debug , Graph_fdebug ) ;
327     _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
328     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
329     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
330     break ;
331   }
332   case SUPERV::EndSwitchNode : {
333     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
334     _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
335                                              ORB , ptrNamingService ,
336                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
337                                              NodeName , akind ,
338                                              NodeFirstCreation , NodeLastModification  ,
339                                              NodeEditorRelease , NodeAuthor ,
340                                              NodeComment , GeneratedName ,
341                                              NodeX , NodeY ,
342                                              Graph_prof_debug , Graph_fdebug ) ;
343     _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
344     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
345     _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
346     break ;
347   }
348   case SUPERV::DataFlowNode : {
349     cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowNode ERROR : " << NodeName ;
350   }
351   case SUPERV::UnknownNode : {
352     cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
353   }
354   }
355   cdebug << "GraphExecutor::InNode::InNode "  << (void *) this
356          << " _ComputingNode " << (void *) _ComputingNode  ;
357   _ComputingNode->InNode( this ) ;
358 }
359
360 GraphExecutor::InNode::~InNode() {
361 }
362
363 void GraphExecutor::InNode::LockDataWait() {
364   if ( pthread_mutex_lock( &_MutexDataWait ) ) {
365     perror("Ready pthread_mutex_lock ") ;
366     exit( 0 ) ;
367   }
368   _DataWait = true ;
369 }
370 void GraphExecutor::InNode::UnLockDataWait() {
371   _DataWait = false ;
372   if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
373     perror("Ready pthread_mutex_unlock ") ;
374     exit( 0 ) ;
375   }
376 }
377
378 Engines::Component_var GraphExecutor::InNode::Component() const {
379   if ( IsFactoryNode() ) {
380     return _FactoryNode->Component() ;
381   }
382   else {
383     CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
384     CORBA::Object_ptr obj ;
385     try {
386       *anAnyComponent >>= obj ;
387       return Engines::Component::_narrow( obj ) ;
388     }
389     catch( ... ) {
390       cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
391     }
392   }
393   return Engines::Component::_nil() ;
394 }
395
396 Engines::Container_var GraphExecutor::InNode::Container() const {
397   if ( IsFactoryNode() ) {
398     return _FactoryNode->Container() ;
399   }
400   return Engines::Container::_nil() ;
401 }
402
403
404 bool GraphExecutor::InNode::Ping() {
405 //  cdebug_in << "GraphExecutor::InNode::Ping" << endl;
406   bool RetVal ;
407   if ( IsFactoryNode() ) {
408     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
409     if ( RetVal ) {
410       if ( State() != SUPERV::SuspendedExecutingState ) {
411         _FactoryNode->Component()->ping() ;
412       }
413       else {
414         RetVal = false ;
415       }
416     }
417   }
418 //  cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
419   return RetVal ;
420 }
421
422 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
423   ThreadNo ( aThread ) ; 
424   if ( aThread )
425     _OutNode->NewThread() ;
426 }
427 void GraphExecutor::InNode::ExitThread() {
428   ThreadNo( 0 ) ;
429   _OutNode->ExitThread() ;
430
431
432 bool GraphExecutor::InNode::Suspend() {
433   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
434             << endl;
435   bool RetVal ;
436   if ( IsDone() ) {
437     ControlState( SUPERV::VoidState ) ;
438     if ( _OutNode->IsDone() ) {
439       ControlState( SUPERV::VoidState ) ;
440     }
441     RetVal = false ;
442   }
443   else if ( IsWaiting() || IsReady() ) {
444     ControlState( SUPERV::ToSuspendState ) ;
445     RetVal = true ;
446   }
447   else  if ( IsRunning() ) {
448     ControlState( SUPERV::ToSuspendState ) ;
449     if ( IsFactoryNode() || IsComputingNode() ) {
450       if ( !CORBA::is_nil( Component() ) ) {
451         RetVal = Component()->Suspend_impl() ;
452         if ( RetVal ) {
453           if ( IsRunning() ) {
454             cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
455                    << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
456             SendEvent( GraphExecutor::SuspendEvent ) ;
457             cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
458                    << Name() << " --> thread" << ThreadNo() << endl;
459           }
460           else if ( IsDone() ) {
461             ControlState( SUPERV::VoidState ) ;
462             RetVal = false ; // Too late ...
463           }
464           else {
465             cdebug << "component Suspended and !IsDone and !IsRunning !"
466                    << endl ;
467           }
468         }
469       }
470       else {
471         cdebug << "Suspend cannot Suspend component !" << endl ;
472         RetVal = false ;
473       }
474     }
475     else {
476       cdebug << "Suspend with nilComponent while RunningState !" << endl ;
477       RetVal = false ;
478     }
479   }
480   else {
481     cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
482            << endl ;
483     RetVal = false ;
484   }
485   cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
486              << Automaton()->StateName( State() ) << endl ;
487   return RetVal ;
488 }
489
490 bool GraphExecutor::InNode::ContainerKill() {
491   cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
492             << ThreadNo() << endl;
493   bool RetVal ;
494   if ( IsFactoryNode() ) {
495     Kill() ;
496     RetVal = Container()->Kill_impl() ;
497   }
498   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
499   return RetVal ;
500 }
501
502 bool GraphExecutor::InNode::Kill() {
503   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
504             << Automaton()->StateName( State() ) << endl;
505   bool RetVal ;
506   if ( IsDone() ) {
507     ControlState( SUPERV::ToKillState ) ; // if loop
508     if ( _OutNode->IsDone() ) {
509       ControlState( SUPERV::VoidState ) ;
510     }
511     RetVal = false ;
512   }
513   else {
514     ControlState( SUPERV::ToKillState ) ;
515     if ( IsDone() ) {
516       if ( _OutNode->IsDone() ) {
517         ControlState( SUPERV::VoidState ) ;
518       }
519       RetVal = false ;
520     }
521     else {
522       if ( IsRunning() ) {
523         if ( IsFactoryNode() || IsComputingNode() ) {
524           if ( !CORBA::is_nil( Component() ) ) {
525             RetVal = Component()->Kill_impl() ;
526             cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
527             RetVal = true ;
528             if ( IsRunning() ) {
529               cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
530                      << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
531               SendEvent( GraphExecutor::KillEvent ) ;
532               cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
533                      << Name() << " --> thread" << ThreadNo() << endl;
534             }
535             else if ( IsDone() ) {
536               ControlState( SUPERV::VoidState ) ;
537               RetVal = false ; // Too late ...
538             }
539             else {
540               cdebug << "component Killed and !IsDone and !IsRunning !"
541                      << endl ;
542             }
543           }
544           else {
545             cdebug << "Kill with nilComponent cannot Kill component !" << endl ;
546             RetVal = false ;
547           }
548         }
549       }
550       else if ( IsSuspended() ) {
551         cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
552                << " --> thread" << ThreadNo() << " Resume()" << endl;
553         Resume() ;
554         RetVal = true ;
555       }
556       else if ( IsWaiting() ) {
557         RetVal = true ;
558       }
559       else {
560         cdebug << "Kill and !IsDone and !IsRunning and !IsWaiting ?"
561                << endl ;
562         RetVal = false ;
563       }
564     }
565   }
566   cdebug_out << "GraphExecutor::InNode::Kill" << endl ;
567   return RetVal ;
568 }
569
570 bool GraphExecutor::InNode::KillDone() {
571   cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
572             << endl;
573   bool RetVal ;
574   if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
575     RetVal = false ;
576   }
577   else {
578     ControlState( SUPERV::ToKillDoneState ) ;
579     if ( IsDone() ) {
580       if ( _OutNode->IsDone() ) {
581         ControlState( SUPERV::VoidState ) ;
582       }
583       RetVal = false ;
584     }
585     else {
586       if ( IsRunning() ) {
587         RetVal = true ;
588       }
589       else if ( IsWaiting() ) {
590         RetVal = true ;
591       }
592       else {
593         cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
594                << endl ;
595         RetVal = false ;
596       }
597     }
598   }
599   cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
600   return RetVal ;
601 }
602
603 bool GraphExecutor::InNode::Stop() {
604   cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
605             << endl;
606   bool RetVal ;
607   if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
608     RetVal = false ;
609   }
610   else {
611     ControlState( SUPERV::ToStopState ) ;
612     if ( IsDone() ) {
613       if ( _OutNode->IsDone() ) {
614         ControlState( SUPERV::VoidState ) ;
615       }
616       RetVal = false ;
617     }
618     else {
619       if ( IsRunning() ) {
620         if ( IsFactoryNode() || IsComputingNode() ) {
621           if ( !CORBA::is_nil( Component() ) ) {
622             RetVal = Component()->Stop_impl() ;
623             if ( RetVal ) {
624               if ( IsRunning() ) {
625                 SendEvent( GraphExecutor::StopEvent ) ;
626               }
627               else if ( IsDone() ) {
628                 ControlState( SUPERV::VoidState ) ;
629                 RetVal = false ; // Too late ...
630               }
631               else {
632                 cdebug << "component Suspended and !IsDone and !IsRunning !"
633                        << endl ;
634               }
635             }
636           }
637           else {
638             cdebug << "Suspend cannot Suspend component !" << endl ;
639             RetVal = false ;
640           }
641         }
642         else {
643           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
644           RetVal = false ;
645         }
646       }
647       else if ( IsWaiting() ) {
648         RetVal = true ;
649       }
650       else {
651         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
652                << endl ;
653         RetVal = false ;
654       }
655     }
656   }
657   cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
658   return RetVal ;
659 }
660
661 bool GraphExecutor::InNode::SuspendDone() {
662   cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
663             << ThreadNo() << endl;
664   bool RetVal ;
665   if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
666     RetVal = false ;
667   }
668   else {
669     ControlState( SUPERV::ToSuspendDoneState ) ;
670     if ( IsDone() ) {
671       if ( _OutNode->IsDone() ) {
672         ControlState( SUPERV::VoidState ) ;
673       }
674       RetVal = false ;
675     }
676     else {
677       RetVal = true ;
678     }
679   }
680   cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
681   return RetVal ;
682 }
683
684 bool GraphExecutor::InNode::Resume() {
685   cdebug_in << pthread_self() << "/" << ThreadNo()
686             << " GraphExecutor::InNode::Resume " << Name() << " "
687             << Automaton()->StateName( State() ) << endl;
688   bool RetVal = false ;
689   if ( IsSuspended() ) {
690     if ( State() == SUPERV::SuspendedReadyState ) {
691       ResumeAction( GraphExecutor::ToResumeEvent ) ;
692       RetVal = true ;
693     }
694     else if ( State() == SUPERV::SuspendedExecutingState ) {
695       if ( IsFactoryNode() || IsComputingNode() ) {
696         RetVal = Component()->Resume_impl() ;
697       }
698     }
699     else if ( State() == SUPERV::SuspendedSuccessedState ) {
700       ResumeAction( GraphExecutor::ResumeEvent ) ;
701       RetVal = true ;
702     }
703     else if ( State() == SUPERV::SuspendedErroredState ) {
704       ResumeAction( GraphExecutor::ResumeEvent ) ;
705       RetVal = true ;
706     }
707     else {
708       cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
709              << Automaton()->StateName( State() ) << endl ;
710       RetVal = false ;
711     }
712   }
713   else {
714     cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
715            << Automaton()->StateName( State() ) << endl ;
716     RetVal = false ;
717   }
718   if ( ControlState() == SUPERV::ToSuspendStartState ) {
719     ControlState( SUPERV::VoidState ) ;
720   }
721
722 #if 0
723   if ( ControlState() == SUPERV::ToSuspendRunState ||
724        ( ControlState() == SUPERV::ToSuspendState &&
725          State() == SUPERV::SuspendedReadyState) ) {
726     if ( IsSuspended() ) {
727       if ( State() == SUPERV::SuspendedReadyState ) {
728         ResumeAction() ;
729         RetVal = true ;
730       }
731       else if ( State() == SUPERV::SuspendedExecutingState ) {
732         ResumeAction() ;
733         RetVal = Component()->Resume_impl() ;
734       }
735       else {
736         cdebug << "GraphExecutor::InNode::Resume State "
737                << Automaton()->StateName( State() ) << endl ;
738         RetVal = false ;
739       }
740       if ( ControlState() != SUPERV::ToSuspendState ) {
741         ControlState( SUPERV::VoidState ) ;
742       }
743     }
744     else if ( IsRunning() ) {
745       RetVal = true ;
746     }
747     else if ( IsWaiting() ) {
748       ControlState( SUPERV::VoidState ) ;
749       RetVal = true ;
750     }
751     else if ( IsDone() ) {
752       RetVal = true ;
753     }
754   }
755   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
756             ( ControlState() == SUPERV::ToSuspendState &&
757               State() == SUPERV::SuspendedSuccessedState) ) {
758     if ( IsSuspended() ) {
759       if ( State() == SUPERV::SuspendedSuccessedState ) {
760         ResumeAction() ;
761         RetVal = true ;
762       }
763       else if ( State() == SUPERV::SuspendedErroredState ) {
764         ResumeAction() ;
765         RetVal = true ;
766       }
767       else {
768         cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
769         RetVal = false ;
770       }
771       if ( ControlState() != SUPERV::ToSuspendState ) {
772         ControlState( SUPERV::VoidState ) ;
773       }
774     }
775     else if ( IsRunning() ) {
776       ControlState( SUPERV::VoidState ) ;
777       RetVal = true ;
778     }
779     else if ( IsWaiting() ) {
780       ControlState( SUPERV::VoidState ) ;
781       RetVal = true ;
782     }
783     else if ( IsDone() ) {
784       ControlState( SUPERV::VoidState ) ;
785       RetVal = true ;
786     }
787   }
788 #endif
789   cdebug_out << "GraphExecutor::InNode::Resume " << RetVal << endl ;
790   return RetVal ;
791 }
792
793 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
794                                      const bool AndSuspend ) {
795   bool RetVal = false ;
796   GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->GetGraphNode( AtNodeName )->GetInNode() ;
797   cdebug_in << pthread_self() << "/" << ThreadNo()
798             << " --> GraphExecutor::InNode::ReStartAt( "
799             << AtNodeName << " , " << AndSuspend << ") " << endl
800             << "thread " << aRestartNode->ThreadNo() << " "
801             << Automaton()->StateName( aRestartNode->State() )
802             << " from " << Name() << " " << Automaton()->StateName( State() )
803             << endl ;
804   if ( IsWaiting() && aRestartNode->IsSuspended() ) {
805     RetVal = aRestartNode->Resume() ;
806   }
807   else if ( IsSuspended() ) {
808     if ( strcmp( AtNodeName , Name() ) ) {
809       aRestartNode->State( SUPERV::SuspendedSuccessedState ) ;
810     }
811     if ( AndSuspend ) {
812       ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
813     }
814     else {
815       ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
816     }
817     RetVal = true ;
818   }
819   cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << endl ;
820   return RetVal ;
821 }
822
823 bool GraphExecutor::InNode::IsWaiting() {
824   bool aret = false ;
825 //  cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
826   SUPERV::AutomatonState aState = State() ;
827   if ( aState == SUPERV::DataUndefState ||
828        aState == SUPERV::DataWaitingState ||
829        aState == SUPERV::SuspendedReadyState )
830 //       aState == SUPERV::SuspendedExecutingState ||
831 //       aState == SUPERV::SuspendedSuccessedState ||
832 //       aState == SUPERV::SuspendedErroredState ||
833 //       aState == SUPERV::SuspendedState
834     aret = true ;
835 //  cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
836   return aret ;
837 }
838
839 bool GraphExecutor::InNode::IsReady() {
840   bool aret = false ;
841 //  cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
842   SUPERV::AutomatonState aState = State() ;
843   if ( aState == SUPERV::DataUndefState ||
844        aState == SUPERV::DataWaitingState ||
845        aState == SUPERV::DataReadyState ||
846        aState == SUPERV::ResumedReadyState )
847     aret = true ;
848 //  cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
849   return aret ;
850 }
851
852 bool GraphExecutor::InNode::IsRunning() {
853   bool aret = false ;
854 //  cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
855   SUPERV::AutomatonState aState = State() ;
856   if ( aState == SUPERV::ExecutingState ||
857        aState == SUPERV::ResumedExecutingState )
858     aret = true ;
859 //  cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
860   return aret ;
861 }
862
863 bool GraphExecutor::InNode::IsDone() {
864   bool aret = false ;
865 //  cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
866   SUPERV::AutomatonState aState = State() ;
867   if ( aState == SUPERV::KilledReadyState ||
868        aState == SUPERV::StoppedReadyState ||
869        aState == SUPERV::KilledExecutingState ||
870        aState == SUPERV::StoppedExecutingState ||
871        aState == SUPERV::SuspendedSuccessedState ||
872        aState == SUPERV::SuspendedErroredState ||
873 //       aState == SUPERV::SuccessedExecutingState ||
874 //       aState == SUPERV::ErroredExecutingState ||
875        aState == SUPERV::SuccessedState ||
876        aState == SUPERV::ErroredState ||
877        aState == SUPERV::ResumedSuccessedState ||
878        aState == SUPERV::ResumedErroredState ||
879        aState == SUPERV::KilledSuccessedState ||
880        aState == SUPERV::StoppedSuccessedState )
881     aret = true ;
882 //  cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
883   return aret ;
884 }
885
886 bool GraphExecutor::InNode::IsSuspended() {
887   bool aret = false ;
888 //  cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
889   SUPERV::AutomatonState aState = State() ;
890   if ( aState == SUPERV::SuspendedReadyState ||
891        aState == SUPERV::SuspendedExecutingState ||
892        aState == SUPERV::SuspendedSuccessedState ||
893        aState == SUPERV::SuspendedErroredState )
894     aret = true ;
895 //  cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
896   return aret ;
897 }
898 bool GraphExecutor::InNode::IsKilled() {
899   bool aret = false ;
900 //  cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
901   SUPERV::AutomatonState aState = State() ;
902   if ( aState == SUPERV::KilledReadyState ||
903        aState == SUPERV::KilledExecutingState ||
904        aState == SUPERV::KilledSuccessedState ||
905        aState == SUPERV::KilledErroredState ||
906        aState == SUPERV::KilledState )
907     aret = true ;
908 //  cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
909   return aret ;
910 }
911 bool GraphExecutor::InNode::IsStopped() {
912   bool aret = false ;
913 //  cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
914   SUPERV::AutomatonState aState = State() ;
915   if ( aState == SUPERV::StoppedReadyState ||
916        aState == SUPERV::StoppedExecutingState ||
917        aState == SUPERV::StoppedSuccessedState ||
918        aState == SUPERV::StoppedErroredState ||
919        aState == SUPERV::StoppedState )
920     aret = true ;
921 //  cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
922   return aret ;
923 }
924
925 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
926   bool RetVal = false ;
927   if ( pthread_mutex_lock( &_MutexWait ) ) {
928     perror("pthread_mutex_lock _Wait") ;
929     exit( 0 ) ;
930   }
931   switch ( aState ) {
932   case SUPERV::ReadyState : {
933     RetVal = IsReady() ;
934     cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
935               << " " << Automaton()->StateName( _currentState )
936               << " pthread_cond_wait _ReadyWait " << Name() << endl ;
937     while ( !RetVal && !IsDone() ) {
938       cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
939       pthread_cond_wait( &_ReadyWait , &_MutexWait );
940       RetVal = IsReady() ;
941       cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
942              << Automaton()->StateName( _currentState ) << " " << RetVal
943              << endl ;
944     }
945     cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
946                << " " << Automaton()->StateName( _currentState )
947                << " pthread_cond_wait _ReadyWait " << Name() << endl ;
948     break ;
949   }
950   case SUPERV::RunningState : {
951     RetVal = IsRunning() ;
952     cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
953               << " " << Automaton()->StateName( _currentState )
954               << " pthread_cond_wait _RunningWait " << Name() << endl ;
955     while ( !RetVal && !IsDone() ) {
956       cdebug << pthread_self() << " pthread_cond_wait RunningWait" << endl ;
957       pthread_cond_wait( &_RunningWait , &_MutexWait );
958       RetVal = IsRunning() ;
959       cdebug << pthread_self() << " pthread_cond_waited RunningWait "
960              << Automaton()->StateName( _currentState ) << " " << RetVal
961              << endl ;
962     }
963     cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
964                << " " << Automaton()->StateName( _currentState )
965                << " pthread_cond_wait _RunningWait " << Name() << endl ;
966     break ;
967   }
968   case SUPERV::DoneState : {
969     RetVal = IsDone() ;
970     cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
971               << " " << Automaton()->StateName( _currentState )
972               << " pthread_cond_wait _DoneWait " << Name() << endl ;
973     while ( !RetVal ) {
974       cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
975       pthread_cond_wait( &_DoneWait , &_MutexWait );
976       RetVal = IsDone() ;
977       cdebug << pthread_self() << " pthread_cond_waited DoneWait "
978              << Automaton()->StateName( _currentState ) << " " << RetVal
979              << endl ;
980     }
981     cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
982                << " " << Automaton()->StateName( _currentState )
983                << " pthread_cond_wait _DoneWait " << Name() << endl ;
984     break ;
985   }
986   case SUPERV::SuspendState : {
987     RetVal = IsSuspended() ;
988     cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
989               << " " << Automaton()->StateName( _currentState )
990               << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
991     while ( !RetVal && !IsDone() ) {
992       cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
993       pthread_cond_wait( &_SuspendedWait , &_MutexWait );
994       RetVal = IsSuspended() ;
995       cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
996              << Automaton()->StateName( _currentState ) << " " << RetVal
997              << endl ;
998     }
999     cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1000                << " " << Automaton()->StateName( _currentState )
1001                << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1002     break ;
1003   }
1004   default : {
1005     cdebug << " GraphExecutor::OutNode::StateWait Error Undefined State : "
1006            << aState << endl ;
1007   }
1008   }
1009   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1010     perror("pthread_mutex_lock _Wait") ;
1011     exit( 0 ) ;
1012   }
1013   return RetVal ;
1014 }
1015
1016 bool GraphExecutor::InNode::ReadyWait() {
1017 //  cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1018   bool aret ;
1019   aret = StateWait( SUPERV::ReadyState ) ;
1020 //  cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1021   return aret ;
1022 }
1023
1024 bool GraphExecutor::InNode::RunningWait() {
1025 //  cdebug_in << "GraphExecutor::InNode::RunningWait " << Name() << endl;
1026   bool aret ;
1027   aret = StateWait( SUPERV::RunningState ) ;
1028   return aret ;
1029 }
1030
1031 bool GraphExecutor::InNode::DoneWait() {
1032 //  cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1033   bool aret ;
1034   aret = StateWait( SUPERV::DoneState ) ;
1035   return aret ;
1036 }
1037
1038 bool GraphExecutor::InNode::SuspendedWait() {
1039 //  cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1040   bool aret ;
1041   aret = StateWait( SUPERV::SuspendState ) ;
1042   return aret ;
1043 }
1044
1045 void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
1046 {
1047   cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1048
1049   _OutNode = theOutNode ;
1050
1051   int i;
1052   _ControlState = SUPERV::VoidState ;
1053   CreateNewThread( false ) ;
1054   CreateNewThreadIf( false ) ;
1055   _SuspendSync = false ;
1056   _ResumeSync = false ;
1057 //  ThreadNo( pthread_self() ) ;
1058   ThreadNo( 0 ) ;
1059
1060   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1061     if ( i != 0 || !IsGOTONode() ) {
1062       GetChangeNodeOutPort(i)->State(  SUPERV::WaitingState ) ;
1063       GetChangeNodeOutPort(i)->Done( false ) ;
1064     }
1065   }
1066
1067   int Pc = GetNodeInPortsSize() ;
1068   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1069     const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1070     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1071     if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1072       anOutPort->PortStatus( DataConnected );
1073       anOutPort->State( SUPERV::ReadyState ) ;
1074       anOutPort->Done( true ) ;
1075       CORBA::Any * anAny = new CORBA::Any() ;
1076       *anAny <<= (long ) 1 ;
1077       anOutPort->Value( anAny ) ;
1078     }
1079     else if ( anInPort->IsGate() && anOutPort ) {
1080       if ( IsComputingNode() || IsFactoryNode() ) {
1081         anOutPort->State( SUPERV::WaitingState ) ;
1082         anOutPort->Done( false ) ;
1083       }
1084       else if ( IsOneOfInLineNodes() ) {
1085         anOutPort->PortStatus( DataConnected );
1086         anOutPort->State( SUPERV::ReadyState ) ;
1087         anOutPort->Done( true ) ;
1088       }
1089     }
1090 //    if ( ( anInPort->IsGate() || anInPort->IsBus() ) && anOutPort == NULL ) {
1091     if ( anInPort->IsGate() && anOutPort == NULL ) {
1092       Pc-- ;
1093     }
1094     else {
1095       if ( anOutPort->IsDataConnected() ) {
1096         Pc-- ;
1097       }
1098       if ( anOutPort->IsPortConnected() ) {
1099         anOutPort->State( SUPERV::WaitingState ) ;
1100         anOutPort->Done( false ) ;
1101       }
1102       else if ( anOutPort->IsDataConnected() ) {
1103         anOutPort->State( SUPERV::ReadyState ) ;
1104         anOutPort->Done( true ) ;
1105       }
1106     }
1107     if ( anOutPort ) {
1108       GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1109     }
1110     if ( anOutPort ) {
1111       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1112              << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1113              << " with state " ;
1114       if ( anOutPort->State() == SUPERV::WaitingState ) {
1115         cdebug << "WaitingState" ;
1116       }
1117       else if ( anOutPort->State() == SUPERV::ReadyState ) {
1118         cdebug << "ReadyState" ;
1119       }
1120       else {
1121         cdebug << "???" ;
1122       }
1123       cdebug << " PortConnected("
1124              << anOutPort->IsPortConnected() << ") DataConnected("
1125              << anOutPort->IsDataConnected() << ")" << endl ;
1126     }
1127   }
1128
1129   _currentState = Pc > 0 ? SUPERV::DataWaitingState 
1130                          : SUPERV::DataReadyState ;
1131   if ( Pc == GetNodeInPortsSize() ) {
1132     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1133                          _currentState ) ; 
1134   }
1135   else if ( Pc != 0 ) {
1136     _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1137                          _currentState ) ; 
1138   }
1139   else {
1140     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1141                          _currentState ) ; 
1142   }
1143   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1144          << endl;
1145
1146   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1147 }
1148
1149 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1150   cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
1151   bool Err = false ;
1152   if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1153     if ( IsLoopNode() ) {
1154       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1155       if ( PyRunMethod ) {
1156       }
1157       else {
1158         PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1159                                                   InLineNode()->PythonFunction() ) ;
1160         InLineNode()->PyRunMethod( PyRunMethod ) ;
1161       }
1162       PyObject * PyMoreMethod = LoopNode()->PyMoreMethod() ;
1163       if ( PyMoreMethod ) {
1164       }
1165       else {
1166         PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1167                                         LoopNode()->MorePythonFunction() ) ;
1168         LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1169       }
1170       PyObject * PyNextMethod = LoopNode()->PyNextMethod() ;
1171       if ( PyNextMethod ) {
1172       }
1173       else {
1174         PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1175                                         LoopNode()->NextPythonFunction() ) ;
1176         LoopNode()->PyNextMethod( PyNextMethod ) ;
1177       }
1178       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1179              << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1180       Err = !PyRunMethod || !PyMoreMethod || !PyNextMethod ;
1181     }
1182     else if ( IsInLineNode() || IsSwitchNode() ) {
1183       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1184       if ( PyRunMethod ) {
1185       }
1186       else {
1187         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1188                                        InLineNode()->PythonFunction() ) ;
1189         InLineNode()->PyRunMethod( PyRunMethod ) ;
1190       }
1191       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1192       Err = !PyRunMethod ;
1193     }
1194     else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1195               (*InLineNode()->PythonFunction()).length() ) {
1196       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1197       if ( PyRunMethod ) {
1198       }
1199       else {
1200         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1201                                        InLineNode()->PythonFunction() ) ;
1202         InLineNode()->PyRunMethod( PyRunMethod ) ;
1203       }
1204       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1205       Err = !PyRunMethod ;
1206     }
1207   }
1208   Err = WithErr && Err ;
1209   cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1210   if ( Err ) {
1211     cdebug << " Error " << Err ;
1212   }
1213   cdebug << endl;
1214   return Err ;
1215 }
1216
1217 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1218   CORBA::Long cpu = 0 ;
1219 //  cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1220   if ( IsOneOfInLineNodes() ) {
1221 //    cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1222 //    cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1223     cpu = PyCpuUsed( tot ) ;
1224   }
1225   else {
1226     if ( !CORBA::is_nil( Component() ) ) {
1227 //      cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1228 //      cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1229       try {
1230         cpu = Component()->CpuUsed_impl() ;
1231       }
1232       catch ( ... ) {
1233         cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1234         cpu = 0 ;
1235       }
1236     }
1237   }
1238 //  cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1239 //  cout << "CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1240   return cpu ;
1241 }
1242
1243 #include <sys/time.h>
1244 #include <sys/resource.h>
1245 #include <unistd.h>
1246
1247 long GraphExecutor::InNode::PyCpu() {
1248   struct rusage usage ;
1249   long cpu ;
1250   if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1251     perror("GraphExecutor::InNode::PyCpu") ;
1252     return 0 ;
1253   }
1254 //  return usage.ru_utime.__time_t tv_sec ;
1255 //  cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1256 //         << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1257 //         << endl ;
1258   cpu = usage.ru_utime.tv_sec ;
1259   return cpu ;
1260 }
1261
1262 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1263   long cpu ;
1264   if ( _PyTotCpuUsed == -1 ) {
1265     if ( _Pythread == pthread_self() ) {
1266 //      cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1267 //             << " _PyTotCpuUsed " <<  _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1268 //             << _PyCpuUsed << endl ;
1269       cpu = PyCpu() - _PyCpuUsed ;
1270       if ( tot ) {
1271         _PyTotCpuUsed = cpu ;
1272       }
1273     }
1274     else {
1275       cpu = 0 ;
1276     }
1277   }
1278   else {
1279     cpu = _PyTotCpuUsed ;
1280   }
1281 //  cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1282 //         <<  _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1283   return cpu ;
1284 }
1285
1286 void GraphExecutor::InNode::SetPyCpuUsed() {
1287   _PyTotCpuUsed = -1 ;
1288   _PyCpuUsed = 0 ;
1289   _Pythread = pthread_self() ;
1290   _PyCpuUsed = PyCpu() ;
1291 //  cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1292 //         << _PyCpuUsed << endl ;
1293 }
1294