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