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 bool _createNewThreadIf ;
85 GraphExecutor::AutomatonState _OldState ;
86 GraphExecutor::AutomatonState _currentState ;
87 GraphExecutor::NodeEvent _CurrentEvent ;
88 SUPERV::ControlState _ControlState ;
89 GraphExecutor::AutomatonState _NextState ;
90 GraphExecutor::StateEventAction _NextAction ;
94 pthread_mutex_t _MutexDataWait ;
97 pthread_mutex_t _MutexWait ;
99 pthread_cond_t _ReadyWait ;
100 pthread_cond_t _RunningWait ;
101 pthread_cond_t _DoneWait ;
102 pthread_cond_t _SuspendedWait ;
104 pthread_cond_t _SuspendWait ;
106 pthread_cond_t _ResumeWait ;
108 GraphExecutor::NodeEvent _aResumeEvent ;
109 GraphExecutor::InNode * _aReStartNode ;
110 GraphExecutor::NodeEvent _aReStartEvent ;
112 pthread_cond_t _KillWait ;
114 pthread_cond_t _StopWait ;
116 pthread_cond_t _ThreadStartedWait ;
117 bool _ThreadStartedSync ;
119 pthread_t _Pythread ;
123 GraphExecutor::FiniteStateMachine * _Automaton ;
127 GraphExecutor::OutNode * _OutNode ;
129 char * _DataFromNode ;
134 InNode( CORBA::ORB_ptr ORB, SALOME_NamingService* ptrNamingService,
135 const SALOME_ModuleCatalog::Service& NodeService ,
136 const char *NodeComponentName ,
137 const char* NodeInterfaceName ,
138 const char *NodeName ,
139 const SUPERV::KindOfNode akind = SUPERV::ComputingNode ,
140 GraphBase::ListOfFuncName aFuncName = GraphBase::ListOfFuncName() ,
141 GraphBase::ListOfPythonFunctions aPythonFunction = GraphBase::ListOfPythonFunctions() ,
142 const SUPERV::SDate NodeFirstCreation = SUPERV::SDate() ,
143 const SUPERV::SDate NodeLastModification = SUPERV::SDate() ,
144 const char * NodeEditorRelease = NULLSTRING ,
145 const char * NodeAuthor = NULLSTRING ,
146 const char * NodeComputer = NULLSTRING ,
147 const char * NodeComment = NULLSTRING ,
148 const bool GeneratedName = false ,
149 const int NodeX = 0 ,
150 const int NodeY = 0 ,
151 int * Graph_prof_debug = NULL ,
152 ofstream * Graph_fdebug = NULL ) ;
155 pthread_t ThreadNo() {
156 return _ComputingNode->ThreadNo() ; } ;
157 void ThreadNo( pthread_t aThread ) {
158 _ComputingNode->ThreadNo ( aThread ) ; } ;
160 char * Name() const {
161 return _ComputingNode->Name() ; } ;
162 const char *const * NamePtr() const {
163 return _ComputingNode->NamePtr() ; } ;
164 SUPERV::KindOfNode Kind() const {
165 return _ComputingNode->Kind() ; } ;
166 const bool IsComputingNode() const {
167 return _ComputingNode->IsComputingNode() ; } ;
168 const bool IsFactoryNode() const {
169 return _ComputingNode->IsFactoryNode() ; } ;
170 const bool IsInLineNode() const {
171 return _ComputingNode->IsInLineNode() ; } ;
172 const bool IsOneOfInLineNodes() const {
173 return _ComputingNode->IsOneOfInLineNodes() ; } ;
174 const bool IsOneOfGOTONodes() const {
175 return _ComputingNode->IsOneOfGOTONodes() ; } ;
176 const bool IsMacroNode() const {
177 return _ComputingNode->IsMacroNode() ; } ;
178 const bool IsDataFlowNode() const {
179 return _ComputingNode->IsDataFlowNode() ; } ;
180 const bool IsDataStreamNode() const {
181 return _ComputingNode->IsDataStreamNode() ; } ;
182 const bool IsLoopNode() const {
183 return _ComputingNode->IsLoopNode() ; } ;
184 const bool IsEndLoopNode() const {
185 return _ComputingNode->IsEndLoopNode() ; } ;
186 const bool IsSwitchNode() const {
187 return _ComputingNode->IsSwitchNode() ; } ;
188 const bool IsEndSwitchNode() const {
189 return _ComputingNode->IsEndSwitchNode() ; } ;
190 const bool IsGOTONode() const {
191 return _ComputingNode->IsGOTONode() ; } ;
192 const bool IsHeadNode() const {
193 return _ComputingNode->IsHeadNode() ; } ;
194 GraphBase::ComputingNode * ComputingNode() {
195 return _ComputingNode ; } ;
196 GraphBase::FactoryNode * FactoryNode() {
197 return _FactoryNode ; } ;
198 GraphBase::GOTONode * GOTONode() {
203 if ( _EndOfLoopNode )
204 return _EndOfLoopNode ;
207 if ( _EndOfSwitchNode )
208 return _EndOfSwitchNode ;
211 GraphBase::InLineNode * InLineNode() {
212 GraphBase::InLineNode * aNode = GOTONode() ;
217 GraphBase::LoopNode * LoopNode() {
218 return _LoopNode ; } ;
219 GraphBase::Graph * GraphMacroNode() {
220 return _GraphMacroNode ; } ;
222 SUPERV::CNode_var ObjRef() const { return _ComputingNode->ObjRef() ; } ;
223 void SetObjRef( SUPERV::CNode_var aNode ) {
224 _ComputingNode->SetObjRef( aNode ) ; } ;
226 CNode_Impl * ObjImpl() const { return _ComputingNode->ObjImpl() ; } ;
227 void SetObjImpl( CNode_Impl * aGraph ) {
228 _ComputingNode->SetObjImpl( aGraph ) ; } ;
230 Engines::Component_var Component() const ;
231 Engines::Container_var Container() const ;
232 void SetContainer(Engines::Container_var aContainer) {
233 _FactoryNode->SetContainer( aContainer ) ; } ;
234 void SetComponent(Engines::Component_var anObjComponent) {
235 _FactoryNode->SetComponent( anObjComponent ) ; } ;
236 void ObjInterface( bool k_interface ) {
237 _ComputingNode->ObjInterface( k_interface ) ; } ;
238 bool ObjInterface() {
239 return _FactoryNode->ObjInterface() ; } ;
240 char * ComponentName() const { return _FactoryNode->ComponentName() ; } ;
241 char * InterfaceName() const { return _FactoryNode->InterfaceName() ; } ;
242 char * Computer() const { return _FactoryNode->Computer() ; } ;
243 const char * ServiceName() const {
244 return _ComputingNode->ServiceName() ; } ;
245 const SALOME_ModuleCatalog::ListOfServicesParameter ServiceInParameter() const {
246 return _ComputingNode->ServiceInParameter() ; } ;
247 const SALOME_ModuleCatalog::ListOfServicesParameter ServiceOutParameter() const {
248 return _ComputingNode->ServiceOutParameter() ; } ;
250 void CoupledNode( GraphBase::InLineNode * aCoupledNode ) {
251 GOTONode()->CoupledNode( aCoupledNode ) ; } ;
252 GraphBase::InLineNode * CoupledNode() {
253 return GOTONode()->CoupledNode() ; } ;
255 GraphBase::InPort * AddInPort( const char * InputParameterName ,
256 const char * InputParameterType ,
257 const SUPERV::KindOfPort aKindOfPort ) {
258 return _ComputingNode->AddInPort( InputParameterName ,
261 GraphBase::OutPort * AddOutPort( const char * OutputParameterName ,
262 const char * OutputParameterType ,
263 const SUPERV::KindOfPort aKindOfPort ) {
264 return _ComputingNode->AddOutPort( OutputParameterName ,
265 OutputParameterType ,
267 // void InOutPort( GraphBase::InPort * InputPort ,
268 // GraphBase::OutPort * OutputPort ) {
269 // return _ComputingNode->InOutPort( InputPort , OutputPort ) ; } ;
270 int LinkedNodesSize() const {
271 return _ComputingNode->LinkedNodesSize() ; } ;
272 // GraphBase::ComputingNode * LinkedNodes( int i ) const {
273 GraphBase::StreamNode * LinkedNodes( int i ) const {
274 return _ComputingNode->LinkedNodes( i ) ; } ;
275 const int LinkedInPortsNumber( int i ) const {
276 return _ComputingNode->LinkedInPortsNumber( i ) ; } ;
278 const int GetNodeInPortsSize() const {
279 return _ComputingNode->GetNodeInPortsSize() ; } ;
280 const GraphBase::InPort *GetNodeInLoop() const {
281 return _ComputingNode->GetNodeInLoop() ; } ;
282 const GraphBase::InPort *GetNodeInGate() const {
283 return _ComputingNode->GetNodeInGate() ; } ;
284 const GraphBase::InPort *GetNodeInPort(int i) const {
285 return _ComputingNode->GetNodeInPort( i ) ; } ;
286 GraphBase::InPort *GetChangeNodeInLoop() const {
287 return _ComputingNode->GetChangeNodeInLoop() ; } ;
288 GraphBase::InPort *GetChangeNodeInGate() const {
289 return _ComputingNode->GetChangeNodeInGate() ; } ;
290 GraphBase::InPort *GetChangeNodeInPort(int i) const {
291 return _ComputingNode->GetChangeNodeInPort( i ) ; } ;
292 const int GetNodeOutPortsSize() const {
293 return _ComputingNode->GetNodeOutPortsSize() ; } ;
294 const GraphBase::OutPort *GetNodeOutLoop() const {
295 return _ComputingNode->GetNodeOutLoop() ; } ;
296 const GraphBase::OutPort *GetNodeOutGate() const {
297 return _ComputingNode->GetNodeOutGate() ; } ;
298 const GraphBase::OutPort *GetNodeOutPort(int i) const {
299 return _ComputingNode->GetNodeOutPort( i ) ; } ;
300 GraphBase::OutPort *GetChangeNodeOutLoop() const {
301 return _ComputingNode->GetChangeNodeOutLoop() ; } ;
302 GraphBase::OutPort *GetChangeNodeOutGate() const {
303 return _ComputingNode->GetChangeNodeOutGate() ; } ;
304 GraphBase::OutPort *GetChangeNodeOutPort(int i) const {
305 return _ComputingNode->GetChangeNodeOutPort( i ) ; } ;
307 const GraphBase::InPort *GetInPort( const char *name ) {
308 return _ComputingNode->GetInPort( name ) ; } ;
309 const GraphBase::OutPort *GetOutPort( const char *name ) {
310 return _ComputingNode->GetOutPort( name ) ; } ;
311 GraphBase::InPort *GetChangeInPort( const char *name ) {
312 return _ComputingNode->GetChangeInPort( name ) ; } ;
313 GraphBase::OutPort *GetChangeOutPort( const char *name ) {
314 return _ComputingNode->GetChangeOutPort( name ) ; } ;
316 void PyFuncRunned( bool arunned ) {
317 _PyFuncRunned = arunned ; } ;
318 bool PyFuncRunned() {
319 return _PyFuncRunned ; } ;
321 void OutNode( GraphExecutor::OutNode * theOutNode ) {
322 _OutNode = theOutNode ; } ;
325 PyObject * InitPyDynInvoke( char * PyFuncName ,
326 const SUPERV::ListOfStrings * aPythonFunction ,
329 void LockDataWait() ;
330 void UnLockDataWait() ;
331 bool IsLockedDataWait() { return _DataWait ; } ;
334 bool ContainerKill() ;
341 bool ReStart( const char * AtNodeName , const bool AndSuspend ) ;
344 void CreateNewThread( bool k_create ) { _createNewThread = k_create ; } ;
345 void CreateNewThreadIf( bool k_create ) { _createNewThreadIf = k_create ; } ;
346 bool CreateNewThread() { return _createNewThread ; } ;
347 bool CreateNewThreadIf() { return _createNewThreadIf ; } ;
348 void NewThread( pthread_t aThread ) ;
350 void RewindStack( int aRewindStack ) { _RewindStack = aRewindStack ; } ;
351 int RewindStack() const { return _RewindStack ; } ;
353 GraphExecutor::AutomatonState State() const {
354 return _currentState; };
355 void State(GraphExecutor::AutomatonState aState ) {
356 // cdebug << "GraphExecutor::InNode::State( "
357 // << Automaton()->StateName( _currentState ) << " --> "
358 // << Automaton()->StateName( aState ) << " )" << endl ;
359 _currentState = aState ; } ;
360 SUPERV::ControlState ControlState() const {
361 return _ControlState; };
362 void ControlState(SUPERV::ControlState aControlState ) {
363 _ControlState = aControlState ; } ;
364 void ControlClear() {
365 _ControlState = SUPERV::VoidState ; } ;
367 void SetAutomaton() {
368 _Automaton = theAutomaton ; } ;
369 GraphExecutor::FiniteStateMachine * Automaton() const {
370 return _Automaton ; } ;
379 void IsLoading( bool Loading );
380 bool IsLoading() { return _Loading ; } ;
382 bool StateWait( SUPERV::GraphState aState ) ;
386 bool SuspendedWait() ;
388 void InitialState() ;
389 bool InitPythonFunctions(bool WithErr ) ;
390 void SetWaitingStates(GraphExecutor::InNode * EndNode ) ;
392 int SendEvent(const GraphExecutor::NodeEvent anEvent ) ;
393 void DataFromNode( char * FromNodeName ) {
394 _DataFromNode = FromNodeName ; } ;
395 const char * DataFromNode() const { return _DataFromNode ; } ;
400 void RunningAction() ;
402 void SuspendedAction() ;
403 GraphExecutor::InNode * SuspendAction() ;
404 bool ResumeAction(GraphExecutor::NodeEvent aResumeEvent ) ;
405 bool ReStartAction( GraphExecutor::InNode * aRestartNode ,
406 GraphExecutor::NodeEvent anEvent ) ;
408 void KilledAction() ;
409 void ThreadStartAction() ;
410 void ThreadStartedAction() ;
412 void StoppedAction() ;
413 int executeAction() ; // New Thread or Same Thread
414 int ExecuteAction() ;
416 int DataWaiting_SomeDataReadyAction() ;
417 int DataUndef_NotAllDataReadyAction() ;
418 int DataUndef_AllDataReadyAction() ;
419 int DataReady_SuspendAction() ;
420 int SuspendedReady_ResumeAction() ;
421 int DataReady_KillAction() ;
422 int DataReady_StopAction() ;
423 int DataReady_ExecuteAction() ;
424 void DynInvoke( Engines::Component_ptr obj,
426 ServicesAnyData * inParams, int nInParams,
427 ServicesAnyData * outParams, int nOutParams) ;
428 void DynInvoke( Engines::Component_ptr obj,
430 const char * aGraphName ,
431 const char * aNodeName );
432 bool PyDynInvoke( PyObject * MyPyRunMethod ,
434 ServicesAnyData * inParams , int nInParams ,
435 ServicesAnyData * inParams , int nOutParams ) ;
437 int Executing_SuspendAction() ;
438 int SuspendedExecuting_ResumeAction() ;
439 int Executing_KillAction() ;
440 int Executing_StopAction() ;
441 int Executing_SuccessAction() ;
442 int Executing_ErrorAction() ;
443 int Successed_SuccessAction() ;
444 bool SendSomeDataReady( char * FromNodeName ) ;
445 int Errored_ErrorAction() ;
446 int Successed_SuspendAction() ;
447 int Errored_SuspendAction() ;
448 int SuspendedSuccessed_ResumeAction() ;
449 int SuspendedErrored_ResumeAction() ;
450 int Successed_KillAction() ;
451 int Errored_KillAction() ;
452 int Successed_StopAction() ;
453 int Errored_StopAction() ;
454 int SuspendedSuccessed_ReStartAction() ;
455 int SuspendedErrored_ReStartAction() ;
456 int SuspendedSuccessed_ReStartAndSuspendAction() ;
457 int SuspendedErrored_ReStartAndSuspendAction() ;
459 void InParametersSet( bool & Err ,
461 ServicesAnyData * InParametersList ) ;
462 void InOutParametersSet( int nOutParams ,
463 ServicesAnyData * OutParametersList ) ;
464 bool OutParametersSet( bool Err , SUPERV::GraphState NewState ,
466 ServicesAnyData * OutParametersList ) ;
470 const long CpuUsed( bool tot = false ) ;
472 long PyCpuUsed( bool tot = false ) ;
473 void SetPyCpuUsed() ;
476 bool PyRunSimpleString( char* thePyString );
477 PyObject * PyEvalCallObject( PyObject * MyPyRunMethod ,
478 PyObject * ArgsList ) ;