Salome HOME
*** empty log message ***
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_OutNode.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   : DataFlowBase_OutNode.cxx
25 //  Author : Jean Rahuel, CEA
26 //  Module : SUPERV
27 //  $Header:
28
29 using namespace std;
30
31 #include "DataFlowExecutor_OutNode.hxx"
32
33 // Implementation de la classe GraphEditor::GraphControl
34
35 extern GraphExecutor::FiniteStateMachine * theAutomaton ;
36
37 // static const char *ComponentName = "SalomeSuperVisionComponent" ;
38
39 extern int _ArgC ;
40 extern char ** _ArgV ;
41
42 GraphExecutor::OutNode::OutNode() :
43                Graph() {
44   _Valid = false ;
45   _Executable = false ;
46   _Done = false ;
47   _Threads = 0 ;
48   _ControlState = SUPERV::VoidState ;
49   _State = SUPERV::UnKnownState ;
50   _PyInitialized = false ;
51   pthread_mutex_init( &_MutexWait , NULL ) ;
52   pthread_mutex_init( &_PyMutexWait , NULL ) ;
53   if ( pthread_cond_init( &_EventWait , NULL ) ) {
54     perror("pthread_cond_init( &_EventWait , NULL )") ;
55     exit( 0 ) ;
56   }
57   if ( pthread_cond_init( &_JoinWait , NULL ) ) {
58     perror("pthread_cond_init( &_JoinWait , NULL )") ;
59     exit( 0 ) ;
60   }
61 }
62
63 GraphExecutor::OutNode::OutNode( CORBA::ORB_ptr ORB, 
64                                  SALOME_NamingService* ptrNamingService ,
65                                  const char *DataFlowName ,
66                                  const char * DebugFileName ) :
67                Graph( ORB , ptrNamingService , DataFlowName , DebugFileName ) {
68   cdebug_in << "GraphEditor::OutNode::OutNode(" << DataFlowName << ")" << endl;
69   _Valid = false ;
70   _Executable = false ;
71   _Done = false ;
72   _Threads = 0 ;
73   _ControlState = SUPERV::VoidState ;
74   _State = SUPERV::UnKnownState ;
75   _PyInitialized = false ;
76   _Orb = CORBA::ORB::_duplicate( ORB ) ;
77   pthread_mutex_init( &_MutexWait , NULL ) ;
78   pthread_mutex_init( &_PyMutexWait , NULL ) ;
79   if ( pthread_cond_init( &_EventWait , NULL ) ) {
80     perror("pthread_cond_init( &_EventWait , NULL )") ;
81     exit( 0 ) ;
82   }
83   if ( pthread_cond_init( &_JoinWait , NULL ) ) {
84     perror("pthread_cond_init( &_JoinWait , NULL )") ;
85     exit( 0 ) ;
86   }
87   cdebug_out << "GraphEditor::OutNode::OutNode" << endl;
88 }
89
90 GraphExecutor::OutNode::OutNode(
91                CORBA::ORB_ptr ORB, 
92                SALOME_NamingService* ptrNamingService ,
93                const SALOME_ModuleCatalog::Service& DataFlowService ,
94                const char *DataFlowComponentName ,
95                const char *DataFlowInterfaceName ,
96                const char *DataFlowName ,
97                const SUPERV::KindOfNode DataFlowkind ,
98                const SUPERV::SDate DataFlowFirstCreation ,
99                const SUPERV::SDate DataFlowLastModification ,
100                const char * DataFlowEditorRelease ,
101                const char * DataFlowAuthor ,
102                const char * DataFlowComputer ,
103                const char * DataFlowComment ,
104                const char * DebugFileName ) :
105                Graph( ORB , ptrNamingService , DataFlowService , DataFlowComponentName ,
106                       DataFlowInterfaceName , DataFlowName , DataFlowkind ,
107                       DataFlowFirstCreation , DataFlowLastModification  ,
108                       DataFlowEditorRelease , DataFlowAuthor ,
109                       DataFlowComputer , DataFlowComment , DebugFileName ) {
110   _Valid = false ;
111   _Executable = false ;
112   _Done = false ;
113   _Threads = 0 ;
114   _ControlState = SUPERV::VoidState ;
115   _State = SUPERV::UnKnownState ;
116   _PyInitialized = false ;
117   _Orb = CORBA::ORB::_duplicate( ORB ) ;
118   pthread_mutex_init( &_MutexWait , NULL ) ;
119   pthread_mutex_init( &_PyMutexWait , NULL ) ;
120   if ( pthread_cond_init( &_EventWait , NULL ) ) {
121     perror("pthread_cond_init( &_EventWait , NULL )") ;
122     exit( 0 ) ;
123   }
124   if ( pthread_cond_init( &_JoinWait , NULL ) ) {
125     perror("pthread_cond_init( &_JoinWait , NULL )") ;
126     exit( 0 ) ;
127   }
128 }
129
130 GraphExecutor::OutNode::~OutNode() {
131 }
132
133 bool GraphExecutor::OutNode::LoadDataFlow(const GraphBase::SGraph &aDataFlow ) {
134   bool RetVal = false ;
135   RetVal = LoadInfo( aDataFlow.Info ) ;
136   if ( GraphBase::Service::ServiceName() != NULL ) {
137 //    MESSAGE( "GraphExecutor::OutNode::LoadDataFlow" );
138     if ( RetVal ) {
139       RetVal = LoadNodes( aDataFlow.Nodes ) ;
140       if ( RetVal ) {
141         RetVal = LoadLinks( aDataFlow.Links ) ;
142         if ( RetVal ) {
143           IsValid() ;
144           RetVal = LoadDatas( aDataFlow.Datas ) ;
145           IsExecutable() ;
146           if ( !RetVal) {
147             cdebug << "GraphExecutor::OutNode::LoadDataFlow LoadDatas Error."
148                    << endl ;
149           }
150         }
151         else {
152           cdebug << "GraphExecutor::OutNode::LoadDataFlow LoadLinks Error."
153                << endl ;
154         }
155       }
156       else {
157         cdebug << "GraphExecutor::OutNode::LoadDataFlow LoadNodes Error."
158              << endl ;
159       }
160     }
161     else {
162       cdebug << "GraphExecutor::OutNode::LoadDataFlow LoadInfo Error."
163            << endl ;
164     }
165   }
166   else {
167     cdebug << "GraphExecutor::OutNode::LoadDataFlow ServiceName Error." << endl ;
168   }
169   return RetVal ;
170 }
171
172 bool GraphExecutor::OutNode::LoadXml( const char* myFileName ) {
173   bool RetVal = false ;
174   GraphBase::SGraph aDataFlow ;
175   if ( GraphBase::Graph::LoadXml( _Orb , myFileName , aDataFlow ) ) {
176     RetVal = LoadDataFlow( aDataFlow ) ;
177 //    if ( aConstructor && RetVal )
178 //      RetVal = Name( aDataFlow.Info.theName.c_str() ) ;
179   }
180   return RetVal ;
181
182
183 bool GraphExecutor::OutNode::LoadInfo(const GraphBase::SNode &aDataFlowInfo ) {
184   cdebug << "GraphExecutor::OutNode::LoadInfo" << endl ;
185 //  ComponentName( aDataFlowInfo.theComponentName.c_str()  ) ;
186   Name( aDataFlowInfo.theName.c_str()  ) ;
187   Kind( aDataFlowInfo.theKind ) ;
188   DataService( _Orb , aDataFlowInfo.theService , Graph_prof_debug() , Graph_fdebug() ) ;
189   FirstCreation( aDataFlowInfo.theFirstCreation ) ;
190   LastModification( aDataFlowInfo.theLastModification ) ;
191   EditorRelease( aDataFlowInfo.theEditorRelease.c_str()  ) ;
192   Author( aDataFlowInfo.theAuthor.c_str()   ) ;
193 //  Computer( aDataFlowInfo.theContainer.c_str()  ) ;
194   Comment( aDataFlowInfo.theComment.c_str()  ) ;
195 // Not in OutNode/DataFlow but in InNode/DataFlow_in_an_other_DataFlow
196 //  Coordinates( aDataFlowInfo.theX , aDataFlowInfo.theY ) ;
197   return true ;
198 }
199
200 bool GraphExecutor::OutNode::LoadNodes(const GraphBase::ListOfNodes &aListOfNodes ) {
201   bool RetVal = true ;
202   GraphExecutor::InNode * anInNode ;
203   cdebug << "GraphExecutor::OutNode::LoadNodes" << endl ;
204   int i ;
205   for ( i = 0 ; i < (int ) aListOfNodes.size() ; i++ ) {
206     GraphBase::SNode aNode = aListOfNodes[ i ] ;
207     anInNode = AddNode( aNode.theService ,
208                         aNode.theListOfFuncName ,
209                         aNode.theListOfPythonFunctions ,
210                         aNode.theComponentName.c_str() ,
211                         aNode.theInterfaceName.c_str()  , aNode.theName.c_str() ,
212                         aNode.theKind ,
213                         aNode.theFirstCreation , aNode.theLastModification ,
214                         aNode.theEditorRelease.c_str() ,
215                         aNode.theAuthor.c_str()  , aNode.theContainer.c_str() ,
216                         aNode.theComment.c_str() ,
217                         aNode.theCoords.theX , aNode.theCoords.theY ) ;
218     if ( !anInNode ) {
219       RetVal = false ;
220       break ;
221     }
222     if ( anInNode->IsOneOfInLineNodes() ) {
223       anInNode->GraphExecutor::InNode::InLineNode()->DefPortsOfNode(
224                                 _Orb , aNode.theService , anInNode->NamePtr() ,
225                                 anInNode->Kind() ,
226                                 Graph_prof_debug() , Graph_fdebug() ) ;
227 #if 0
228       GraphBase::InLineNode * aINode = anInNode->InLineNode() ;
229       GraphBase::LoopNode * aLNode = NULL ;
230       if ( aINode->IsLoopNode() ) {
231         aLNode = anInNode->LoopNode() ;
232         aLNode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
233                                    *aNode.theListOfPythonFunctions[ 0 ] ) ;
234         aLNode->SetMorePythonFunction( aNode.theListOfFuncName[ 1 ].c_str() ,
235                                        *aNode.theListOfPythonFunctions[ 1 ] ) ;
236         aLNode->SetNextPythonFunction( aNode.theListOfFuncName[ 2 ].c_str() ,
237                                        *aNode.theListOfPythonFunctions[ 2 ] ) ;
238       }
239       else if ( aINode->IsInLineNode() || aINode->IsGOTONode() ||
240                 aINode->IsSwitchNode() || aINode->IsEndSwitchNode() ) {
241         aINode->SetPythonFunction( aNode.theListOfFuncName[ 0 ].c_str() ,
242                                    *aNode.theListOfPythonFunctions[ 0 ] ) ;
243       }
244 #endif
245     }
246 #if 0
247     if ( aNode.theListOfParameters.size() ) { // BusPorts ...
248       int j ;
249       for ( j = 0 ; j < aNode.theListOfParameters.size() ; j++ ) {
250         GraphBase::InPort * InputPort = anInNode->AddInPort(
251                aNode.theListOfParameters[ j ].theInParameter.Parametername ,
252                aNode.theListOfParameters[ j ].theInParameter.Parametertype ) ;
253         GraphBase::OutPort * OutputPort = anInNode->AddOutPort(
254                aNode.theListOfParameters[ j ].theOutParameter.Parametername ,
255                aNode.theListOfParameters[ j ].theOutParameter.Parametertype ) ;
256         anInNode->InOutPort( InputPort , OutputPort ) ;
257       }
258     }
259 #endif
260   }
261   for ( i = 0 ; i < (int ) aListOfNodes.size() ; i++ ) {
262     GraphBase::SNode aNode = aListOfNodes[ i ] ;
263     anInNode = (GraphExecutor::InNode * ) GetChangeGraphNode( aNode.theName.c_str() )->GetInNode() ;
264     cdebug << "GraphExecutor::OutNode::LoadNodes " << anInNode->Name() << "IsOneOfGOTONodes "
265            << anInNode->IsOneOfGOTONodes() << " " << aNode.theCoupledNode.c_str() << endl ;
266     if ( anInNode->IsOneOfGOTONodes() && strlen( aNode.theCoupledNode.c_str() ) ) {
267       GraphBase::GOTONode * aCoupledNode ;
268       aCoupledNode = (GraphBase::GOTONode * ) GetGraphNode( aNode.theName.c_str() ) ;
269       aCoupledNode->CoupledNode( (GraphBase::GOTONode * ) GetChangeGraphNode( aNode.theCoupledNode.c_str() ) ) ; 
270     }
271   }
272   return RetVal ;
273 }
274
275 bool GraphExecutor::OutNode::LoadLinks(const GraphBase::ListOfLinks &aListOfLinks ) {
276   bool RetVal = true ;
277   cdebug << "GraphExecutor::OutNode::LoadLinks " << aListOfLinks.size()
278          << endl ;
279   int i ;
280   for ( i = 0 ; i < (int ) aListOfLinks.size() ; i++ ) {
281     GraphBase::SLink aLink = aListOfLinks[ i ] ;
282     RetVal = AddLink( aLink.FromNodeName.c_str() ,
283                       aLink.FromServiceParameterName.c_str() ,
284                       aLink.ToNodeName.c_str() ,
285                       aLink.ToServiceParameterName.c_str() ,
286                       aLink.aLinkValue ) ;
287 //                      aLink.aLinkValue.Value , aLink.aLinkValue.Kind ) ;
288     if ( !RetVal )
289       break ;
290   }
291   return RetVal ;
292 }
293
294 bool GraphExecutor::OutNode::LoadDatas(const GraphBase::ListOfLinks &aListOfDatas ) {
295   bool RetVal = true ;
296   cdebug << "GraphExecutor::OutNode::LoadDatas " << aListOfDatas.size()
297          << endl ;
298   int i ;
299   for ( i = 0 ; i < (int ) aListOfDatas.size() ; i++ ) {
300     GraphBase::SLink aLink = aListOfDatas[ i ] ;
301     if ( !strcmp( aLink.FromNodeName.c_str() , Name() ) )
302       RetVal = GraphBase::Graph::AddInputData( aLink.ToNodeName.c_str() ,
303                                                aLink.ToServiceParameterName.c_str() ,
304                                                aLink.aLinkValue ) ;
305 //                        aLink.aLinkValue.Value , aLink.aLinkValue.Kind ) ;
306     else if ( !strcmp( aLink.ToNodeName.c_str() , Name() ) ) {
307       RetVal = AddOutputData( aLink.FromNodeName.c_str() ,
308                               aLink.FromServiceParameterName.c_str() ,
309                               aLink.aLinkValue ) ;
310 //                              aLink.aLinkValue.Value ,
311 //                              aLink.aLinkValue.Kind ) ;
312       AddLink( aLink.FromNodeName.c_str() , (GraphBase::ComputingNode *) this ) ;
313     }
314     else {
315       cdebug << "GraphExecutor::OutNode::LoadDatas Error " << aLink.FromNodeName
316            << " and " << aLink.ToNodeName << " differents from " << Name()
317            << endl ;
318       RetVal = false ;
319     }
320     if ( !RetVal )
321       break ;
322   }
323   return RetVal ;
324 }
325
326 GraphExecutor::InNode *GraphExecutor::OutNode::AddNode(
327                       const SALOME_ModuleCatalog::Service& NodeService ,
328                       GraphBase::ListOfFuncName aFuncName ,
329                       GraphBase::ListOfPythonFunctions aPythonFunction ,
330                       const char * NodeComponentName ,
331                       const char * NodeInterfaceName ,
332                       const char * NodeName ,
333                       const SUPERV::KindOfNode NodeKindOfNode ,
334                       const SUPERV::SDate NodeFirstCreation ,
335                       const SUPERV::SDate NodeLastModification  ,
336                       const char * NodeEditorRelease ,
337                       const char * NodeAuthor ,
338                       const char * NodeComputer ,
339                       const char * NodeComment ,
340                       const int NodeX ,
341                       const int NodeY ) {
342   cdebug_in << "GraphExecutor::OutNode::AddNode(" << NodeComponentName << " , "
343             << NodeName << ")" << endl;
344   GraphExecutor::InNode *Nd = NULL ;
345   Nd = new GraphExecutor::InNode( _Orb, NamingService() , NodeService ,
346                                   NodeComponentName , NodeInterfaceName ,
347                                   NodeName , NodeKindOfNode ,
348                                   aFuncName , aPythonFunction ,
349                                   NodeFirstCreation , NodeLastModification ,
350                                   NodeEditorRelease , NodeAuthor ,
351                                   NodeComputer , NodeComment , false , NodeX , NodeY ,
352                                   Graph_prof_debug() , Graph_fdebug() ) ;
353   GraphBase::Graph::AddNode( Nd->ComputingNode() ) ;
354   cdebug_out << "GraphExecutor::OutNode::AddNode" << endl;
355   return Nd ;
356 }
357
358
359 bool GraphExecutor::OutNode::AddInputData( const char* ToNodeName1 ,
360                                            const char* ToParameterName1 ,
361                                            const char* ToNodeName2 ,
362                                            const char* ToParameterName2 ) {
363   cdebug_in << "GraphExecutor::OutNode::AddInputData" << endl;
364   bool RetVal = GraphBase::Graph::AddInputData( ToNodeName1 ,
365                                                 ToParameterName1 ,
366                                                 ToNodeName2 ,
367                                                 ToParameterName2 ) ;
368   cdebug_out << "GraphExecutor::OutNode::AddInputData" << endl;
369   _Valid = false ;
370   return RetVal ;
371 }
372
373 bool GraphExecutor::OutNode::Valid() {
374   cdebug_in << "GraphExecutor::OutNode::Valid" << endl;
375
376   if ( _Valid )
377     return true ;
378
379   _Executable = false ;
380
381   if ( !CreateService() ) {
382     cdebug << "This DataFlow has invalid type(s)." << endl ;
383     return false ;
384   }
385
386   if ( !Sort() ) {
387     cdebug << "This DataFlow is not valid." << endl ;
388     return false ;
389   }
390
391 //  CreateService() ;
392
393   InLineServices() ;
394
395   ComputingNodes() ;
396   
397   _Valid = true ;
398
399   cdebug_out << "GraphExecutor::OutNode::Valid" << endl;
400   return _Valid ;
401 }
402
403
404 bool GraphExecutor::OutNode::Executable() {
405
406   cdebug_in << "GraphExecutor::OutNode::Executable" << endl;
407   if ( !IsValid() )
408     return false ;
409
410   if ( DataServerNodes() )
411     _Executable = true ;
412   else {
413     cdebug << "This DataFlow is not executable." << endl ;
414     _Executable = false ;
415   }
416
417   cdebug_out << "GraphExecutor::OutNode::Executable" << endl;
418   return _Executable ;
419 }
420
421 bool GraphExecutor::OutNode::Run( const bool AndSuspend ) {
422   bool RetVal = false ;
423   cdebug_in << "GraphExecutor::OutNode::Run" << endl;
424
425   if ( Executable() ) {
426     _ControlState = SUPERV::VoidState ;
427     _SuspendedThreads = 0 ;
428     ThreadNo( pthread_self() ) ;
429     Done( false ) ;
430     _JustStarted = true ;
431     int i ;
432     for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
433       GraphExecutor::InNode * anInNode = (GraphExecutor::InNode *) GraphNodes( i )->GetInNode() ;
434       if ( !PyInitialized() && anInNode->IsOneOfInLineNodes() ) {
435         if ( !Py_IsInitialized() ) {
436 //          Py_Initialize() ;
437           PySys_SetArgv( _ArgC , _ArgV ) ;
438         }
439         anInNode->InitPython() ;
440         PyInitialized( true ) ;
441       }
442       anInNode->InitialState( this ) ;
443       if ( anInNode->IsOneOfInLineNodes() ) {
444         anInNode->InitPythonFunctions( false ) ;
445       }
446     }
447 // One more time because inline nodes may share one definition of the same function
448     for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
449       GraphExecutor::InNode * anInNode = (GraphExecutor::InNode *) GraphNodes( i )->GetInNode() ;
450       if ( anInNode->IsOneOfInLineNodes() ) {
451         if ( anInNode->InitPythonFunctions( true ) ) {
452         }
453       }
454     }
455
456     cdebug << "Execution starting GraphExecutor::Action_DataOk_RunService Node "
457            << Name() << endl ;
458
459     PushEvent( NULL , GraphExecutor::ReadyEvent ,
460                SUPERV::DataReadyState ) ; 
461     State( SUPERV::DataReadyState ) ;
462
463     for ( i = 0 ; i < HeadNodesSize() ; i++ ) {
464       GraphExecutor::InNode * anInNode = (GraphExecutor::InNode *) HeadNodes( i )->GetInNode() ;
465       if ( anInNode->State() != SUPERV::DataReadyState ) {
466         cdebug << "GraphExecutor::OutNode::Run inconsistency State of Node "
467              << anInNode->Name() << " : " << anInNode->State() << endl ;
468         cdebug_out << "GraphExecutor::OutNode::Run State ERROR" << endl ;
469         return false ;
470       }
471 //      PushEvent( anInNode , GraphExecutor::ReadyEvent ,
472 //                 SUPERV::DataReadyState ) ; 
473       anInNode->CreateNewThread( true ) ;
474       anInNode->DataFromNode( Name() ) ;
475       if ( AndSuspend ) {
476         anInNode->State( SUPERV::DataWaitingState ) ;
477         anInNode->ControlState( SUPERV::ToSuspendStartState ) ;
478         if ( !anInNode->SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
479           cdebug << "InNode::SendEvent( SomeDataReadyEvent ) ERROR Node "
480                  << anInNode->Name() << endl ;
481           cdebug_out << "GraphExecutor::OutNode::Run SendEvent ERROR" << endl ;
482           return false ;
483         }
484         anInNode->SuspendedWait() ;
485       }
486       else if ( !anInNode->SendEvent( GraphExecutor::ExecuteEvent ) ) {
487         cdebug << "InNode::SendEvent( ExecuteEvent ) ERROR Node "
488                << anInNode->Name() << endl ;
489         cdebug_out << "GraphExecutor::OutNode::Run SendEvent ERROR" << endl ;
490         return false ;
491       }
492       else {
493         anInNode->RunningWait() ;
494       }
495     }
496
497     if ( AndSuspend ) {
498       PushEvent( NULL , GraphExecutor::SuspendedReadyEvent ,
499                  SUPERV::SuspendedReadyState ) ; 
500     }
501     else {
502       PushEvent( NULL , GraphExecutor::ExecutingEvent ,
503                  SUPERV::ExecutingState ) ; 
504       if (AutomatonState() == SUPERV::DataReadyState) {
505           State( SUPERV::ExecutingState ) ;
506       };
507     }
508
509     RetVal = true ;
510   }
511   else {
512     PushEvent( NULL , GraphExecutor::NoDataReadyEvent ,
513                SUPERV::DataUndefState ) ; 
514   }
515
516   cdebug_out << "GraphExecutor::OutNode::Run" << endl ;
517   return RetVal ;
518 }
519
520 bool GraphExecutor::OutNode::Run( const char * aNodeName ,
521                                   const char * AtNodeName ,
522                                   const bool AndSuspend ) {
523   bool RetVal = false ;
524   cdebug_in << "GraphExecutor::OutNode::Run( " << aNodeName << " , "
525             << AtNodeName << " , " << AndSuspend << ")" << endl;
526   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( aNodeName )->GetInNode() ;
527   if ( anInNode ) {
528     RetVal = anInNode->ReStart( AtNodeName , AndSuspend ) ;
529   }
530   cdebug_out << "GraphExecutor::OutNode::Run" << endl ;
531   return RetVal ;
532 }
533
534 void GraphExecutor::OutNode::CheckAllDone() {
535   int j ;
536   cdebug_in << "GraphExecutor::OutNode::CheckAllDone " << endl;
537   SUPERV::AutomatonState OutNodeState = SUPERV::SuccessedState ;
538   SUPERV::AutomatonState InNodeState ;
539   bool AllDone = true ;
540   if ( !Done() ) {
541     for ( j = 0 ; j < QueueNodesSize() ; j++ ) {
542       InNodeState = ( (GraphExecutor::InNode * ) QueueNodes( j )->GetInNode() )->State() ;
543       cdebug << j << ". "
544              << ( (GraphExecutor::InNode * ) QueueNodes( j )->GetInNode() )->Name()
545              << " " << theAutomaton->StateName( InNodeState ) << endl ;
546       if ( InNodeState != SUPERV::SuccessedState &&
547            InNodeState != SUPERV::ErroredState &&
548            InNodeState != SUPERV::DataWaitingState ) {
549         AllDone = false ;
550       }
551       if ( InNodeState != SUPERV::SuccessedState &&
552            InNodeState != SUPERV::DataWaitingState &&
553            InNodeState != SUPERV::DataReadyState ) {
554         OutNodeState = InNodeState ;
555       }
556     }
557     if ( AllDone ) {
558       if( _Threads == 0 && _SuspendedThreads == 0 ) {
559         if ( OutNodeState != SUPERV::ErroredState ) {
560           OutNodeState = SUPERV::SuccessedState ;
561         }
562       }
563       else {
564         AllDone = false ;
565       }
566     }
567     if ( AllDone ) {
568       int alivenodes = 0 ;
569       for ( j = 0 ; j < GraphNodesSize()  ; j++ ) {
570         GraphExecutor::InNode * aNode ;
571         aNode = (GraphExecutor::InNode * ) GraphNodes( j )->GetInNode() ;
572         SUPERV::GraphState aState = AutomatonGraphState( aNode->State() ) ;
573         cdebug << "GraphExecutor::OutNode::CheckAllDone " << aNode->Name() << " "
574                << theAutomaton->StateName( aNode->State() ) << " CreateNewThread " << aNode->CreateNewThread()
575                << endl ;
576         if ( aState == SUPERV::ErrorState ||
577              aState == SUPERV::SuspendErroredState ||
578              aState == SUPERV::KillState ||
579              aState == SUPERV::StopState ) {
580           OutNodeState = aNode->State() ;
581           State( OutNodeState ) ;
582         }
583         else if ( aState == SUPERV::ReadyState ||
584                   aState == SUPERV::SuspendReadyState ||
585                   aState == SUPERV::RunningState ||
586                   aState == SUPERV::SuspendDoneState ||
587                   aState == SUPERV::SuspendErroredState ||
588                   aState == SUPERV::ReRunState ||
589                   aState == SUPERV::ReStartState ||
590                   aState == SUPERV::SuspendState ) {
591           alivenodes += 1 ;
592         }
593         aNode->SuspendedAction() ;
594         aNode->DoneAction() ;
595       }
596 // PushEvent AFTER State and _Done ! ...
597       if ( alivenodes == 0 ) {
598         State( OutNodeState ) ;
599         Done( true ) ;
600         _JustStarted = false ;
601       }
602       PushEvent( NULL , GraphExecutor::EndExecuteEvent ,
603                  OutNodeState ) ;
604 //      Py_Finalize() ;
605 //      PyInitialized( false ) ;
606     }
607   }
608   if ( IsDone() ) {
609     MESSAGE("================================================================================") ;
610     MESSAGE( Name() << " IS DONE : " <<  theAutomaton->StateName( AutomatonState() ) << " EventQSize "
611              << EventQSize() ) ;
612     MESSAGE("================================================================================") ;
613     cdebug << "================================================================================" << endl ;
614     cdebug << Name() << " IS DONE : " <<  theAutomaton->StateName( AutomatonState() ) << " EventQSize "
615              << EventQSize() << endl  ;
616     cdebug << "================================================================================" << endl ;
617     //cout << Name() << " IS DONE : " <<  theAutomaton->StateName( AutomatonState() ) << " EventQSize "
618     //     << EventQSize() << endl  ;
619   }
620   cdebug_out << "GraphExecutor::OutNode::CheckAllDone " << IsDone()
621              << " GraphAutomatonState " << theAutomaton->StateName( AutomatonState() )
622              << " State " << State() << " Threads " << _Threads << " SuspendedThreads "
623              << _SuspendedThreads << " EventQSize " << EventQSize() << endl ;
624 }
625
626 void GraphExecutor::OutNode::PThreadLock( pthread_mutex_t * aMutex , char * errmsg ) {
627 //  if ( strcmp( errmsg , "EventLoop" ) && strcmp( errmsg , "EventW" ) ) {
628 //    cdebug << "GraphExecutor::OutNode::PThreadLock " << pthread_self() << " " << aMutex << " "
629 //           << errmsg << endl ;
630 //  }
631   if ( pthread_mutex_lock( aMutex ) ) {
632     perror( errmsg ) ;
633     exit( 0 ) ;
634   }
635 //  if ( strcmp( errmsg , "EventLoop" ) && strcmp( errmsg , "EventW" ) ) {
636 //    cdebug << "GraphExecutor::OutNode::PThreadLocked " << pthread_self() << " " << aMutex << " "
637 //           << errmsg << endl ;
638 //  }
639 }
640
641 void GraphExecutor::OutNode::PThreadUnLock( pthread_mutex_t * aMutex , char * errmsg ) {
642 //  if ( strcmp( errmsg , "EventLoop" ) && strcmp( errmsg , "EventW" ) ) {
643 //    cdebug << " GraphExecutor::OutNode::PThreadUnLock " << pthread_self() << " " << aMutex << " "
644 //           << errmsg << endl ;
645 //  }
646   if ( pthread_mutex_unlock( aMutex ) ) {
647     perror( errmsg ) ;
648     exit( 0 ) ;
649   }
650 }
651
652 void GraphExecutor::OutNode::PyThreadLock() {
653 //  cout << " GraphExecutor::OutNode::PyThreadLock " << pthread_self() << endl ;
654   if ( pthread_mutex_lock( &_PyMutexWait ) ) {
655     perror( "GraphExecutor::OutNode::PyThreadLock" ) ;
656     exit( 0 ) ;
657   }
658   theAutomaton->PyLock() ;
659 //  cout << " GraphExecutor::OutNode::PyThreadLocked " << pthread_self() << endl ;
660 }
661
662 void GraphExecutor::OutNode::PyThreadUnLock() {
663 //  cout << " GraphExecutor::OutNode::PyThreadUnLock " << pthread_self() << endl ;
664   if ( pthread_mutex_unlock( &_PyMutexWait ) ) {
665     perror( "GraphExecutor::OutNode::PyThreadUnLock" ) ;
666     exit( 0 ) ;
667   }
668   theAutomaton->PyUnLock() ;
669 //  cout << " GraphExecutor::OutNode::PyThreadUnLocked " << pthread_self() << endl ;
670 }
671
672 void GraphExecutor::OutNode::NewThread() {
673   if ( pthread_mutex_lock( &_MutexWait ) ) {
674     perror("pthread_mutex_lock _NewThread") ;
675     exit( 0 ) ;
676   }
677   _Threads += 1 ;
678   cdebug << "NewThread : " << _Threads << " running threads "
679          << _SuspendedThreads << " suspended threads"
680          << endl ;
681   if ( pthread_mutex_unlock( &_MutexWait ) ) {
682     perror("pthread_mutex_unlock _NewThread") ;
683     exit( 0 ) ;
684   }
685 }
686
687 void GraphExecutor::OutNode::ExitThread() {
688   if ( pthread_mutex_lock( &_MutexWait ) ) {
689     perror("pthread_mutex_lock _ExitThread") ;
690     exit( 0 ) ;
691   }
692   _Threads -= 1 ;
693   theAutomaton->JoinThread( pthread_self() ) ;
694   if ( pthread_cond_signal( &_JoinWait ) ) {
695     perror("ExitThread pthread_cond_signal ") ;
696   }
697   cdebug << "ExitThread : " << _Threads << " running threads "
698          << _SuspendedThreads << " suspended threads"
699          << endl ;
700   if ( pthread_mutex_unlock( &_MutexWait ) ) {
701     perror("pthread_mutex_unlock _ExitThread") ;
702     exit( 0 ) ;
703   }
704   if ( _Threads == 0 && _SuspendedThreads == 0 ) {
705     CheckAllDone() ;
706     if ( IsDone() ) {
707       theAutomaton->Executed() ;
708     }
709   }
710 }
711 void GraphExecutor::OutNode::JoinedWait() {
712   if ( pthread_mutex_lock( &_MutexWait ) ) {
713     perror("pthread_mutex_lock JoinedWait") ;
714     exit( 0 ) ;
715   }
716   while ( _Threads ) {
717     if ( pthread_cond_wait( &_JoinWait , &_MutexWait ) ) {
718       perror("JoinedWait pthread_cond_wait ") ;
719     }
720   }
721   if ( pthread_mutex_unlock( &_MutexWait ) ) {
722     perror("pthread_mutex_unlock JoinedWait") ;
723     exit( 0 ) ;
724   }
725 }
726
727 void GraphExecutor::OutNode::SuspendThread() {
728   if ( pthread_mutex_lock( &_MutexWait ) ) {
729     perror("pthread_mutex_lock _SuspendThread") ;
730     exit( 0 ) ;
731   }
732   _SuspendedThreads += 1 ;
733   cdebug << "SuspendThread : " << _Threads << " running threads "
734          << _SuspendedThreads << " suspended threads"
735          << endl ;
736   if ( pthread_mutex_unlock( &_MutexWait ) ) {
737     perror("pthread_mutex_unlock _SuspendThread") ;
738     exit( 0 ) ;
739   }
740   if ( IsSuspended() ) {
741     PushEvent( NULL , GraphExecutor::SuspendEvent , SUPERV::SuspendedState ) ;
742   }
743 }
744 void GraphExecutor::OutNode::ResumeThread() {
745   if ( pthread_mutex_lock( &_MutexWait ) ) {
746     perror("pthread_mutex_lock _ResumeThread") ;
747     exit( 0 ) ;
748   }
749   _SuspendedThreads -= 1 ;
750   cdebug << "ResumeThread : " << _Threads << " running threads "
751          << _SuspendedThreads << " suspended threads"
752          << endl ;
753   if ( pthread_mutex_unlock( &_MutexWait ) ) {
754     perror("pthread_mutex_unlock _ResumeThread") ;
755     exit( 0 ) ;
756   }
757 }
758
759 long GraphExecutor::OutNode::Thread( const char * aNodeName ) {
760   long RetVal = 0 ;
761   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( aNodeName )->GetInNode() ;
762   if ( anInNode ) {
763     RetVal = anInNode->ThreadNo() ;
764   }
765   return RetVal ;
766 }
767
768 SUPERV::GraphEvent GraphExecutor::OutNode::AutomatonGraphEvent(GraphExecutor::NodeEvent anEvent ) {
769   SUPERV::GraphEvent aGraphEvent ;
770   switch ( anEvent ) {
771   case GraphExecutor::UndefinedEvent : {
772     aGraphEvent = SUPERV::UndefinedEvent ;
773     break ;
774   }
775   case GraphExecutor::NewThreadEvent : {
776     aGraphEvent = SUPERV::NewThreadEvent ;
777     break ;
778   }
779   case GraphExecutor::SuspendEvent : {
780     aGraphEvent = SUPERV::SuspendEvent ;
781     break ;
782   }
783   case GraphExecutor::ResumeEvent : {
784     aGraphEvent = SUPERV::ResumeEvent ;
785     break ;
786   }
787   case GraphExecutor::KillEvent : {
788     aGraphEvent = SUPERV::KillEvent ;
789     break ;
790   }
791   case GraphExecutor::StopEvent : {
792     aGraphEvent = SUPERV::StopEvent ;
793     break ;
794   }
795   case GraphExecutor::ExecuteEvent : {
796     aGraphEvent = SUPERV::RunningEvent ;
797     break ;
798   }
799   case GraphExecutor::SuccessEvent : {
800     aGraphEvent = SUPERV::DoneEvent ;
801     break ;
802   }
803   case GraphExecutor::ErrorEvent : {
804     aGraphEvent = SUPERV::ErroredEvent ;
805     break ;
806   }
807   case GraphExecutor::ReStartEvent : {
808     aGraphEvent = SUPERV::ReRunEvent ;
809     break ;
810   }
811   case GraphExecutor::ReStartAndSuspendEvent : {
812     aGraphEvent = SUPERV::ReStartEvent ;
813     break ;
814   }
815   case GraphExecutor::NoDataReadyEvent : {
816     aGraphEvent = SUPERV::WaitingEvent ;
817     break ;
818   }
819   case GraphExecutor::SomeDataReadyEvent : {
820     aGraphEvent = SUPERV::WaitingEvent ;
821     break ;
822   }
823   case GraphExecutor::NotAllDataReadyEvent : {
824     aGraphEvent = SUPERV::WaitingEvent ;
825     break ;
826   }
827   case GraphExecutor::AllDataReadyEvent : {
828     aGraphEvent = SUPERV::ReadyEvent ;
829     break ;
830   }
831   case GraphExecutor::ReadyEvent : {
832     aGraphEvent = SUPERV::ReadyEvent ;
833     break ;
834   }
835   case GraphExecutor::SuspendedReadyEvent : {
836     aGraphEvent = SUPERV::SuspendEvent ;
837     break ;
838   }
839   case GraphExecutor::ResumedReadyEvent : {
840     aGraphEvent = SUPERV::ResumeEvent ;
841     break ;
842   }
843   case GraphExecutor::KilledReadyEvent : {
844     aGraphEvent = SUPERV::KillEvent ;
845     break ;
846   }
847   case GraphExecutor::StoppedReadyEvent : {
848     aGraphEvent = SUPERV::StopEvent ;
849     break ;
850   }
851   case GraphExecutor::ExecutingEvent : {
852     aGraphEvent = SUPERV::RunningEvent ;
853     break ;
854   }
855   case GraphExecutor::SuspendedExecutingEvent : {
856     aGraphEvent = SUPERV::SuspendEvent ;
857     break ;
858   }
859   case GraphExecutor::ResumedExecutingEvent : {
860     aGraphEvent = SUPERV::ResumeEvent ;
861     break ;
862   }
863   case GraphExecutor::KilledExecutingEvent : {
864     aGraphEvent = SUPERV::KillEvent ;
865     break ;
866   }
867   case GraphExecutor::StoppedExecutingEvent : {
868     aGraphEvent = SUPERV::StopEvent ;
869     break ;
870   }
871   case GraphExecutor::SuccessedExecutingEvent : {
872     aGraphEvent = SUPERV::DoneEvent ;
873     break ;
874   }
875   case GraphExecutor::ErroredExecutingEvent : {
876     aGraphEvent = SUPERV:: ErroredEvent;
877     break ;
878   }
879   case GraphExecutor::SuspendedSuccessedEvent : {
880     aGraphEvent = SUPERV::SuspendEvent ;
881     break ;
882   }
883   case GraphExecutor::SuspendedErroredEvent : {
884     aGraphEvent = SUPERV::SuspendEvent ;
885     break ;
886   }
887   case GraphExecutor::ResumedSuccessedEvent : {
888     aGraphEvent = SUPERV::ResumeEvent ;
889     break ;
890   }
891   case GraphExecutor::ResumedErroredEvent : {
892     aGraphEvent = SUPERV::ResumeEvent ;
893     break ;
894   }
895   case GraphExecutor::KilledEvent : {
896     aGraphEvent = SUPERV::KillEvent ;
897     break ;
898   }
899   case GraphExecutor::StoppedEvent : {
900     aGraphEvent = SUPERV::StopEvent ;
901     break ;
902   }
903   case GraphExecutor::ReStartedEvent : {
904     aGraphEvent = SUPERV::ReRunEvent ;
905     break ;
906   }
907   case GraphExecutor::ReStartedAndSuspendEvent : {
908     aGraphEvent = SUPERV::ReStartEvent ;
909     break ;
910   }
911   case GraphExecutor::EndExecuteEvent : {
912     aGraphEvent = SUPERV::DoneEvent ;
913     break ;
914   }
915   default : {
916     cdebug << " GraphExecutor::OutNode::AutomatonGraphEvent Error Undefined Event : "
917            << anEvent << endl ;
918     aGraphEvent = SUPERV::UndefinedEvent ;
919   }
920   }
921   return aGraphEvent ;
922 }
923
924 SUPERV::GraphState GraphExecutor::OutNode::AutomatonGraphState(SUPERV::AutomatonState aState ) {
925   SUPERV::GraphState aGraphState ;
926   switch ( aState ) {
927   case SUPERV::UnKnownState : {
928     aGraphState = SUPERV::UndefinedState ;
929     break ;
930   }
931   case SUPERV::DataUndefState : {
932     aGraphState = SUPERV::UndefinedState ;
933     break ;
934   }
935   case SUPERV::DataWaitingState : {
936     aGraphState = SUPERV::WaitingState ;
937     break ;
938   }
939   case SUPERV::DataReadyState : {
940     aGraphState = SUPERV::ReadyState ;
941     break ;
942   }
943   case SUPERV::SuspendedReadyState : {
944     aGraphState = SUPERV::SuspendReadyState ;
945     break ;
946   }
947   case SUPERV::ResumedReadyState : {
948     aGraphState = SUPERV::ReadyState ;
949     break ;
950   }
951   case SUPERV::KilledReadyState : {
952     aGraphState = SUPERV::KillState ;
953     break ;
954   }
955   case SUPERV::StoppedReadyState : {
956     aGraphState = SUPERV::StopState ;
957     break ;
958   }
959   case SUPERV::ExecutingState : {
960     aGraphState = SUPERV::RunningState ;
961     break ;
962   }
963   case SUPERV::SuspendedExecutingState : {
964     aGraphState = SUPERV::SuspendState ;
965     break ;
966   }
967   case SUPERV::ResumedExecutingState : {
968     aGraphState = SUPERV::RunningState ;
969     break ;
970   }
971   case SUPERV::KilledExecutingState : {
972     aGraphState = SUPERV::KillState ;
973     break ;
974   }
975   case SUPERV::StoppedExecutingState : {
976     aGraphState = SUPERV::StopState ;
977     break ;
978   }
979   case SUPERV::SuccessedExecutingState : {
980     aGraphState = SUPERV::DoneState ;
981     break ;
982   }
983   case SUPERV::ErroredExecutingState : {
984     aGraphState = SUPERV::ErrorState ;
985     break ;
986   }
987   case SUPERV::SuspendedSuccessedState : {
988     aGraphState = SUPERV::SuspendDoneState ;
989     break ;
990   }
991   case SUPERV::SuspendedErroredState : {
992     aGraphState = SUPERV::SuspendErroredState ;
993     break ;
994   }
995   case SUPERV::ResumedSuccessedState : {
996     aGraphState = SUPERV::DoneState ;
997     break ;
998   }
999   case SUPERV::ResumedErroredState : {
1000     aGraphState = SUPERV::ErrorState ;
1001     break ;
1002   }
1003   case SUPERV::KilledSuccessedState : {
1004     aGraphState = SUPERV::KillState ;
1005     break ;
1006   }
1007   case SUPERV::KilledErroredState : {
1008     aGraphState = SUPERV::KillState ;
1009     break ;
1010   }
1011   case SUPERV::StoppedSuccessedState : {
1012     aGraphState = SUPERV::StopState ;
1013     break ;
1014   }
1015   case SUPERV::StoppedErroredState : {
1016     aGraphState = SUPERV::StopState ;
1017     break ;
1018   }
1019   case SUPERV::SuccessedState : {
1020     aGraphState = SUPERV::DoneState ;
1021     break ;
1022   }
1023   case SUPERV::ErroredState : {
1024     aGraphState = SUPERV::ErrorState ;
1025     break ;
1026   }
1027   case SUPERV::SuspendedState : {
1028     aGraphState = SUPERV::SuspendState ;
1029     break ;
1030   }
1031   case SUPERV::KilledState : {
1032     aGraphState = SUPERV::KillState ;
1033     break ;
1034   }
1035   case SUPERV::StoppedState : {
1036     aGraphState = SUPERV::StopState ;
1037     break ;
1038   }
1039   case SUPERV::ReRunnedState : {
1040     aGraphState = SUPERV::ReRunState ;
1041     break ;
1042   }
1043   case SUPERV::ReStartedState : {
1044     aGraphState = SUPERV::ReStartState ;
1045     break ;
1046   }
1047   default : {
1048     cdebug << " GraphExecutor::OutNode::AutomatonGraphState Error Undefined State : "
1049            << aGraphState << endl ;
1050     aGraphState = SUPERV::UndefinedState ;
1051   }
1052   }
1053   return aGraphState ;
1054 }
1055
1056 int GraphExecutor::OutNode::GetListSize() {
1057   return _EventNodes.size();
1058 }
1059
1060 bool GraphExecutor::OutNode::PushEvent( GraphExecutor::InNode * aNode ,
1061                                         GraphExecutor::NodeEvent anEvent ,
1062                                         SUPERV::AutomatonState aState ) {
1063 //  cdebug_in << "PushEvent Threads " << Threads() << " SuspendedThreads "
1064 //            << SuspendedThreads() << endl ;
1065   if ( pthread_mutex_lock( &_MutexWait ) ) {
1066     perror("PushEvent pthread_mutex_lock ") ;
1067     exit( 0 ) ;
1068   }
1069   if ( aNode ) {
1070     _EventNodes.push_back( aNode->Name() ) ;
1071   }
1072   else {
1073     _EventNodes.push_back( Name() ) ;
1074   }
1075   _Events.push_back( anEvent ) ;
1076   _States.push_back( aState ) ;
1077   pthread_cond_broadcast( &_EventWait );
1078   if ( aNode ) {
1079 //    cdebug << aNode->ThreadNo() << " PushEvent " << aNode->Name() ;
1080 //    cdebug << " " << aNode->Automaton()->EventName( anEvent )
1081 //           << " " << aNode->Automaton()->StateName( aState )
1082 //           << " ControleState "
1083 //           << aNode->Automaton()->ControlStateName( aNode->ControlState() ) ;
1084   }
1085   else {
1086 //    cdebug << "PushEvent " << Name() ;
1087 //    cdebug << " " << theAutomaton->EventName( anEvent ) << " "
1088 //           << theAutomaton->StateName( aState ) ;
1089   }
1090 //  cdebug_out << "PushEvent Threads " << Threads() << " SuspendedThreads "
1091 //             << SuspendedThreads() << endl ;
1092 #if 0
1093   if ( _EventNodes.size() > 101 ) {
1094     while ( _EventNodes.size() > 31 ) {
1095       _EventNodes.pop_front() ;
1096       _Events.pop_front() ;
1097       _States.pop_front() ;
1098     }
1099   }
1100 #endif
1101   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1102     perror("PushEvent pthread_mutex_unlock ") ;
1103     exit( 0 ) ;
1104   }
1105   return true ;
1106 }
1107
1108 bool GraphExecutor::OutNode::StateWait( SUPERV::GraphState aState ) {
1109   return false ;
1110 }
1111
1112 bool GraphExecutor::OutNode::Event( char ** aNodeName ,
1113                                     SUPERV::GraphEvent & anEvent ,
1114                                     SUPERV::GraphState & aState ,
1115                                     bool WithWait ) {
1116   int ThreadsNumber ;
1117   int SuspendedThreadsNumber ;
1118   if ( _EventNodes.size() > 0 ) {
1119     cdebug_in << "GraphExecutor::OutNode::Event " << _EventNodes.size() << " in queue" << endl ;
1120   }
1121   if ( pthread_mutex_lock( &_MutexWait ) ) {
1122     perror("EventLoop pthread_mutex_lock ") ;
1123     exit( 0 ) ;
1124   }
1125   _JustStarted = false ;
1126   ThreadsNumber = Threads() ;
1127   SuspendedThreadsNumber = SuspendedThreads() ;
1128   bool RetVal = ( ThreadsNumber - SuspendedThreadsNumber) != 0 ||
1129                 _EventNodes.size() > 0 ;
1130   char * NodeName = "" ;
1131   GraphExecutor::NodeEvent theEvent = GraphExecutor::UndefinedEvent ;
1132   SUPERV::AutomatonState theState = SUPERV::UnKnownState ;
1133   anEvent = SUPERV::UndefinedEvent ;
1134   aState = SUPERV::UndefinedState ;
1135   if ( ( Done() || IsKilled() || IsStopped() ) && _EventNodes.size() == 0 ) {
1136 //    cdebug << "EventLoop Done()/IsKilled()/IsStopped() && _EventNodes.size() == 0" << endl ;
1137     RetVal = false ;
1138   }
1139   else if ( !WithWait && _EventNodes.size() == 0 ) {
1140     anEvent = SUPERV::NoEvent ;
1141     aState = SUPERV::NoState ;
1142     RetVal = true ;
1143   }
1144   else if ( RetVal ) {
1145     while ( !IsSuspended() && _EventNodes.size() == 0 ) {
1146 //      cdebug << "EventLoop pthread_cond_wait _EventWait" << endl ;
1147       pthread_cond_wait( &_EventWait , &_MutexWait );
1148 //      cdebug << "EventLoop pthread_cond_waited _EventWait"
1149 //             << " _EventNodes.size() " << _EventNodes.size() << endl ;
1150     }
1151     if ( _EventNodes.size() ) {
1152       ThreadsNumber = Threads() ;
1153       NodeName = _EventNodes.front() ;
1154       _EventNodes.pop_front() ;
1155       theEvent = _Events.front() ;
1156       anEvent = AutomatonGraphEvent( theEvent ) ;
1157       _Events.pop_front() ;
1158       theState = _States.front() ;
1159       aState = AutomatonGraphState( theState ) ;
1160       _States.pop_front() ;
1161     }
1162   }
1163   *aNodeName = NodeName ;
1164   if ( IsSuspended() && _EventNodes.size() == 0 ) {
1165     RetVal = false ;
1166   }
1167   if ( anEvent != SUPERV::NoEvent ) {
1168 //    cdebug << pthread_self() << "EventLoop "
1169 //           << NodeName << " " << theAutomaton->StateName( theState )
1170 //           << " _EventNodes.size() " << _EventNodes.size()
1171 //           << " Threads " << Threads() << " SuspendedThreads "
1172 //           << SuspendedThreads() << " RetVal " << RetVal << endl ;
1173   }
1174   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1175     perror("EventLoop pthread_mutex_lock ") ;
1176     exit( 0 ) ;
1177   }
1178   if ( _EventNodes.size() > 0 ) {
1179     cdebug_out << "GraphExecutor::OutNode::Event " << _EventNodes.size() << " in queue" << endl ;
1180   }
1181   return RetVal ;
1182 }
1183
1184 bool GraphExecutor::OutNode::EventW( char ** aNodeName ,
1185                                      SUPERV::GraphEvent & anEvent ,
1186                                      SUPERV::GraphState & aState ) {
1187   bool sts = true ;
1188   char * NodeName ;
1189   aState = SUPERV::UndefinedState ;
1190   while ( sts &&
1191           aState != SUPERV::SuspendReadyState &&
1192           aState != SUPERV::RunningState &&
1193           aState != SUPERV::SuspendDoneState &&
1194           aState != SUPERV::SuspendErroredState ) {
1195     NodeName = Name() ;
1196     while ( sts && !strcmp( NodeName , Name() ) ) {
1197       sts = EventWait( aNodeName , anEvent , aState ) ;
1198       NodeName = *aNodeName ;
1199     }
1200   }
1201   return sts ;
1202 }
1203
1204 bool GraphExecutor::OutNode::EventWait( char ** aNodeName ,
1205                                         SUPERV::GraphEvent & anEvent ,
1206                                         SUPERV::GraphState & aState ) {
1207   if ( pthread_mutex_lock( &_MutexWait ) ) {
1208     perror("EventW pthread_mutex_lock ") ;
1209     exit( 0 ) ;
1210   }
1211   int ThreadsNumber ;
1212   int SuspendedThreadsNumber ;
1213   ThreadsNumber = Threads() ;
1214   SuspendedThreadsNumber = SuspendedThreads() ;
1215   bool RetVal = ( ThreadsNumber - SuspendedThreadsNumber) != 0 ||
1216                 _EventNodes.size() > 0 ;
1217   cdebug << "--> EventW RetVal " << RetVal << endl ;
1218   char * NodeName = "" ;
1219   GraphExecutor::NodeEvent theEvent = GraphExecutor::UndefinedEvent ;
1220   SUPERV::AutomatonState theState = SUPERV::UnKnownState ;
1221   anEvent = SUPERV::UndefinedEvent ;
1222   aState = SUPERV::UndefinedState ;
1223   if ( IsDone() && _EventNodes.size() == 0 ) {
1224     cdebug << "EventW IsDone() && _EventNodes.size() == 0" << endl ;
1225     RetVal = 0 ;
1226   }
1227   else if ( RetVal ) {
1228     GraphExecutor::InNode * aNode = NULL ;
1229     while ( aNode == NULL && RetVal ) {
1230       NodeName = _EventNodes.front() ;
1231       theEvent = _Events.front() ;
1232       anEvent = AutomatonGraphEvent( theEvent ) ;
1233       theState = _States.front() ;
1234       aState = AutomatonGraphState( theState ) ;
1235
1236       if ( _JustStarted ) {
1237         _JustStarted = false ;
1238       }
1239       else {
1240         _EventNodes.pop_front() ;
1241         _Events.pop_front() ;
1242         _States.pop_front() ;
1243       }
1244
1245       aNode = ((GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode()) ;
1246       cdebug << "EventW Previous Node " << NodeName << " ThreadsNumber "
1247              << ThreadsNumber
1248              << " _EventNodes.size() " << _EventNodes.size() << " "
1249              << theAutomaton->StateName( theState )
1250              << " Threads " << Threads() << " SuspendedThreads "
1251              << SuspendedThreads() << endl ;
1252       if ( aNode ) {
1253       }
1254       else if ( IsDone() && _EventNodes.size() == 0 ) {
1255         cdebug << "EventW IsDone() && _EventNodes.size() == 0" << endl ;
1256         RetVal = 0 ;
1257       }
1258       else {
1259         cdebug << "EventW Not InNode " << NodeName
1260                << " _EventNodes.size() " << _EventNodes.size() << endl ;
1261         while ( _EventNodes.size() == 0 ) {
1262           pthread_cond_wait( &_EventWait , &_MutexWait );
1263         }
1264         cdebug << "EventW pthread_cond_waited Not InNode " << NodeName
1265                << " _EventNodes.size() " << _EventNodes.size() << endl ;
1266       }
1267     }
1268
1269     if ( aNode ) {
1270       if ( aState == SUPERV::SuspendState ||
1271            aState == SUPERV::SuspendReadyState ||
1272            aState == SUPERV::SuspendDoneState ||
1273            aState == SUPERV::SuspendErroredState ) {
1274         aNode->ControlState( SUPERV::ToSuspendState ) ;
1275         if ( aNode->IsSuspended() ) {
1276           if ( pthread_mutex_unlock( &_MutexWait ) ) {
1277             perror("EventW pthread_mutex_lock ") ;
1278             exit( 0 ) ;
1279           }
1280           cdebug << "EventW " << aNode->Name() << " ResumeAction" << endl ;
1281           aNode->ResumeAction( GraphExecutor::ToResumeEvent ) ;
1282           cdebug << "EventW " << aNode->Name() << " ResumedAction" << endl ;
1283           if ( pthread_mutex_lock( &_MutexWait ) ) {
1284             perror("EventW pthread_mutex_lock ") ;
1285             exit( 0 ) ;
1286           }
1287         }
1288         else {
1289           cdebug << "EventW inconsistent SuspendState" << endl ;
1290           RetVal = false ; 
1291         }
1292       }
1293       else {
1294         if ( aNode->IsDone() ) {
1295           RetVal = true ;
1296         }
1297         else {
1298           cdebug << "EventW NOT SuspendedState _EventNodes.size() "
1299                  << _EventNodes.size() << endl ;
1300           RetVal = true ;
1301         }
1302       }
1303       if ( RetVal ) {
1304         cdebug << "EventW " << aNode->Name() << " pthread_cond_wait" << endl ;
1305         while ( _EventNodes.size() == 0 ) {
1306           pthread_cond_wait( &_EventWait , &_MutexWait );
1307         }
1308         ThreadsNumber = Threads() ;
1309         NodeName = _EventNodes.front() ;
1310         theEvent = _Events.front() ;
1311         anEvent = AutomatonGraphEvent( theEvent ) ;
1312         theState = _States.front() ;
1313         aState = AutomatonGraphState( theState ) ;
1314       }
1315     }
1316   }
1317   *aNodeName = NodeName ;
1318   cdebug << "<-- EventW RetVal " << RetVal << " " << NodeName
1319          << " Threads " << Threads() << " SuspendedThreads "
1320          << SuspendedThreads()
1321          << " _EventNodes.size() " << _EventNodes.size()
1322          << " " << theAutomaton->EventName( theEvent ) << " "
1323          << theAutomaton->StateName( theState ) << endl ;
1324   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1325     perror("EventW pthread_mutex_lock ") ;
1326     exit( 0 ) ;
1327   }
1328   return RetVal ;
1329 }
1330 long GraphExecutor::OutNode::EventQSize() {
1331   return _EventNodes.size() ;
1332 }
1333
1334 void GraphExecutor::OutNode::EventList() {
1335   if ( pthread_mutex_lock( &_MutexWait ) ) {
1336     perror("EventList pthread_mutex_lock ") ;
1337     exit( 0 ) ;
1338   }
1339   list< char * >::iterator itEventNodes = _EventNodes.begin() ;
1340   list< GraphExecutor::NodeEvent >::iterator itEvents = _Events.begin() ;
1341   list< SUPERV::AutomatonState >::iterator itStates = _States.begin() ;
1342   while ( itEventNodes != _EventNodes.end() ) {
1343     cdebug << pthread_self() << "EVENTSTACK "
1344            << *itEventNodes << " " << *itEvents << " "
1345            << theAutomaton->StateName( *itStates )
1346            << " Threads " << Threads() << " SuspendedThreads " << SuspendedThreads() << endl ;
1347     itEventNodes++ ;
1348     itEvents++ ;
1349     itStates++ ;
1350   }
1351   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1352     perror("EventList pthread_mutex_lock ") ;
1353     exit( 0 ) ;
1354   }
1355 }
1356
1357 void GraphExecutor::OutNode::State(SUPERV::AutomatonState aState ) {
1358 //  cdebug << "GraphExecutor::OutNode::State " << Name() << " "
1359 //         << theAutomaton->StateName( AutomatonGraphState( _State ) ) << " ---> "
1360 //         << theAutomaton->StateName( AutomatonGraphState( aState ) ) << endl ;
1361   _State = aState ;
1362 }
1363
1364 SUPERV::GraphState GraphExecutor::OutNode::State() {
1365 //  cdebug_in << "GraphExecutor::OutNode::State" << endl;
1366 //  cdebug_out << "GraphExecutor::OutNode::State" << endl ;
1367 //  cdebug << "GraphExecutor::OutNode::State GraphState "
1368 //         << theAutomaton->StateName( AutomatonGraphState( _State ) ) << endl ;
1369   return AutomatonGraphState( _State ) ;
1370 }
1371
1372 SUPERV::GraphState GraphExecutor::OutNode::State( const char * NodeName ) {
1373 //  cdebug_in << "GraphExecutor::OutNode::State " << NodeName << endl;
1374   SUPERV::AutomatonState aret = SUPERV::UnKnownState ;
1375   const GraphBase::ComputingNode * aCNode =  GetGraphNode( NodeName ) ;
1376   if ( aCNode ) {
1377     GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *)aCNode->GetInNode() ;
1378     if ( anInNode ) {
1379       aret = anInNode->State() ;
1380 //      cdebug << "GraphExecutor::OutNode::State( " << NodeName << " ) "
1381 //             << theAutomaton->StateName( AutomatonGraphState( aret ) ) << endl ;
1382     }
1383   }
1384 //  cdebug_out << "GraphExecutor::OutNode::State" << endl ;
1385   return AutomatonGraphState( aret ) ;
1386 }
1387
1388 SUPERV::GraphState GraphExecutor::OutNode::State( const char * NodeName ,
1389                                                   const char * ServiceParameterName )  {
1390 //  cdebug_in << "GraphExecutor::OutNode::State " << NodeName << " "
1391 //            << ServiceParameterName<< endl;
1392   SUPERV::GraphState aret = PortState( NodeName , ServiceParameterName ) ;
1393 //  cdebug_out << "GraphExecutor::OutNode::State" << endl ;
1394   return aret ;
1395 }
1396
1397 SUPERV::AutomatonState GraphExecutor::OutNode::AutomatonState() {
1398 //  cdebug_in << "GraphExecutor::OutNode::AutomatonState" << endl;
1399 //  cdebug_out << "GraphExecutor::OutNode::AutomatonState" << endl ;
1400   return _State ;
1401 }
1402
1403 SUPERV::AutomatonState GraphExecutor::OutNode::AutomatonState( const char * NodeName ) {
1404 //  cdebug_in << "GraphExecutor::OutNode::AutomatonState " << NodeName << endl;
1405   SUPERV::AutomatonState aret = SUPERV::UnKnownState ;
1406   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1407   if ( anInNode )
1408     aret = anInNode->State() ;
1409 //  cdebug_out << "GraphExecutor::OutNode::AutomatonState" << endl ;
1410   return aret ;
1411 }
1412
1413 SUPERV::ControlState GraphExecutor::OutNode::ControlState() {
1414 //  cdebug_in << "GraphExecutor::OutNode::ControlState" << endl;
1415 //  cdebug_out << "GraphExecutor::OutNode::ControlState" << endl ;
1416   return _ControlState ;
1417 }
1418
1419 SUPERV::ControlState GraphExecutor::OutNode::ControlState( const char * NodeName ) {
1420 //  cdebug_in << "GraphExecutor::OutNode::ControlState " << NodeName << endl;
1421   SUPERV::ControlState aret = SUPERV::VoidState ;
1422   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1423   if ( anInNode )
1424     aret = anInNode->ControlState() ;
1425 //  cdebug_out << "GraphExecutor::OutNode::ControlState" << endl ;
1426   return aret ;
1427 }
1428
1429 void GraphExecutor::OutNode::ControlClear() {
1430 //  cdebug_in << "GraphExecutor::OutNode::ControlClear" << endl;
1431 //  cdebug_out << "GraphExecutor::OutNode::ControlClear" << endl ;
1432   _ControlState = SUPERV::VoidState;
1433 }
1434
1435 void GraphExecutor::OutNode::ControlClear( const char * NodeName ) {
1436 //  cdebug_in << "GraphExecutor::OutNode::ControlClear " << NodeName << endl;
1437   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1438   if ( anInNode )
1439     anInNode->ControlClear() ;
1440 //  cdebug_out << "GraphExecutor::OutNode::ControlClear" << endl ;
1441 }
1442
1443 bool GraphExecutor::OutNode::IsWaiting() {
1444 //  cdebug_in << "GraphExecutor::OutNode::IsWaiting" << endl;
1445 //  cdebug_out << "GraphExecutor::OutNode::IsWaiting" << endl ;
1446   return !IsDone() ;
1447 }
1448
1449 bool GraphExecutor::OutNode::IsReady() {
1450 //  cdebug_in << "GraphExecutor::OutNode::IsReady" << endl;
1451 //  cdebug_out << "GraphExecutor::OutNode::IsReady" << endl ;
1452   return !IsDone() ;
1453 }
1454
1455 bool GraphExecutor::OutNode::IsRunning() {
1456 //  cdebug_in << "GraphExecutor::OutNode::IsRunning" << endl;
1457 //  cdebug_out << "GraphExecutor::OutNode::IsRunning" << endl ;
1458   return !IsDone() ;
1459 }
1460
1461 bool GraphExecutor::OutNode::IsDone() {
1462 //  cdebug_in << "GraphExecutor::OutNode::IsDone" << endl;
1463 //  cdebug_out << "GraphExecutor::OutNode::IsDone" << endl ;
1464   return ( Done() || IsKilled() || IsStopped() ) ;
1465 }
1466
1467 bool GraphExecutor::OutNode::IsSuspended() {
1468 //  cdebug_in << "GraphExecutor::OutNode::IsSuspended" << endl;
1469   bool aret = false ;
1470   if ( _SuspendedThreads == _Threads ) {
1471     aret = true ;
1472   }
1473 //  cdebug_out << "GraphExecutor::OutNode::IsSuspended" << endl ;
1474   return aret ;
1475 }
1476
1477 bool GraphExecutor::OutNode::IsKilled() {
1478 //  cdebug_in << "GraphExecutor::OutNode::IsKilled" << endl;
1479   bool aret = false ;
1480   if ( AutomatonGraphState( _State ) == SUPERV::KillState ) {
1481     aret = true ;
1482   }
1483 //  cdebug_out << "GraphExecutor::OutNode::IsKilled" << endl ;
1484   return aret ;
1485 }
1486
1487 bool GraphExecutor::OutNode::IsStopped() {
1488 //  cdebug_in << "GraphExecutor::OutNode::IsStopped" << endl;
1489   bool aret = false ;
1490   if ( AutomatonGraphState( _State ) == SUPERV::StopState ) {
1491     aret = true ;
1492   }
1493 //  cdebug_out << "GraphExecutor::OutNode::IsStopped" << endl ;
1494   return aret ;
1495 }
1496
1497 bool GraphExecutor::OutNode::IsWaiting( const char * NodeName ) {
1498   bool aret = false ;
1499 //  cdebug_in << "GraphExecutor::OutNode::IsWaiting " << NodeName << endl;
1500   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1501   if ( anInNode ) {
1502     aret = anInNode->IsWaiting() ;
1503   }
1504 //  cdebug_out << "GraphExecutor::OutNode::IsWaiting" << endl ;
1505   return aret ;
1506 }
1507
1508 bool GraphExecutor::OutNode::IsReady( const char * NodeName ) {
1509   bool aret = false ;
1510 //  cdebug_in << "GraphExecutor::OutNode::IsReady " << NodeName << endl;
1511   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1512   if ( anInNode ) {
1513     aret = anInNode->IsReady() ;
1514   }
1515 //  cdebug_out << "GraphExecutor::OutNode::IsReady" << endl ;
1516   return aret ;
1517 }
1518
1519 bool GraphExecutor::OutNode::IsRunning( const char * NodeName ) {
1520   bool aret = false ;
1521 //  cdebug_in << "GraphExecutor::OutNode::IsRunning " << NodeName << endl;
1522   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1523   if ( anInNode ) {
1524     aret = anInNode->IsRunning() ;
1525   }
1526 //  cdebug_out << "GraphExecutor::OutNode::IsRunning" << endl ;
1527   return aret ;
1528 }
1529
1530 bool GraphExecutor::OutNode::IsDone( const char * NodeName ) {
1531   bool aret = false ;
1532 //  cdebug_in << "GraphExecutor::OutNode::IsDone " << NodeName << endl;
1533   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1534   if ( anInNode ) {
1535     aret = anInNode->IsDone() ;
1536   }
1537 //  cdebug_out << "GraphExecutor::OutNode::IsDone" << endl ;
1538   return aret ;
1539 }
1540
1541 bool GraphExecutor::OutNode::IsSuspended( const char * NodeName ) {
1542   bool aret = false ;
1543 //  cdebug_in << "GraphExecutor::OutNode::IsSuspended " << NodeName << endl;
1544   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1545   if ( anInNode ) {
1546     aret = anInNode->IsSuspended() ;
1547   }
1548 //  cdebug_out << "GraphExecutor::OutNode::IsSuspended" << endl ;
1549   return aret ;
1550 }
1551
1552 bool GraphExecutor::OutNode::IsDone( const char * NodeName ,
1553                                      const char * ServiceParameterName )  {
1554 //  cdebug_in << "GraphExecutor::OutNode::IsDone " << NodeName << " "
1555 //            << ServiceParameterName<< endl;
1556   bool aret = PortDone( NodeName , ServiceParameterName ) ;
1557 //  cdebug_out << "GraphExecutor::OutNode::IsDone" << endl ;
1558   return aret ;
1559 }
1560
1561 bool GraphExecutor::OutNode::ContainerKill() {
1562   bool RetVal = true ;
1563   cdebug_in << "GraphExecutor::OutNode::ContainerKill" << endl;
1564   _ControlState = SUPERV::ToSuspendState ;
1565   int i ;
1566   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1567     GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) GraphNodes( i )->GetInNode() ;
1568     bool sts = aNode->ContainerKill() ;
1569     if ( sts && aNode->IsKilled() ) {
1570       cdebug << aNode->Name() << " killed" << endl ;
1571     }
1572     else if ( aNode->IsWaiting() || aNode->IsDone() ) {
1573       cdebug << aNode->Name() << " not killed : "
1574              << theAutomaton->StateName( aNode->State() ) << endl ;
1575     }
1576     else {
1577       cdebug << aNode->Name() << " cannot be killed : "
1578              << theAutomaton->StateName( aNode->State() ) << endl ;
1579       RetVal = false ;
1580     }
1581   }
1582   if ( !RetVal || Threads() != 0 ) {
1583     for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1584       GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) GraphNodes( i )->GetInNode() ;
1585       if ( !aNode->IsKilled() && !aNode->IsWaiting() && !aNode->IsDone() ) {
1586         aNode->KilledAction() ;
1587       }
1588     }
1589     RetVal = true ;
1590   }
1591   State( SUPERV::KilledState ) ;
1592   cdebug_out << "GraphExecutor::OutNode::ContainerKill" << endl ;
1593   return RetVal ;
1594 }
1595
1596 bool GraphExecutor::OutNode::Suspend() {
1597   int RetVal = 0 ;
1598   cdebug_in << "GraphExecutor::OutNode::Suspend" << endl;
1599 //  _ControlState = SUPERV::ToSuspendState ;
1600   int i ;
1601   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1602     GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) GraphNodes( i )->GetInNode() ;
1603     bool sts = aNode->Suspend() ;
1604     if ( sts && aNode->IsSuspended() ) {
1605       RetVal += 1 ;
1606       cdebug << aNode->Name() << " Suspended" << endl ;
1607     }
1608     else if ( aNode->IsWaiting() || aNode->IsDone() ) {
1609       cdebug << aNode->Name() << " not Suspended : "
1610              << theAutomaton->StateName( aNode->State() ) << endl ;
1611     }
1612     else {
1613       RetVal += 1 ;
1614       cdebug << aNode->Name() << " cannot be Suspended : "
1615              << theAutomaton->StateName( aNode->State() ) << endl ;
1616     }
1617   }
1618   if ( RetVal ) {
1619     State( SUPERV::SuspendedState ) ;
1620     MESSAGE("================================================================================") ;
1621     MESSAGE( Name() << " IS SUSPENDED" ) ;
1622     MESSAGE("================================================================================") ;
1623   }
1624   else {
1625     MESSAGE("================================================================================") ;
1626     MESSAGE( Name() << " IS NOT SUSPENDED" ) ;
1627     MESSAGE("================================================================================") ;
1628   }
1629   cdebug_out << "GraphExecutor::OutNode::Suspend" << theAutomaton->StateName( State() ) << endl ;
1630   return RetVal ;
1631 }
1632
1633 bool GraphExecutor::OutNode::Resume() {
1634   int RetVal = 0 ;
1635   cdebug_in << "GraphExecutor::OutNode::Resume" << endl;
1636   if ( IsSuspended() ) {
1637     State( SUPERV::ExecutingState ) ;
1638     int i ;
1639     for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1640       GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) GraphNodes( i )->GetInNode() ;
1641       aNode->ControlState( SUPERV::VoidState ) ;
1642       if ( aNode->IsSuspended() ) {
1643         cdebug << aNode->Name() << "->Resume " << theAutomaton->StateName( aNode->State() )
1644                << endl ;
1645         if ( aNode->Resume() ) {
1646           cdebug << aNode->Name() << " Resumed " << theAutomaton->StateName( aNode->State() )
1647                  << endl ;
1648           RetVal += 1 ;
1649         }
1650         else {
1651           cdebug << aNode->Name() << " Resume failed"
1652                  << theAutomaton->StateName( aNode->State() ) << endl ;
1653         }
1654       }
1655       else {
1656         cdebug << aNode->Name() << " " << theAutomaton->StateName( aNode->State() )
1657                << endl ;
1658       }
1659     }
1660   }
1661   else {
1662     cdebug << Name() << " not suspended " << theAutomaton->StateName( State() ) << endl ;
1663   }
1664   if ( RetVal ) {
1665     MESSAGE("================================================================================") ;
1666     MESSAGE( Name() << " IS RESUMED" ) ;
1667     MESSAGE("================================================================================") ;
1668   }
1669   else {
1670     MESSAGE("================================================================================") ;
1671     MESSAGE( Name() << " IS NOT RESUMED" ) ;
1672     MESSAGE("================================================================================") ;
1673   }
1674   cdebug_out << "GraphExecutor::OutNode::Resume" << theAutomaton->StateName( State() ) << " " << RetVal << endl ;
1675   return RetVal ;
1676 }
1677
1678 bool GraphExecutor::OutNode::Kill() {
1679   bool RetVal = true ;
1680   cdebug_in << "GraphExecutor::OutNode::Kill" << endl;
1681   _ControlState = SUPERV::ToSuspendState ;
1682   int i ;
1683   for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1684     GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) GraphNodes( i )->GetInNode() ;
1685     bool sts = aNode->Kill() ;
1686     if ( sts && aNode->IsKilled() ) {
1687       cdebug << aNode->Name() << " killed" << endl ;
1688     }
1689     else if ( aNode->IsWaiting() || aNode->IsDone() ) {
1690       cdebug << aNode->Name() << " not killed : "
1691              << theAutomaton->StateName( aNode->State() ) << endl ;
1692     }
1693     else {
1694       cdebug << aNode->Name() << " cannot be killed : "
1695              << theAutomaton->StateName( aNode->State() ) << endl ;
1696       RetVal = false ;
1697     }
1698   }
1699   if ( !RetVal || Threads() != 0 ) {
1700     for ( i = 0 ; i < GraphNodesSize() ; i++ ) {
1701       GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) GraphNodes( i )->GetInNode() ;
1702       if ( !aNode->IsKilled() && !aNode->IsWaiting() && !aNode->IsDone() ) {
1703         cdebug << aNode->Name() << " not killed : "
1704                << theAutomaton->StateName( aNode->State() ) << " " << aNode->Name() << "->"
1705                << "KilledAction()" << endl ;
1706         aNode->KilledAction() ;
1707       }
1708     }
1709     RetVal = true ;
1710   }
1711   State( SUPERV::KilledState ) ;
1712   if ( RetVal ) {
1713     MESSAGE("================================================================================") ;
1714     MESSAGE( Name() << " IS KILLED" ) ;
1715     MESSAGE("================================================================================") ;
1716   }
1717   else {
1718     MESSAGE("================================================================================") ;
1719     MESSAGE( Name() << " IS NOT KILLED" ) ;
1720     MESSAGE("================================================================================") ;
1721   }
1722   cdebug_out << "GraphExecutor::OutNode::Kill" << endl ;
1723   return RetVal ;
1724 }
1725
1726 bool GraphExecutor::OutNode::Stop() {
1727   bool RetVal = false ;
1728   cdebug_in << "GraphExecutor::OutNode::Stop" << endl;
1729   RetVal = Kill() ;
1730   cdebug_out << "GraphExecutor::OutNode::Stop" << endl ;
1731   if ( RetVal ) {
1732     MESSAGE("================================================================================") ;
1733     MESSAGE( Name() << " IS STOPPED" ) ;
1734     MESSAGE("================================================================================") ;
1735   }
1736   return RetVal ;
1737 }
1738 bool GraphExecutor::OutNode::ReRun() {
1739   bool RetVal = false ;
1740   cdebug_in << "GraphExecutor::OutNode::ReRun" << endl;
1741   if ( IsSuspended() ) {
1742   }
1743   cdebug_out << "GraphExecutor::OutNode::ReRun" << endl ;
1744   return RetVal ;
1745 }
1746 bool GraphExecutor::OutNode::ReStart() {
1747   bool RetVal = false ;
1748   cdebug_in << "GraphExecutor::OutNode::ReStart" << endl;
1749   if ( IsSuspended() ) {
1750   }
1751   cdebug_out << "GraphExecutor::OutNode::ReStart" << endl ;
1752   return RetVal ;
1753 }
1754
1755 bool GraphExecutor::OutNode::ReadyWait() {
1756   cdebug_in << "GraphExecutor::OutNode::ReadyWait" << endl;
1757   bool aret ;
1758   if ( pthread_mutex_lock( &_MutexWait ) ) {
1759     perror("pthread_mutex_lock _ReadyWait") ;
1760     exit( 0 ) ;
1761   }
1762   aret = IsReady() ;
1763   if ( !aret ) {
1764     Suspend() ;
1765     pthread_cond_wait( &_EventWait , &_MutexWait );
1766     aret = IsReady() ;
1767   }
1768   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1769     perror("pthread_mutex_lock _ReadyWait") ;
1770     exit( 0 ) ;
1771   }
1772   cdebug_out << "GraphExecutor::OutNode::ReadyWait" << endl ;
1773   return aret ;
1774 }
1775
1776 bool GraphExecutor::OutNode::RunningWait() {
1777   cdebug_in << "GraphExecutor::OutNode::RunningWait" << endl;
1778   bool aret ;
1779   if ( pthread_mutex_lock( &_MutexWait ) ) {
1780     perror("pthread_mutex_lock _RunningWait") ;
1781     exit( 0 ) ;
1782   }
1783   aret = IsRunning() ;
1784   if ( !aret ) {
1785     cdebug << "RunningWait pthread_cond_wait _EventWait" << endl;
1786     pthread_cond_wait( &_EventWait , &_MutexWait );
1787     aret = IsRunning() ;
1788     cdebug << "RunningWait pthread_cond_waited _EventWait " << aret << endl;
1789   }
1790   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1791     perror("pthread_mutex_lock _RunningWait") ;
1792     exit( 0 ) ;
1793   }
1794   cdebug_out << "GraphExecutor::OutNode::RunningWait " << aret << endl ;
1795   return aret ;
1796 }
1797
1798 bool GraphExecutor::OutNode::DoneWait() {
1799   cdebug_in << "GraphExecutor::OutNode::DoneWait" << endl;
1800   bool aret ;
1801   if ( pthread_mutex_lock( &_MutexWait ) ) {
1802     perror("pthread_mutex_lock _DoneWait") ;
1803     exit( 0 ) ;
1804   }
1805   aret = IsDone() ;
1806   while ( !aret && !IsSuspended() && IsRunning() ) {
1807     cdebug << "DoneWait pthread_cond_wait _EventWait" << endl;
1808     pthread_cond_wait( &_EventWait , &_MutexWait );
1809     aret = IsDone() ;
1810     cdebug << "DoneWait pthread_cond_waited _EventWait " << aret << endl;
1811   }
1812   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1813     perror("pthread_mutex_lock _DoneWait") ;
1814     exit( 0 ) ;
1815   }
1816   cdebug_out << "GraphExecutor::OutNode::DoneWait " << aret << endl ;
1817   return aret ;
1818 }
1819
1820 bool GraphExecutor::OutNode::SuspendedWait() {
1821   cdebug_in << "GraphExecutor::OutNode::SuspendedWait" << endl;
1822   bool aret ;
1823   if ( pthread_mutex_lock( &_MutexWait ) ) {
1824     perror("pthread_mutex_lock _SuspendedWait") ;
1825     exit( 0 ) ;
1826   }
1827   aret = IsSuspended() ;
1828   while ( !aret && !IsDone() ) {
1829     pthread_cond_wait( &_EventWait , &_MutexWait );
1830     aret = IsSuspended() ;
1831   }
1832   if ( pthread_mutex_unlock( &_MutexWait ) ) {
1833     perror("pthread_mutex_lock _SuspendedWait") ;
1834     exit( 0 ) ;
1835   }
1836   cdebug_out << "GraphExecutor::OutNode::SuspendedWait" << endl ;
1837   return aret ;
1838 }
1839
1840 bool GraphExecutor::OutNode::ReadyWait( const char * NodeName ) {
1841   bool aret = false ;
1842   cdebug_in << "GraphExecutor::OutNode::ReadyWait " << NodeName << endl;
1843   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1844   if ( anInNode ) {
1845     aret = anInNode->ReadyWait() ;
1846   }
1847   cdebug_out << "GraphExecutor::OutNode::ReadyWait" << endl ;
1848   return aret ;
1849 }
1850
1851 bool GraphExecutor::OutNode::RunningWait( const char * NodeName ) {
1852   bool aret = false ;
1853   cdebug_in << "GraphExecutor::OutNode::RunningWait " << NodeName << endl;
1854   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1855   if ( anInNode ) {
1856     aret = anInNode->RunningWait() ;
1857   }
1858   cdebug_out << "GraphExecutor::OutNode::RunningWait" << endl ;
1859   return aret ;
1860 }
1861
1862 bool GraphExecutor::OutNode::DoneWait( const char * NodeName ) {
1863   bool aret = false ;
1864   cdebug_in << "GraphExecutor::OutNode::DoneWait " << NodeName << endl;
1865   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1866   if ( anInNode ) {
1867     aret = anInNode->DoneWait() ;
1868   }
1869   cdebug_out << "GraphExecutor::OutNode::DoneWait" << endl ;
1870   return aret ;
1871 }
1872
1873 bool GraphExecutor::OutNode::SuspendedWait( const char * NodeName ) {
1874   bool aret = false ;
1875   cdebug_in << "GraphExecutor::OutNode::SuspendedWait " << NodeName << endl;
1876   GraphExecutor::InNode *anInNode = (GraphExecutor::InNode *) GetGraphNode( NodeName )->GetInNode() ;
1877   if ( anInNode ) {
1878     aret = anInNode->SuspendedWait() ;
1879   }
1880   cdebug_out << "GraphExecutor::OutNode::SuspendedWait" << endl ;
1881   return aret ;
1882 }
1883
1884 long GraphExecutor::OutNode::LastLevelDone() {
1885   int RetVal = -1 ;
1886   int i , j ;
1887   for ( i = 0 ; i <= LevelMax() ; i++ ) {
1888     for ( j = 0 ; j <= NodesNumber( i ) ; j++ ) {
1889       GraphBase::ComputingNode * aNode = SortedNodes( i , j ) ;
1890       if ( !IsDone( aNode->Name() ) ) {
1891         break ;
1892       }
1893     }
1894     if ( j != NodesNumber( i ) + 1 )
1895       break ;
1896     RetVal = i ;
1897   }
1898   return RetVal ;
1899 }
1900
1901
1902 const CORBA::Any *GraphExecutor::OutNode::GetInData( const char * NodeName ,
1903                                                      const char * ServiceParameterName ) {
1904 //  cdebug_in << "GraphExecutor::OutNode::GetInData " << NodeName << " "
1905 //            << ServiceParameterName << endl ;
1906   const CORBA::Any * retdata = PortInData( NodeName , ServiceParameterName ) ;
1907 //  cdebug_out << "GraphExecutor::OutNode::GetInData" << endl ;
1908   return retdata ;
1909 }
1910
1911 const CORBA::Any *GraphExecutor::OutNode::GetOutData( const char * NodeName ,
1912                                                       const char * ServiceParameterName ) {
1913 //  cdebug_in << "GraphExecutor::OutNode::GetOutData " << NodeName << " "
1914 //            << ServiceParameterName << endl ;
1915   const CORBA::Any * retdata = PortOutData( NodeName , ServiceParameterName ) ;
1916 //  cdebug_out << "GraphExecutor::OutNode::GetOutData" << endl ;
1917   return retdata ;
1918 }
1919
1920 const long GraphExecutor::OutNode::CpuUsed() {
1921   return GraphBase::Graph::CpuUsed() ;
1922 }
1923
1924 const long GraphExecutor::OutNode::CpuUsed( const char * aNodeName ) {
1925   GraphBase::ComputingNode * aNode = GetChangeGraphNode( aNodeName ) ;
1926   if ( aNode ) {
1927     GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) aNode->GetInNode() ;
1928     if ( anInNode ) {
1929       return anInNode->CpuUsed() ;
1930     }
1931   }
1932   return 0 ;
1933 }
1934
1935