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