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