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