Salome HOME
DCQ : Merge with Ecole_Ete_a6.
[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::DataFlowGraph : {
349     cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
350   }
351   case SUPERV::DataStreamGraph : {
352     cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
353   }
354   case SUPERV::UnknownNode : {
355     cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
356   }
357   }
358   cdebug << "GraphExecutor::InNode::InNode "  << (void *) this
359          << " _ComputingNode " << (void *) _ComputingNode  ;
360   _ComputingNode->InNode( this ) ;
361 }
362
363 GraphExecutor::InNode::~InNode() {
364 }
365
366 void GraphExecutor::InNode::LockDataWait() {
367   if ( pthread_mutex_lock( &_MutexDataWait ) ) {
368     perror("Ready pthread_mutex_lock ") ;
369     exit( 0 ) ;
370   }
371   _DataWait = true ;
372 }
373 void GraphExecutor::InNode::UnLockDataWait() {
374   _DataWait = false ;
375   if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
376     perror("Ready pthread_mutex_unlock ") ;
377     exit( 0 ) ;
378   }
379 }
380
381 Engines::Component_var GraphExecutor::InNode::Component() const {
382   if ( IsFactoryNode() ) {
383     return _FactoryNode->Component() ;
384   }
385   else {
386     CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
387     CORBA::Object_ptr obj ;
388     try {
389       *anAnyComponent >>= obj ;
390       return Engines::Component::_narrow( obj ) ;
391     }
392     catch( ... ) {
393       cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
394     }
395   }
396   return Engines::Component::_nil() ;
397 }
398
399 Engines::Container_var GraphExecutor::InNode::Container() const {
400   if ( IsFactoryNode() ) {
401     return _FactoryNode->Container() ;
402   }
403   return Engines::Container::_nil() ;
404 }
405
406
407 bool GraphExecutor::InNode::Ping() {
408 //  cdebug_in << "GraphExecutor::InNode::Ping" << endl;
409   bool RetVal ;
410   if ( IsFactoryNode() ) {
411     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
412     if ( RetVal ) {
413       if ( State() != SUPERV::SuspendedExecutingState ) {
414         try {
415           _FactoryNode->Component()->ping() ;
416         }
417         catch( ... ) {
418           cdebug << "InNode::Ping() catched" << endl ;
419           State( SUPERV::ErroredState ) ;
420           _OutNode->State( SUPERV::ErroredState ) ;
421           RetVal = false ;
422         }
423       }
424       else {
425         RetVal = false ;
426       }
427     }
428   }
429 //  cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
430   return RetVal ;
431 }
432
433 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
434   ThreadNo ( aThread ) ; 
435   if ( aThread )
436     _OutNode->NewThread() ;
437 }
438 void GraphExecutor::InNode::ExitThread() {
439   ThreadNo( 0 ) ;
440   _OutNode->ExitThread() ;
441
442
443 bool GraphExecutor::InNode::Suspend() {
444   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
445             << endl;
446   bool RetVal ;
447   if ( IsDone() ) {
448     ControlState( SUPERV::VoidState ) ;
449     if ( _OutNode->IsDone() ) {
450       ControlState( SUPERV::VoidState ) ;
451     }
452     RetVal = false ;
453   }
454   else if ( IsWaiting() || IsReady() ) {
455     ControlState( SUPERV::ToSuspendState ) ;
456     RetVal = true ;
457   }
458   else  if ( IsRunning() ) {
459     ControlState( SUPERV::ToSuspendState ) ;
460     if ( IsFactoryNode() || IsComputingNode() ) {
461       if ( !CORBA::is_nil( Component() ) ) {
462         try {
463           RetVal = Component()->Suspend_impl() ;
464         }
465         catch( ... ) {
466           cdebug << "InNode::Suspend() catched" << endl ;
467           State( SUPERV::ErroredState ) ;
468           _OutNode->State( SUPERV::ErroredState ) ;
469           RetVal = false ;
470         }
471         if ( RetVal ) {
472           if ( IsRunning() ) {
473             cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
474                    << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
475             SendEvent( GraphExecutor::SuspendEvent ) ;
476             cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
477                    << Name() << " --> thread" << ThreadNo() << endl;
478           }
479           else if ( IsDone() ) {
480             ControlState( SUPERV::VoidState ) ;
481             RetVal = false ; // Too late ...
482           }
483           else {
484             cdebug << "component Suspended and !IsDone and !IsRunning !"
485                    << endl ;
486           }
487         }
488       }
489       else {
490         cdebug << "Suspend cannot Suspend component !" << endl ;
491         RetVal = false ;
492       }
493     }
494     else {
495       cdebug << "Suspend with nilComponent while RunningState !" << endl ;
496       RetVal = false ;
497     }
498   }
499   else {
500     cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
501            << endl ;
502     RetVal = false ;
503   }
504   cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
505              << Automaton()->StateName( State() ) << endl ;
506   return RetVal ;
507 }
508
509 bool GraphExecutor::InNode::ContainerKill() {
510   cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
511             << ThreadNo() << endl;
512   bool RetVal ;
513   if ( IsFactoryNode() ) {
514     Kill() ;
515     RetVal = Container()->Kill_impl() ;
516   }
517   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
518   return RetVal ;
519 }
520
521 bool GraphExecutor::InNode::Kill() {
522   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
523             << Automaton()->StateName( State() ) << endl;
524   bool RetVal ;
525   if ( IsDone() ) {
526     ControlState( SUPERV::ToKillState ) ; // if loop
527     if ( _OutNode->IsDone() ) {
528       ControlState( SUPERV::VoidState ) ;
529     }
530     RetVal = false ;
531   }
532   else {
533     ControlState( SUPERV::ToKillState ) ;
534     if ( IsDone() ) {
535       if ( _OutNode->IsDone() ) {
536         ControlState( SUPERV::VoidState ) ;
537       }
538       RetVal = false ;
539     }
540     else {
541       if ( IsRunning() ) {
542         if ( IsFactoryNode() || IsComputingNode() ) {
543           if ( !CORBA::is_nil( Component() ) ) {
544             try {
545               RetVal = Component()->Kill_impl() ;
546             }
547             catch( ... ) {
548               cdebug << "InNode::Suspend() catched" << endl ;
549               State( SUPERV::ErroredState ) ;
550               _OutNode->State( SUPERV::ErroredState ) ;
551               RetVal = false ;
552             }
553             cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
554             RetVal = true ;
555             if ( IsRunning() ) {
556               cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
557                      << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
558               SendEvent( GraphExecutor::KillEvent ) ;
559               cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
560                      << Name() << " --> thread" << ThreadNo() << endl;
561             }
562             else if ( IsDone() ) {
563               ControlState( SUPERV::VoidState ) ;
564               RetVal = false ; // Too late ...
565             }
566             else {
567               cdebug << "component Killed and !IsDone and !IsRunning !"
568                      << endl ;
569             }
570           }
571           else {
572             cdebug << "Kill with nilComponent cannot Kill component !" << endl ;
573             RetVal = false ;
574           }
575         }
576       }
577       else if ( IsSuspended() ) {
578         cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
579                << " --> thread" << ThreadNo() << " Resume()" << endl;
580         Resume() ;
581         RetVal = true ;
582       }
583       else if ( IsWaiting() ) {
584         RetVal = true ;
585       }
586       else {
587         cdebug << "Kill and !IsDone and !IsRunning and !IsWaiting ?"
588                << endl ;
589         RetVal = false ;
590       }
591     }
592   }
593   cdebug_out << "GraphExecutor::InNode::Kill" << endl ;
594   return RetVal ;
595 }
596
597 bool GraphExecutor::InNode::KillDone() {
598   cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
599             << endl;
600   bool RetVal ;
601   if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
602     RetVal = false ;
603   }
604   else {
605     ControlState( SUPERV::ToKillDoneState ) ;
606     if ( IsDone() ) {
607       if ( _OutNode->IsDone() ) {
608         ControlState( SUPERV::VoidState ) ;
609       }
610       RetVal = false ;
611     }
612     else {
613       if ( IsRunning() ) {
614         RetVal = true ;
615       }
616       else if ( IsWaiting() ) {
617         RetVal = true ;
618       }
619       else {
620         cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
621                << endl ;
622         RetVal = false ;
623       }
624     }
625   }
626   cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
627   return RetVal ;
628 }
629
630 bool GraphExecutor::InNode::Stop() {
631   cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
632             << endl;
633   bool RetVal ;
634   if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
635     RetVal = false ;
636   }
637   else {
638     ControlState( SUPERV::ToStopState ) ;
639     if ( IsDone() ) {
640       if ( _OutNode->IsDone() ) {
641         ControlState( SUPERV::VoidState ) ;
642       }
643       RetVal = false ;
644     }
645     else {
646       if ( IsRunning() ) {
647         if ( IsFactoryNode() || IsComputingNode() ) {
648           if ( !CORBA::is_nil( Component() ) ) {
649             try {
650               RetVal = Component()->Stop_impl() ;
651             }
652             catch( ... ) {
653               cdebug << "InNode::Stop() catched" << endl ;
654               State( SUPERV::ErroredState ) ;
655               _OutNode->State( SUPERV::ErroredState ) ;
656               RetVal = false ;
657             }
658             if ( RetVal ) {
659               if ( IsRunning() ) {
660                 SendEvent( GraphExecutor::StopEvent ) ;
661               }
662               else if ( IsDone() ) {
663                 ControlState( SUPERV::VoidState ) ;
664                 RetVal = false ; // Too late ...
665               }
666               else {
667                 cdebug << "component Suspended and !IsDone and !IsRunning !"
668                        << endl ;
669               }
670             }
671           }
672           else {
673             cdebug << "Suspend cannot Suspend component !" << endl ;
674             RetVal = false ;
675           }
676         }
677         else {
678           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
679           RetVal = false ;
680         }
681       }
682       else if ( IsWaiting() ) {
683         RetVal = true ;
684       }
685       else {
686         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
687                << endl ;
688         RetVal = false ;
689       }
690     }
691   }
692   cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
693   return RetVal ;
694 }
695
696 bool GraphExecutor::InNode::SuspendDone() {
697   cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
698             << ThreadNo() << endl;
699   bool RetVal ;
700   if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
701     RetVal = false ;
702   }
703   else {
704     ControlState( SUPERV::ToSuspendDoneState ) ;
705     if ( IsDone() ) {
706       if ( _OutNode->IsDone() ) {
707         ControlState( SUPERV::VoidState ) ;
708       }
709       RetVal = false ;
710     }
711     else {
712       RetVal = true ;
713     }
714   }
715   cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
716   return RetVal ;
717 }
718
719 bool GraphExecutor::InNode::Resume() {
720   cdebug_in << pthread_self() << "/" << ThreadNo()
721             << " GraphExecutor::InNode::Resume " << Name() << " "
722             << Automaton()->StateName( State() ) << endl;
723   bool RetVal = false ;
724   if ( IsSuspended() ) {
725     if ( State() == SUPERV::SuspendedReadyState ) {
726       ResumeAction( GraphExecutor::ToResumeEvent ) ;
727       RetVal = true ;
728     }
729     else if ( State() == SUPERV::SuspendedExecutingState ) {
730       if ( IsFactoryNode() || IsComputingNode() ) {
731         try {
732           RetVal = Component()->Resume_impl() ;
733         }
734         catch( ... ) {
735           cdebug << "InNode::Resume() catched" << endl ;
736           State( SUPERV::ErroredState ) ;
737           _OutNode->State( SUPERV::ErroredState ) ;
738           RetVal = false ;
739         }
740       }
741     }
742     else if ( State() == SUPERV::SuspendedSuccessedState ) {
743       ResumeAction( GraphExecutor::ResumeEvent ) ;
744       RetVal = true ;
745     }
746     else if ( State() == SUPERV::SuspendedErroredState ) {
747       ResumeAction( GraphExecutor::ResumeEvent ) ;
748       RetVal = true ;
749     }
750     else {
751       cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
752              << Automaton()->StateName( State() ) << endl ;
753       RetVal = false ;
754     }
755   }
756   else {
757     cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
758            << Automaton()->StateName( State() ) << endl ;
759     RetVal = false ;
760   }
761   if ( ControlState() == SUPERV::ToSuspendStartState ) {
762     ControlState( SUPERV::VoidState ) ;
763   }
764
765 #if 0
766   if ( ControlState() == SUPERV::ToSuspendRunState ||
767        ( ControlState() == SUPERV::ToSuspendState &&
768          State() == SUPERV::SuspendedReadyState) ) {
769     if ( IsSuspended() ) {
770       if ( State() == SUPERV::SuspendedReadyState ) {
771         ResumeAction() ;
772         RetVal = true ;
773       }
774       else if ( State() == SUPERV::SuspendedExecutingState ) {
775         ResumeAction() ;
776         RetVal = Component()->Resume_impl() ;
777       }
778       else {
779         cdebug << "GraphExecutor::InNode::Resume State "
780                << Automaton()->StateName( State() ) << endl ;
781         RetVal = false ;
782       }
783       if ( ControlState() != SUPERV::ToSuspendState ) {
784         ControlState( SUPERV::VoidState ) ;
785       }
786     }
787     else if ( IsRunning() ) {
788       RetVal = true ;
789     }
790     else if ( IsWaiting() ) {
791       ControlState( SUPERV::VoidState ) ;
792       RetVal = true ;
793     }
794     else if ( IsDone() ) {
795       RetVal = true ;
796     }
797   }
798   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
799             ( ControlState() == SUPERV::ToSuspendState &&
800               State() == SUPERV::SuspendedSuccessedState) ) {
801     if ( IsSuspended() ) {
802       if ( State() == SUPERV::SuspendedSuccessedState ) {
803         ResumeAction() ;
804         RetVal = true ;
805       }
806       else if ( State() == SUPERV::SuspendedErroredState ) {
807         ResumeAction() ;
808         RetVal = true ;
809       }
810       else {
811         cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
812         RetVal = false ;
813       }
814       if ( ControlState() != SUPERV::ToSuspendState ) {
815         ControlState( SUPERV::VoidState ) ;
816       }
817     }
818     else if ( IsRunning() ) {
819       ControlState( SUPERV::VoidState ) ;
820       RetVal = true ;
821     }
822     else if ( IsWaiting() ) {
823       ControlState( SUPERV::VoidState ) ;
824       RetVal = true ;
825     }
826     else if ( IsDone() ) {
827       ControlState( SUPERV::VoidState ) ;
828       RetVal = true ;
829     }
830   }
831 #endif
832   cdebug_out << "GraphExecutor::InNode::Resume " << RetVal << endl ;
833   return RetVal ;
834 }
835
836 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
837                                      const bool AndSuspend ) {
838   bool RetVal = false ;
839   GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetGraphNode( AtNodeName )->GetInNode() ;
840   cdebug_in << pthread_self() << "/" << ThreadNo()
841             << " --> GraphExecutor::InNode::ReStartAt( "
842             << AtNodeName << " , " << AndSuspend << ") " << endl
843             << "thread " << aRestartNode->ThreadNo() << " "
844             << Automaton()->StateName( aRestartNode->State() )
845             << " from " << Name() << " " << Automaton()->StateName( State() )
846             << endl ;
847   if ( IsWaiting() && aRestartNode->IsSuspended() ) {
848     RetVal = aRestartNode->Resume() ;
849   }
850   else if ( IsSuspended() ) {
851     if ( strcmp( AtNodeName , Name() ) ) {
852       aRestartNode->State( SUPERV::SuspendedSuccessedState ) ;
853     }
854     if ( AndSuspend ) {
855       ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
856     }
857     else {
858       ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
859     }
860     RetVal = true ;
861   }
862   cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << endl ;
863   return RetVal ;
864 }
865
866 bool GraphExecutor::InNode::IsWaiting() {
867   bool aret = false ;
868 //  cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
869   SUPERV::AutomatonState aState = State() ;
870   if ( aState == SUPERV::DataUndefState ||
871        aState == SUPERV::DataWaitingState ||
872        aState == SUPERV::SuspendedReadyState )
873 //       aState == SUPERV::SuspendedExecutingState ||
874 //       aState == SUPERV::SuspendedSuccessedState ||
875 //       aState == SUPERV::SuspendedErroredState ||
876 //       aState == SUPERV::SuspendedState
877     aret = true ;
878 //  cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
879   return aret ;
880 }
881
882 bool GraphExecutor::InNode::IsReady() {
883   bool aret = false ;
884 //  cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
885   SUPERV::AutomatonState aState = State() ;
886   if ( aState == SUPERV::DataUndefState ||
887        aState == SUPERV::DataWaitingState ||
888        aState == SUPERV::DataReadyState ||
889        aState == SUPERV::ResumedReadyState )
890     aret = true ;
891 //  cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
892   return aret ;
893 }
894
895 bool GraphExecutor::InNode::IsRunning() {
896   bool aret = false ;
897 //  cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
898   SUPERV::AutomatonState aState = State() ;
899   if ( aState == SUPERV::ExecutingState ||
900        aState == SUPERV::ResumedExecutingState )
901     aret = true ;
902 //  cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
903   return aret ;
904 }
905
906 bool GraphExecutor::InNode::IsDone() {
907   bool aret = false ;
908 //  cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
909   SUPERV::AutomatonState aState = State() ;
910   if ( aState == SUPERV::KilledReadyState ||
911        aState == SUPERV::StoppedReadyState ||
912        aState == SUPERV::KilledExecutingState ||
913        aState == SUPERV::StoppedExecutingState ||
914        aState == SUPERV::SuspendedSuccessedState ||
915        aState == SUPERV::SuspendedErroredState ||
916 //       aState == SUPERV::SuccessedExecutingState ||
917 //       aState == SUPERV::ErroredExecutingState ||
918        aState == SUPERV::SuccessedState ||
919        aState == SUPERV::ErroredState ||
920        aState == SUPERV::ResumedSuccessedState ||
921        aState == SUPERV::ResumedErroredState ||
922        aState == SUPERV::KilledSuccessedState ||
923        aState == SUPERV::StoppedSuccessedState )
924     aret = true ;
925 //  cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
926   return aret ;
927 }
928
929 bool GraphExecutor::InNode::IsSuspended() {
930   bool aret = false ;
931 //  cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
932   SUPERV::AutomatonState aState = State() ;
933   if ( aState == SUPERV::SuspendedReadyState ||
934        aState == SUPERV::SuspendedExecutingState ||
935        aState == SUPERV::SuspendedSuccessedState ||
936        aState == SUPERV::SuspendedErroredState )
937     aret = true ;
938 //  cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
939   return aret ;
940 }
941 bool GraphExecutor::InNode::IsKilled() {
942   bool aret = false ;
943 //  cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
944   SUPERV::AutomatonState aState = State() ;
945   if ( aState == SUPERV::KilledReadyState ||
946        aState == SUPERV::KilledExecutingState ||
947        aState == SUPERV::KilledSuccessedState ||
948        aState == SUPERV::KilledErroredState ||
949        aState == SUPERV::KilledState )
950     aret = true ;
951 //  cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
952   return aret ;
953 }
954 bool GraphExecutor::InNode::IsStopped() {
955   bool aret = false ;
956 //  cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
957   SUPERV::AutomatonState aState = State() ;
958   if ( aState == SUPERV::StoppedReadyState ||
959        aState == SUPERV::StoppedExecutingState ||
960        aState == SUPERV::StoppedSuccessedState ||
961        aState == SUPERV::StoppedErroredState ||
962        aState == SUPERV::StoppedState )
963     aret = true ;
964 //  cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
965   return aret ;
966 }
967
968 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
969   bool RetVal = false ;
970   if ( pthread_mutex_lock( &_MutexWait ) ) {
971     perror("pthread_mutex_lock _Wait") ;
972     exit( 0 ) ;
973   }
974   switch ( aState ) {
975   case SUPERV::ReadyState : {
976     RetVal = IsReady() ;
977     cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
978               << " " << Automaton()->StateName( _currentState )
979               << " pthread_cond_wait _ReadyWait " << Name() << endl ;
980     while ( !RetVal && !IsDone() ) {
981       cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
982       pthread_cond_wait( &_ReadyWait , &_MutexWait );
983       RetVal = IsReady() ;
984       cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
985              << Automaton()->StateName( _currentState ) << " " << RetVal
986              << endl ;
987     }
988     cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
989                << " " << Automaton()->StateName( _currentState )
990                << " pthread_cond_wait _ReadyWait " << Name() << endl ;
991     break ;
992   }
993   case SUPERV::RunningState : {
994     RetVal = IsRunning() ;
995     cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
996               << " " << Automaton()->StateName( _currentState )
997               << " pthread_cond_wait _RunningWait " << Name() << endl ;
998     while ( !RetVal && !IsDone() ) {
999       cdebug << pthread_self() << " pthread_cond_wait RunningWait" << endl ;
1000       pthread_cond_wait( &_RunningWait , &_MutexWait );
1001       RetVal = IsRunning() ;
1002       cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1003              << Automaton()->StateName( _currentState ) << " " << RetVal
1004              << endl ;
1005     }
1006     cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1007                << " " << Automaton()->StateName( _currentState )
1008                << " pthread_cond_wait _RunningWait " << Name() << endl ;
1009     break ;
1010   }
1011   case SUPERV::DoneState : {
1012     RetVal = IsDone() ;
1013     cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1014               << " " << Automaton()->StateName( _currentState )
1015               << " pthread_cond_wait _DoneWait " << Name() << endl ;
1016     while ( !RetVal ) {
1017       cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1018       pthread_cond_wait( &_DoneWait , &_MutexWait );
1019       RetVal = IsDone() ;
1020       cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1021              << Automaton()->StateName( _currentState ) << " " << RetVal
1022              << endl ;
1023     }
1024     cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1025                << " " << Automaton()->StateName( _currentState )
1026                << " pthread_cond_wait _DoneWait " << Name() << endl ;
1027     break ;
1028   }
1029   case SUPERV::SuspendState : {
1030     RetVal = IsSuspended() ;
1031     cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1032               << " " << Automaton()->StateName( _currentState )
1033               << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1034     while ( !RetVal && !IsDone() ) {
1035       cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1036       pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1037       RetVal = IsSuspended() ;
1038       cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1039              << Automaton()->StateName( _currentState ) << " " << RetVal
1040              << endl ;
1041     }
1042     cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1043                << " " << Automaton()->StateName( _currentState )
1044                << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1045     break ;
1046   }
1047   default : {
1048     cdebug << " GraphExecutor::OutNode::StateWait Error Undefined State : "
1049            << aState << endl ;
1050   }
1051   }
1052   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1053     perror("pthread_mutex_lock _Wait") ;
1054     exit( 0 ) ;
1055   }
1056   return RetVal ;
1057 }
1058
1059 bool GraphExecutor::InNode::ReadyWait() {
1060 //  cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1061   bool aret ;
1062   aret = StateWait( SUPERV::ReadyState ) ;
1063 //  cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1064   return aret ;
1065 }
1066
1067 bool GraphExecutor::InNode::RunningWait() {
1068 //  cdebug_in << "GraphExecutor::InNode::RunningWait " << Name() << endl;
1069   bool aret ;
1070   aret = StateWait( SUPERV::RunningState ) ;
1071   return aret ;
1072 }
1073
1074 bool GraphExecutor::InNode::DoneWait() {
1075 //  cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1076   bool aret ;
1077   aret = StateWait( SUPERV::DoneState ) ;
1078   return aret ;
1079 }
1080
1081 bool GraphExecutor::InNode::SuspendedWait() {
1082 //  cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1083   bool aret ;
1084   aret = StateWait( SUPERV::SuspendState ) ;
1085   return aret ;
1086 }
1087
1088 void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
1089 {
1090   cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1091
1092   _OutNode = theOutNode ;
1093
1094   int i;
1095   _ControlState = SUPERV::VoidState ;
1096   CreateNewThread( false ) ;
1097   CreateNewThreadIf( false ) ;
1098   _SuspendSync = false ;
1099   _ResumeSync = false ;
1100 //  ThreadNo( pthread_self() ) ;
1101   ThreadNo( 0 ) ;
1102
1103   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1104     if ( GetNodeOutPort(i)->IsDataStream() ) {
1105       GetChangeNodeOutPort(i)->State(  SUPERV::ReadyState ) ;
1106       GetChangeNodeOutPort(i)->Done( true ) ;
1107     }
1108     else if ( i != 0 || !IsGOTONode() ) {
1109       GetChangeNodeOutPort(i)->State(  SUPERV::WaitingState ) ;
1110       GetChangeNodeOutPort(i)->Done( false ) ;
1111     }
1112   }
1113
1114   int Pc = GetNodeInPortsSize() ;
1115   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1116     const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1117     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1118     if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1119       anOutPort->PortStatus( DataConnected );
1120       anOutPort->State( SUPERV::ReadyState ) ;
1121       anOutPort->Done( true ) ;
1122       CORBA::Any * anAny = new CORBA::Any() ;
1123       *anAny <<= (long ) 1 ;
1124       anOutPort->Value( anAny ) ;
1125     }
1126     else if ( anInPort->IsGate() && anOutPort ) {
1127       if ( IsComputingNode() || IsFactoryNode() ) {
1128         anOutPort->State( SUPERV::WaitingState ) ;
1129         anOutPort->Done( false ) ;
1130       }
1131       else if ( IsOneOfInLineNodes() ) {
1132         anOutPort->PortStatus( DataConnected );
1133         anOutPort->State( SUPERV::ReadyState ) ;
1134         anOutPort->Done( true ) ;
1135       }
1136     }
1137 //    if ( ( anInPort->IsGate() || anInPort->IsBus() ) && anOutPort == NULL ) {
1138     if ( anInPort->IsGate() && anOutPort == NULL ) {
1139       Pc-- ;
1140     }
1141     else if ( anOutPort ) {
1142       if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1143         Pc-- ;
1144       }
1145       if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1146         anOutPort->State( SUPERV::ReadyState ) ;
1147         anOutPort->Done( true ) ;
1148       }
1149       else if ( anOutPort->IsPortConnected() ) {
1150         anOutPort->State( SUPERV::WaitingState ) ;
1151         anOutPort->Done( false ) ;
1152       }
1153     }
1154     if ( anOutPort ) {
1155       if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1156         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1157                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1158                << " with state " << theAutomaton->StateName( anOutPort->State() ) << endl ;
1159         GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1160       }
1161       else {
1162         cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1163                << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1164                << " with state ReadyState" << endl ;
1165         GetChangeNodeInPort(i)->State( SUPERV::ReadyState ) ;
1166       }
1167     }
1168     if ( anOutPort ) {
1169       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1170              << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1171              << " with state " ;
1172       if ( anOutPort->State() == SUPERV::WaitingState ) {
1173         cdebug << "WaitingState" ;
1174       }
1175       else if ( anOutPort->State() == SUPERV::ReadyState ) {
1176         cdebug << "ReadyState" ;
1177       }
1178       else {
1179         cdebug << "???" ;
1180       }
1181       cdebug << " PortConnected("
1182              << anOutPort->IsPortConnected() << ") DataConnected("
1183              << anOutPort->IsDataConnected() << ")" << endl ;
1184     }
1185   }
1186
1187   _currentState = Pc > 0 ? SUPERV::DataWaitingState 
1188                          : SUPERV::DataReadyState ;
1189   if ( Pc == GetNodeInPortsSize() ) {
1190     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1191                          _currentState ) ; 
1192   }
1193   else if ( Pc != 0 ) {
1194     _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1195                          _currentState ) ; 
1196   }
1197   else {
1198     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1199                          _currentState ) ; 
1200   }
1201
1202   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1203     cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1204            << theAutomaton->StateName( GetChangeNodeOutPort(i)->State() )
1205            << " " << GetNodeOutPort(i)->Kind() << endl ;
1206   }
1207
1208   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1209          << endl;
1210
1211   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1212 }
1213
1214 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1215   cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
1216   bool Err = false ;
1217   if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1218     if ( IsLoopNode() ) {
1219       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1220       PyObject * PyMoreMethod = NULL ;
1221       PyObject * PyNextMethod = NULL ;
1222       if ( PyRunMethod ) {
1223       }
1224       else {
1225         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1226                                        InLineNode()->PythonFunction() ,
1227                                        Err ) ;
1228         InLineNode()->PyRunMethod( PyRunMethod ) ;
1229       }
1230       if ( !Err ) {
1231         PyMoreMethod = LoopNode()->PyMoreMethod() ;
1232         if ( PyMoreMethod ) {
1233         }
1234         else {
1235           PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1236                                           LoopNode()->MorePythonFunction() ,
1237                                           Err ) ;
1238           LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1239         }
1240       }
1241       if ( !Err ) {
1242         PyNextMethod = LoopNode()->PyNextMethod() ;
1243         if ( PyNextMethod ) {
1244         }
1245         else {
1246           PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1247                                           LoopNode()->NextPythonFunction() ,
1248                                           Err ) ;
1249           LoopNode()->PyNextMethod( PyNextMethod ) ;
1250         }
1251       }
1252       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1253              << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1254     }
1255     else if ( IsInLineNode() || IsSwitchNode() ) {
1256       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1257       if ( PyRunMethod ) {
1258       }
1259       else {
1260         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1261                                        InLineNode()->PythonFunction() ,
1262                                        Err ) ;
1263         InLineNode()->PyRunMethod( PyRunMethod ) ;
1264       }
1265       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1266     }
1267     else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1268               (*InLineNode()->PythonFunction()).length() ) {
1269       PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1270       if ( PyRunMethod ) {
1271       }
1272       else {
1273         PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1274                                        InLineNode()->PythonFunction() ,
1275                                        Err ) ;
1276         InLineNode()->PyRunMethod( PyRunMethod ) ;
1277       }
1278       cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1279     }
1280   }
1281   Err = WithErr && Err ;
1282   cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1283   if ( Err ) {
1284     cdebug << " Error " << Err ;
1285   }
1286   cdebug << endl;
1287   return !Err ;
1288 }
1289
1290 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1291   CORBA::Long cpu = 0 ;
1292 //  cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1293   if ( IsOneOfInLineNodes() ) {
1294 //    cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1295 //    cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1296     cpu = PyCpuUsed( tot ) ;
1297   }
1298   else {
1299     if ( !CORBA::is_nil( Component() ) ) {
1300 //      cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1301 //      cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1302       try {
1303         cpu = Component()->CpuUsed_impl() ;
1304       }
1305       catch ( ... ) {
1306         cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1307         State( SUPERV::ErroredState ) ;
1308         _OutNode->State( SUPERV::ErroredState ) ;
1309         cpu = 0 ;
1310       }
1311     }
1312   }
1313 //  cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1314 //  cout << "CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1315   return cpu ;
1316 }
1317
1318 #include <sys/time.h>
1319 #include <sys/resource.h>
1320 #include <unistd.h>
1321
1322 long GraphExecutor::InNode::PyCpu() {
1323   struct rusage usage ;
1324   long cpu ;
1325   if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1326     perror("GraphExecutor::InNode::PyCpu") ;
1327     return 0 ;
1328   }
1329 //  return usage.ru_utime.__time_t tv_sec ;
1330 //  cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1331 //         << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1332 //         << endl ;
1333   cpu = usage.ru_utime.tv_sec ;
1334   return cpu ;
1335 }
1336
1337 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1338   long cpu ;
1339   if ( _PyTotCpuUsed == -1 ) {
1340     if ( _Pythread == pthread_self() ) {
1341 //      cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1342 //             << " _PyTotCpuUsed " <<  _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1343 //             << _PyCpuUsed << endl ;
1344       cpu = PyCpu() - _PyCpuUsed ;
1345       if ( tot ) {
1346         _PyTotCpuUsed = cpu ;
1347       }
1348     }
1349     else {
1350       cpu = 0 ;
1351     }
1352   }
1353   else {
1354     cpu = _PyTotCpuUsed ;
1355   }
1356 //  cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1357 //         <<  _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1358   return cpu ;
1359 }
1360
1361 void GraphExecutor::InNode::SetPyCpuUsed() {
1362   _PyTotCpuUsed = -1 ;
1363   _PyCpuUsed = 0 ;
1364   _Pythread = pthread_self() ;
1365   _PyCpuUsed = PyCpu() ;
1366 //  cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1367 //         << _PyCpuUsed << endl ;
1368 }
1369