Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNode.hxx
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : DataFlowBase_InNode.hxx
25 //  Author : Jean Rahuel, CEA
26 //  Module : SUPERV
27 //  $Header:
28
29 #ifndef _DATAFLOWEXECUTOR_INNODE_HXX
30 #define _DATAFLOWEXECUTOR_INNODE_HXX
31
32 #include <stdio.h>
33
34 #include <Python.h>
35
36 #include "SALOME_Container_i.hxx"
37
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"
45
46 #include "DataFlowExecutor_FiniteStateMachine.hxx"
47
48 #define MAXSTACKTHREADSIZE 127
49
50 void * run_function(void *p);
51
52 extern GraphExecutor::FiniteStateMachine * theAutomaton ;
53
54 extern "C" PyObject * PyRunMethod( PyObject * dummy , PyObject * args ) ;
55
56 namespace GraphExecutor {
57
58   struct ServicesAnyData {
59     string     Name;
60     CORBA::Any Value;
61   };
62
63   class OutNode ;
64
65 //  class InNode : public GraphBase::Node {
66   class InNode : public GraphBase::Base {
67
68     private:
69
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 ;
79
80       PyObject                       * _MyPyRunMethod ;
81
82       bool                             _createNewThread ;
83 //JR 15.04.2005 Debug PAL8624 RetroConception :
84 //      bool                             _createNewThreadIf ;
85       int                              _RewindStack ;
86       GraphExecutor::AutomatonState    _OldState ;
87       GraphExecutor::AutomatonState    _currentState ;
88       GraphExecutor::NodeEvent         _CurrentEvent ;
89       SUPERV::ControlState             _ControlState ;
90       GraphExecutor::AutomatonState    _NextState ;
91       GraphExecutor::StateEventAction  _NextAction ;
92
93       pthread_mutex_t                  _MutexDataReady ;
94       bool                             _MutexDataReadyLocked ;
95       bool                             _HasAllDataReady ;
96
97       bool                             _PyFuncRunned ;
98       bool                             _Loading ;
99     
100 //JR 15.04.2005 Debug PAL8624 RetroConception :
101 //      pthread_mutex_t                  _MutexDataWait ;
102 //      bool                             _DataWait ;
103
104       pthread_mutex_t                  _MutexWait ;
105
106       pthread_cond_t                   _ReadyWait ;
107       pthread_cond_t                   _RunningWait ;
108       pthread_cond_t                   _DoneWait ;
109       pthread_cond_t                   _SuspendedWait ;
110
111       pthread_cond_t                   _SuspendWait ;
112       bool                             _SuspendSync ;
113       pthread_cond_t                   _ResumeWait ;
114       bool                             _ResumeSync ;
115       GraphExecutor::NodeEvent         _aResumeEvent ;
116       GraphExecutor::InNode *          _aReStartNode ;
117       GraphExecutor::NodeEvent         _aReStartEvent ;
118
119       pthread_cond_t                   _KillWait ;
120       bool                             _KillSync ;
121       pthread_cond_t                   _StopWait ;
122
123       pthread_cond_t                   _ThreadStartedWait ;
124       bool                             _ThreadStartedSync ;
125
126       pthread_t                        _Pythread ;
127       long                             _PyCpuUsed ;
128       long                             _PyTotCpuUsed ;
129
130       GraphExecutor::FiniteStateMachine * _Automaton ;
131     
132       CORBA::ORB_ptr                    _Orb;
133
134       GraphExecutor::OutNode          * _OutNode ;
135
136       char                            * _DataFromNode ;
137       bool                              _InitLoop ;
138
139     public:
140
141       InNode() ;
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 ) ;
161       virtual ~InNode() ;
162
163       pthread_t ThreadNo() {
164                 return _ComputingNode->ThreadNo() ; } ;
165       void ThreadNo( pthread_t aThread ) {
166            _ComputingNode->ThreadNo ( aThread ) ; } ;
167
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() {
207                             if ( _GOTONode )
208                               return _GOTONode ;
209                             if ( _LoopNode )
210                               return _LoopNode ;
211                             if ( _EndOfLoopNode )
212                               return _EndOfLoopNode ;
213                             if ( _SwitchNode )
214                               return _SwitchNode ;
215                             if ( _EndOfSwitchNode )
216                               return _EndOfSwitchNode ;
217                             return NULL ;
218                             } ;
219       GraphBase::InLineNode * InLineNode() {
220                               GraphBase::InLineNode * aNode = GOTONode() ;
221                               if ( aNode == NULL )
222                                 return _InLineNode ;
223                               return aNode ;
224                               } ;
225       GraphBase::LoopNode * LoopNode() {
226                             return _LoopNode ; } ;
227       GraphBase::Graph * GraphMacroNode() {
228                          return _GraphMacroNode ; } ;
229
230       SUPERV::CNode_var ObjRef() const { return _ComputingNode->ObjRef() ; } ;
231       void SetObjRef( SUPERV::CNode_var aNode ) {
232                      _ComputingNode->SetObjRef( aNode ) ; } ;
233
234       CNode_Impl * ObjImpl() const { return _ComputingNode->ObjImpl() ; } ;
235       void SetObjImpl( CNode_Impl * aGraph ) {
236                        _ComputingNode->SetObjImpl( aGraph ) ; } ;
237
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() ; } ;
257
258       void CoupledNode( GraphBase::InLineNode * aCoupledNode ) {
259            GOTONode()->CoupledNode( aCoupledNode ) ; } ;
260       GraphBase::InLineNode * CoupledNode() {
261                               return GOTONode()->CoupledNode() ; } ;
262
263       GraphBase::InPort * AddInPort( const char * InputParameterName ,
264                                      const char * InputParameterType ,
265                                      const SUPERV::KindOfPort aKindOfPort ) {
266                           return _ComputingNode->AddInPort( InputParameterName ,
267                                                             InputParameterType ,
268                                                             aKindOfPort ) ; } ;
269       GraphBase::OutPort * AddOutPort( const char * OutputParameterName ,
270                                        const char * OutputParameterType ,
271                                        const SUPERV::KindOfPort aKindOfPort ) {
272                            return _ComputingNode->AddOutPort( OutputParameterName ,
273                                                               OutputParameterType ,
274                                                               aKindOfPort ) ; } ;
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 ) ; } ;
285
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 ) ; } ;
314
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 ) ; } ;
323
324       void PyFuncRunned( bool arunned ) {
325            _PyFuncRunned = arunned ; } ;
326       bool PyFuncRunned() {
327            return _PyFuncRunned ; } ;
328
329       void OutNode( GraphExecutor::OutNode * theOutNode ) {
330            _OutNode = theOutNode ; } ;
331
332       bool InitPython() ;
333       PyObject * InitPyDynInvoke( char * PyFuncName ,
334                                   const SUPERV::ListOfStrings * aPythonFunction ,
335                                   bool & Err ) ;
336       void RemovePyDynInvoke( char * PyFuncName ) ;
337
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
347 //                  << endl ;
348            _HasAllDataReady = hasAllDataReady ; } ;
349       bool HasAllDataReady() const {
350            return _HasAllDataReady ; }
351
352       bool Ping() ;
353       bool ContainerKill() ;
354
355       bool Kill() ;
356       bool KillDone() ;
357       bool Suspend() ;
358       bool SuspendDone() ;
359       bool Resume() ;
360       bool Stop() ;
361
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 ) ;
372       void ExitThread() ;
373       void RewindStack( int aRewindStack ) { _RewindStack = aRewindStack ; } ;
374       int RewindStack() const { return _RewindStack ; } ;
375
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 ; } ;
389
390       void SetAutomaton() {
391             _Automaton = theAutomaton ; } ;
392       GraphExecutor::FiniteStateMachine * Automaton() const {
393             return _Automaton ; } ;
394
395       bool IsWaiting() ;
396       bool IsReady() ;
397       bool IsRunning() ;
398       bool IsDone() ;
399       bool IsSuspended() ;
400       bool IsKilled() ;
401       bool IsStopped() ;
402       void IsLoading( bool Loading );
403       bool IsLoading() { return _Loading ; } ;
404
405       bool StateWait( SUPERV::GraphState aState ) ;
406       bool ReadyWait() ;
407       bool RunningWait() ;
408       bool DoneWait() ;
409       bool SuspendedWait() ;
410
411       void InitialState() ;
412       bool InitPythonFunctions(bool WithErr ) ;
413       void SetWaitingStates(GraphExecutor::InNode * EndNode ) ;
414
415       int SendEvent(const GraphExecutor::NodeEvent anEvent ) ;
416       void DataFromNode( char * FromNodeName ) {
417            _DataFromNode = FromNodeName ; } ;
418       const char * DataFromNode() const { return _DataFromNode ; } ;
419
420       int ErrorAction();
421       int VoidAction();
422       void ReadyAction() ;
423       void RunningAction() ;
424       void DoneAction() ;
425       void SuspendedAction() ;
426       GraphExecutor::InNode * SuspendAction() ;
427       bool ResumeAction(GraphExecutor::NodeEvent aResumeEvent ) ;
428       bool ReStartAction( GraphExecutor::InNode * aRestartNode ,
429                           GraphExecutor::NodeEvent anEvent ) ;
430       void KillAction() ;
431       void KilledAction() ;
432       void ThreadStartAction() ;
433       void ThreadStartedAction() ;
434       void StopAction() ;
435       void StoppedAction() ;
436       int executeAction() ; // New Thread or Same Thread
437       int ExecuteAction() ;
438
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       int DataReady_ExecuteActionInLineNodes( ServicesAnyData * InParametersList ,
448                                               ServicesAnyData * OutParametersList ) ;      int DataReady_ExecuteActionLoopNodes( ServicesAnyData * InParametersList ,
449                                             ServicesAnyData * OutParametersList ,
450                                             bool & CopyInOut ) ;
451       void DynInvoke( Engines::Component_ptr obj,
452                       const char *method, 
453                       ServicesAnyData * inParams, int nInParams,
454                       ServicesAnyData * outParams, int nOutParams) ;
455       void DynInvoke( Engines::Component_ptr obj,
456                       const char *method, 
457                       const char * aGraphName ,
458                       const char * aNodeName );
459       bool PyDynInvoke( PyObject * MyPyRunMethod ,
460                         const char *method , 
461                         ServicesAnyData * inParams , int nInParams ,
462                         ServicesAnyData * outParams, int nOutParams ) ;
463
464       int Executing_SuspendAction() ;
465       int SuspendedExecuting_ResumeAction() ;
466       int Executing_KillAction() ;
467       int Executing_StopAction() ;
468       int Executing_SuccessAction() ;
469 //      int Executing_ErrorAction() ;
470       int Errored_ExecutingAction() ;
471       int Successed_SuccessAction() ;
472       bool SendSomeDataReady( char * FromNodeName ) ;
473       int Errored_ErrorAction() ;
474       int Successed_SuspendAction() ;
475       int Errored_SuspendAction() ;
476       int SuspendedSuccessed_ResumeAction() ;
477       int SuspendedErrored_ResumeAction() ;
478       int Successed_KillAction() ;
479       int Errored_KillAction() ;
480       int Successed_StopAction() ;
481       int Errored_StopAction() ;
482       int SuspendedSuccessed_ReStartAction() ;
483       int SuspendedErrored_ReStartAction() ;
484       int SuspendedSuccessed_ReStartAndSuspendAction() ;
485       int SuspendedErrored_ReStartAndSuspendAction() ;
486
487       void InParametersSet( bool & Err ,
488                             int  nInParams ,
489                             ServicesAnyData * InParametersList ) ;
490       void InOutParametersSet( int nOutParams ,
491                                ServicesAnyData * OutParametersList ) ;
492       bool OutParametersSet( bool Err , SUPERV::GraphState PortState ,
493                              int nOutParams ,
494                              ServicesAnyData * OutParametersList ) ;
495       void SetOutPortsOfInportsOfEndSwitch( GraphBase::OutPort * anOutPort ,
496                                             const char * anEndSwitchNodeName ) ;
497       void coutbegin() ;
498       void coutexit() ;
499
500       const long CpuUsed( bool tot = false ) ;
501
502       long PyCpuUsed( bool tot = false ) ;
503       void SetPyCpuUsed() ;
504       long PyCpu() ;
505
506       bool PyRunSimpleString( char* thePyString );
507       PyObject * PyEvalCallObject( const char *method ,
508                                    PyObject * MyPyRunMethod ,
509                                    PyObject * ArgsList ) ;
510     } ;
511
512 } ;
513
514
515 #endif
516