1 // SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : DataFlowBase_InNode.hxx
25 // Author : Jean Rahuel, CEA
29 #ifndef _DATAFLOWEXECUTOR_INNODE_HXX
30 #define _DATAFLOWEXECUTOR_INNODE_HXX
36 #include "SALOME_Container_i.hxx"
38 #include "DataFlowBase_Graph.hxx"
39 #include "DataFlowBase_FactoryNode.hxx"
40 #include "DataFlowBase_GOTONode.hxx"
41 #include "DataFlowBase_LoopNode.hxx"
42 #include "DataFlowBase_EndOfLoopNode.hxx"
43 #include "DataFlowBase_SwitchNode.hxx"
44 #include "DataFlowBase_EndOfSwitchNode.hxx"
46 #include "DataFlowExecutor_FiniteStateMachine.hxx"
48 #define MAXSTACKTHREADSIZE 127
50 void * run_function(void *p);
52 extern GraphExecutor::FiniteStateMachine * theAutomaton ;
54 extern "C" PyObject * PyRunMethod( PyObject * dummy , PyObject * args ) ;
56 namespace GraphExecutor {
58 struct ServicesAnyData {
65 // class InNode : public GraphBase::Node {
66 class InNode : public GraphBase::Base {
70 GraphBase::ComputingNode * _ComputingNode ;
71 GraphBase::FactoryNode * _FactoryNode ;
72 GraphBase::InLineNode * _InLineNode ;
73 GraphBase::GOTONode * _GOTONode ;
74 GraphBase::LoopNode * _LoopNode ;
75 GraphBase::EndOfLoopNode * _EndOfLoopNode ;
76 GraphBase::SwitchNode * _SwitchNode ;
77 GraphBase::EndOfSwitchNode * _EndOfSwitchNode ;
78 GraphBase::Graph * _GraphMacroNode ;
80 PyObject * _MyPyRunMethod ;
82 bool _createNewThread ;
83 //JR 15.04.2005 Debug PAL8624 RetroConception :
84 // bool _createNewThreadIf ;
86 GraphExecutor::AutomatonState _OldState ;
87 GraphExecutor::AutomatonState _currentState ;
88 GraphExecutor::NodeEvent _CurrentEvent ;
89 SUPERV::ControlState _ControlState ;
90 GraphExecutor::AutomatonState _NextState ;
91 GraphExecutor::StateEventAction _NextAction ;
93 pthread_mutex_t _MutexDataReady ;
94 bool _MutexDataReadyLocked ;
95 bool _HasAllDataReady ;
100 //JR 15.04.2005 Debug PAL8624 RetroConception :
101 // pthread_mutex_t _MutexDataWait ;
104 pthread_mutex_t _MutexWait ;
106 pthread_cond_t _ReadyWait ;
107 pthread_cond_t _RunningWait ;
108 pthread_cond_t _DoneWait ;
109 pthread_cond_t _SuspendedWait ;
111 pthread_cond_t _SuspendWait ;
113 pthread_cond_t _ResumeWait ;
115 GraphExecutor::NodeEvent _aResumeEvent ;
116 GraphExecutor::InNode * _aReStartNode ;
117 GraphExecutor::NodeEvent _aReStartEvent ;
119 pthread_cond_t _KillWait ;
121 pthread_cond_t _StopWait ;
123 pthread_cond_t _ThreadStartedWait ;
124 bool _ThreadStartedSync ;
126 pthread_t _Pythread ;
130 GraphExecutor::FiniteStateMachine * _Automaton ;
134 GraphExecutor::OutNode * _OutNode ;
136 char * _DataFromNode ;
142 InNode( CORBA::ORB_ptr ORB, SALOME_NamingService* ptrNamingService,
143 const SALOME_ModuleCatalog::Service& NodeService ,
144 const char *NodeComponentName ,
145 const char* NodeInterfaceName ,
146 const char *NodeName ,
147 const SUPERV::KindOfNode akind = SUPERV::ComputingNode ,
148 GraphBase::ListOfFuncName aFuncName = GraphBase::ListOfFuncName() ,
149 GraphBase::ListOfPythonFunctions aPythonFunction = GraphBase::ListOfPythonFunctions() ,
150 const SUPERV::SDate NodeFirstCreation = SUPERV::SDate() ,
151 const SUPERV::SDate NodeLastModification = SUPERV::SDate() ,
152 const char * NodeEditorRelease = NULLSTRING ,
153 const char * NodeAuthor = NULLSTRING ,
154 const char * NodeComputer = NULLSTRING ,
155 const char * NodeComment = NULLSTRING ,
156 const bool GeneratedName = false ,
157 const int NodeX = 0 ,
158 const int NodeY = 0 ,
159 int * Graph_prof_debug = NULL ,
160 ofstream * Graph_fdebug = NULL ) ;
163 pthread_t ThreadNo() {
164 return _ComputingNode->ThreadNo() ; } ;
165 void ThreadNo( pthread_t aThread ) {
166 _ComputingNode->ThreadNo ( aThread ) ; } ;
168 char * Name() const {
169 return _ComputingNode->Name() ; } ;
170 const char *const * NamePtr() const {
171 return _ComputingNode->NamePtr() ; } ;
172 SUPERV::KindOfNode Kind() const {
173 return _ComputingNode->Kind() ; } ;
174 const bool IsComputingNode() const {
175 return _ComputingNode->IsComputingNode() ; } ;
176 const bool IsFactoryNode() const {
177 return _ComputingNode->IsFactoryNode() ; } ;
178 const bool IsInLineNode() const {
179 return _ComputingNode->IsInLineNode() ; } ;
180 const bool IsOneOfInLineNodes() const {
181 return _ComputingNode->IsOneOfInLineNodes() ; } ;
182 const bool IsOneOfGOTONodes() const {
183 return _ComputingNode->IsOneOfGOTONodes() ; } ;
184 const bool IsMacroNode() const {
185 return _ComputingNode->IsMacroNode() ; } ;
186 const bool IsDataFlowNode() const {
187 return _ComputingNode->IsDataFlowNode() ; } ;
188 const bool IsDataStreamNode() const {
189 return _ComputingNode->IsDataStreamNode() ; } ;
190 const bool IsLoopNode() const {
191 return _ComputingNode->IsLoopNode() ; } ;
192 const bool IsEndLoopNode() const {
193 return _ComputingNode->IsEndLoopNode() ; } ;
194 const bool IsSwitchNode() const {
195 return _ComputingNode->IsSwitchNode() ; } ;
196 const bool IsEndSwitchNode() const {
197 return _ComputingNode->IsEndSwitchNode() ; } ;
198 const bool IsGOTONode() const {
199 return _ComputingNode->IsGOTONode() ; } ;
200 const bool IsHeadNode() const {
201 return _ComputingNode->IsHeadNode() ; } ;
202 GraphBase::ComputingNode * ComputingNode() {
203 return _ComputingNode ; } ;
204 GraphBase::FactoryNode * FactoryNode() {
205 return _FactoryNode ; } ;
206 GraphBase::GOTONode * GOTONode() {
211 if ( _EndOfLoopNode )
212 return _EndOfLoopNode ;
215 if ( _EndOfSwitchNode )
216 return _EndOfSwitchNode ;
219 GraphBase::InLineNode * InLineNode() {
220 GraphBase::InLineNode * aNode = GOTONode() ;
225 GraphBase::LoopNode * LoopNode() {
226 return _LoopNode ; } ;
227 GraphBase::Graph * GraphMacroNode() {
228 return _GraphMacroNode ; } ;
230 SUPERV::CNode_var ObjRef() const { return _ComputingNode->ObjRef() ; } ;
231 void SetObjRef( SUPERV::CNode_var aNode ) {
232 _ComputingNode->SetObjRef( aNode ) ; } ;
234 CNode_Impl * ObjImpl() const { return _ComputingNode->ObjImpl() ; } ;
235 void SetObjImpl( CNode_Impl * aGraph ) {
236 _ComputingNode->SetObjImpl( aGraph ) ; } ;
238 Engines::Component_var Component() const ;
239 Engines::Container_var Container() const ;
240 void SetContainer(Engines::Container_var aContainer) {
241 _FactoryNode->SetContainer( aContainer ) ; } ;
242 void SetComponent(Engines::Component_var anObjComponent) {
243 _FactoryNode->SetComponent( anObjComponent ) ; } ;
244 void ObjInterface( bool k_interface ) {
245 _ComputingNode->ObjInterface( k_interface ) ; } ;
246 bool ObjInterface() {
247 return _FactoryNode->ObjInterface() ; } ;
248 char * ComponentName() const { return _FactoryNode->ComponentName() ; } ;
249 char * InterfaceName() const { return _FactoryNode->InterfaceName() ; } ;
250 char * Computer() const { return _FactoryNode->Computer() ; } ;
251 const char * ServiceName() const {
252 return _ComputingNode->ServiceName() ; } ;
253 const SALOME_ModuleCatalog::ListOfServicesParameter ServiceInParameter() const {
254 return _ComputingNode->ServiceInParameter() ; } ;
255 const SALOME_ModuleCatalog::ListOfServicesParameter ServiceOutParameter() const {
256 return _ComputingNode->ServiceOutParameter() ; } ;
258 void CoupledNode( GraphBase::InLineNode * aCoupledNode ) {
259 GOTONode()->CoupledNode( aCoupledNode ) ; } ;
260 GraphBase::InLineNode * CoupledNode() {
261 return GOTONode()->CoupledNode() ; } ;
263 GraphBase::InPort * AddInPort( const char * InputParameterName ,
264 const char * InputParameterType ,
265 const SUPERV::KindOfPort aKindOfPort ) {
266 return _ComputingNode->AddInPort( InputParameterName ,
269 GraphBase::OutPort * AddOutPort( const char * OutputParameterName ,
270 const char * OutputParameterType ,
271 const SUPERV::KindOfPort aKindOfPort ) {
272 return _ComputingNode->AddOutPort( OutputParameterName ,
273 OutputParameterType ,
275 // void InOutPort( GraphBase::InPort * InputPort ,
276 // GraphBase::OutPort * OutputPort ) {
277 // return _ComputingNode->InOutPort( InputPort , OutputPort ) ; } ;
278 int LinkedNodesSize() const {
279 return _ComputingNode->LinkedNodesSize() ; } ;
280 // GraphBase::ComputingNode * LinkedNodes( int i ) const {
281 GraphBase::StreamNode * LinkedNodes( int i ) const {
282 return _ComputingNode->LinkedNodes( i ) ; } ;
283 const int LinkedInPortsNumber( int i ) const {
284 return _ComputingNode->LinkedInPortsNumber( i ) ; } ;
286 const int GetNodeInPortsSize() const {
287 return _ComputingNode->GetNodeInPortsSize() ; } ;
288 const GraphBase::InPort *GetNodeInLoop() const {
289 return _ComputingNode->GetNodeInLoop() ; } ;
290 const GraphBase::InPort *GetNodeInGate() const {
291 return _ComputingNode->GetNodeInGate() ; } ;
292 const GraphBase::InPort *GetNodeInPort(int i) const {
293 return _ComputingNode->GetNodeInPort( i ) ; } ;
294 GraphBase::InPort *GetChangeNodeInLoop() const {
295 return _ComputingNode->GetChangeNodeInLoop() ; } ;
296 GraphBase::InPort *GetChangeNodeInGate() const {
297 return _ComputingNode->GetChangeNodeInGate() ; } ;
298 GraphBase::InPort *GetChangeNodeInPort(int i) const {
299 return _ComputingNode->GetChangeNodeInPort( i ) ; } ;
300 const int GetNodeOutPortsSize() const {
301 return _ComputingNode->GetNodeOutPortsSize() ; } ;
302 const GraphBase::OutPort *GetNodeOutLoop() const {
303 return _ComputingNode->GetNodeOutLoop() ; } ;
304 const GraphBase::OutPort *GetNodeOutGate() const {
305 return _ComputingNode->GetNodeOutGate() ; } ;
306 const GraphBase::OutPort *GetNodeOutPort(int i) const {
307 return _ComputingNode->GetNodeOutPort( i ) ; } ;
308 GraphBase::OutPort *GetChangeNodeOutLoop() const {
309 return _ComputingNode->GetChangeNodeOutLoop() ; } ;
310 GraphBase::OutPort *GetChangeNodeOutGate() const {
311 return _ComputingNode->GetChangeNodeOutGate() ; } ;
312 GraphBase::OutPort *GetChangeNodeOutPort(int i) const {
313 return _ComputingNode->GetChangeNodeOutPort( i ) ; } ;
315 const GraphBase::InPort *GetInPort( const char *name ) {
316 return _ComputingNode->GetInPort( name ) ; } ;
317 const GraphBase::OutPort *GetOutPort( const char *name ) {
318 return _ComputingNode->GetOutPort( name ) ; } ;
319 GraphBase::InPort *GetChangeInPort( const char *name ) {
320 return _ComputingNode->GetChangeInPort( name ) ; } ;
321 GraphBase::OutPort *GetChangeOutPort( const char *name ) {
322 return _ComputingNode->GetChangeOutPort( name ) ; } ;
324 void PyFuncRunned( bool arunned ) {
325 _PyFuncRunned = arunned ; } ;
326 bool PyFuncRunned() {
327 return _PyFuncRunned ; } ;
329 void OutNode( GraphExecutor::OutNode * theOutNode ) {
330 _OutNode = theOutNode ; } ;
333 PyObject * InitPyDynInvoke( char * PyFuncName ,
334 const SUPERV::ListOfStrings * aPythonFunction ,
336 void RemovePyDynInvoke( char * PyFuncName ) ;
338 //JR 15.04.2005 Debug PAL8624 RetroConception :
339 // void LockDataWait() ;
340 // void UnLockDataWait() ;
341 // bool IsLockedDataWait() { return _DataWait ; } ;
342 void LockDataReady() ;
343 void UnLockDataReady() ;
344 void HasAllDataReady( bool hasAllDataReady ) {
345 // cdebug << "Executor::InNode::HasAllDataReady( " << hasAllDataReady
346 // << " ) " << Name() << " previous _HasAllDataReady " << _HasAllDataReady
348 _HasAllDataReady = hasAllDataReady ; } ;
349 bool HasAllDataReady() const {
350 return _HasAllDataReady ; }
353 bool ContainerKill() ;
362 void CreateNewThread( bool k_create ) {
363 // cdebug << Name() << " CreateNewThread " << k_create << endl ;
364 _createNewThread = k_create ; } ;
365 //JR 15.04.2005 Debug PAL8624 RetroConception :
366 // void CreateNewThreadIf( bool k_create ) {
367 // cdebug << Name() << " CreateNewThreadIf( " << k_create << " )" << endl ;
368 // _createNewThreadIf = k_create ; } ;
369 bool CreateNewThread() { return _createNewThread ; } ;
370 // bool CreateNewThreadIf() { return _createNewThreadIf ; } ;
371 void NewThread( pthread_t aThread ) ;
373 void RewindStack( int aRewindStack ) { _RewindStack = aRewindStack ; } ;
374 int RewindStack() const { return _RewindStack ; } ;
376 GraphExecutor::AutomatonState State() const {
377 return _currentState; };
378 void State(GraphExecutor::AutomatonState aState ) {
379 // cdebug << "GraphExecutor::InNode::State( "
380 // << Automaton()->StateName( _currentState ) << " --> "
381 // << Automaton()->StateName( aState ) << " )" << endl ;
382 _currentState = aState ; } ;
383 SUPERV::ControlState ControlState() const {
384 return _ControlState; };
385 void ControlState(SUPERV::ControlState aControlState ) {
386 _ControlState = aControlState ; } ;
387 void ControlClear() {
388 _ControlState = SUPERV::VoidState ; } ;
390 void SetAutomaton() {
391 _Automaton = theAutomaton ; } ;
392 GraphExecutor::FiniteStateMachine * Automaton() const {
393 return _Automaton ; } ;
402 void IsLoading( bool Loading );
403 bool IsLoading() { return _Loading ; } ;
405 bool StateWait( SUPERV::GraphState aState ) ;
409 bool SuspendedWait() ;
411 void InitialState() ;
412 bool InitPythonFunctions(bool WithErr ) ;
413 void SetWaitingStates(GraphExecutor::InNode * EndNode ) ;
415 int SendEvent(const GraphExecutor::NodeEvent anEvent ) ;
416 void DataFromNode( char * FromNodeName ) {
417 _DataFromNode = FromNodeName ; } ;
418 const char * DataFromNode() const { return _DataFromNode ; } ;
423 void RunningAction() ;
425 void SuspendedAction() ;
426 GraphExecutor::InNode * SuspendAction() ;
427 bool ResumeAction(GraphExecutor::NodeEvent aResumeEvent ) ;
428 bool ReStartAction( GraphExecutor::InNode * aRestartNode ,
429 GraphExecutor::NodeEvent anEvent ) ;
431 void KilledAction() ;
432 void ThreadStartAction() ;
433 void ThreadStartedAction() ;
435 void StoppedAction() ;
436 int executeAction() ; // New Thread or Same Thread
437 int ExecuteAction() ;
439 int DataWaiting_SomeDataReadyAction() ;
440 int DataUndef_NotAllDataReadyAction() ;
441 int DataUndef_AllDataReadyAction() ;
442 int DataReady_SuspendAction() ;
443 int SuspendedReady_ResumeAction() ;
444 int DataReady_KillAction() ;
445 int DataReady_StopAction() ;
446 int DataReady_ExecuteAction() ;
447 void DynInvoke( Engines::Component_ptr obj,
449 ServicesAnyData * inParams, int nInParams,
450 ServicesAnyData * outParams, int nOutParams) ;
451 void DynInvoke( Engines::Component_ptr obj,
453 const char * aGraphName ,
454 const char * aNodeName );
455 bool PyDynInvoke( PyObject * MyPyRunMethod ,
457 ServicesAnyData * inParams , int nInParams ,
458 ServicesAnyData * inParams , int nOutParams ) ;
460 int Executing_SuspendAction() ;
461 int SuspendedExecuting_ResumeAction() ;
462 int Executing_KillAction() ;
463 int Executing_StopAction() ;
464 int Executing_SuccessAction() ;
465 int Executing_ErrorAction() ;
466 int Successed_SuccessAction() ;
467 bool SendSomeDataReady( char * FromNodeName ) ;
468 int Errored_ErrorAction() ;
469 int Successed_SuspendAction() ;
470 int Errored_SuspendAction() ;
471 int SuspendedSuccessed_ResumeAction() ;
472 int SuspendedErrored_ResumeAction() ;
473 int Successed_KillAction() ;
474 int Errored_KillAction() ;
475 int Successed_StopAction() ;
476 int Errored_StopAction() ;
477 int SuspendedSuccessed_ReStartAction() ;
478 int SuspendedErrored_ReStartAction() ;
479 int SuspendedSuccessed_ReStartAndSuspendAction() ;
480 int SuspendedErrored_ReStartAndSuspendAction() ;
482 void InParametersSet( bool & Err ,
484 ServicesAnyData * InParametersList ) ;
485 void InOutParametersSet( int nOutParams ,
486 ServicesAnyData * OutParametersList ) ;
487 bool OutParametersSet( bool Err , SUPERV::GraphState PortState ,
489 ServicesAnyData * OutParametersList ) ;
493 const long CpuUsed( bool tot = false ) ;
495 long PyCpuUsed( bool tot = false ) ;
496 void SetPyCpuUsed() ;
499 bool PyRunSimpleString( char* thePyString );
500 PyObject * PyEvalCallObject( const char *method ,
501 PyObject * MyPyRunMethod ,
502 PyObject * ArgsList ) ;