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 : DataFlowExecutor_InNode.cxx
25 // Author : Jean Rahuel, CEA
39 #include <SALOMEconfig.h>
40 #include CORBA_CLIENT_HEADER(SALOME_Component)
41 //#include "SALOME_NamingService.hxx"
42 #include "SALOME_LifeCycleCORBA.hxx"
44 #include "DataFlowBase_FactoryNode.hxx"
45 #include "DataFlowBase_GOTONode.hxx"
46 #include "DataFlowBase_LoopNode.hxx"
47 #include "DataFlowBase_EndOfLoopNode.hxx"
48 #include "DataFlowBase_SwitchNode.hxx"
49 #include "DataFlowBase_EndOfSwitchNode.hxx"
51 #include "DataFlowExecutor_DataFlow.hxx"
52 #include "DataFlowEditor_DataFlow.hxx" // GraphEditor package must be built BEFORE
54 static void InitInNode( int &_RewindStack ,
55 SUPERV::ControlState &_ControlState ,
56 GraphExecutor::AutomatonState &_currentState ,
57 GraphExecutor::InNode ** _aReStartNode ,
58 bool & _PyFuncRunned ,
59 PyObject ** _MyPyRunMethod ,
60 pthread_mutex_t &_MutexDataWait ,
62 pthread_mutex_t &_MutexWait ,
63 pthread_cond_t &_ReadyWait ,
64 pthread_cond_t &_RunningWait ,
65 pthread_cond_t &_DoneWait ,
66 pthread_cond_t &_SuspendedWait ,
67 pthread_cond_t &_SuspendWait ,
69 pthread_cond_t &_ResumeWait ,
71 pthread_cond_t &_KillWait ,
73 pthread_cond_t &_ThreadStartedWait ,
74 bool &_ThreadStartedSync ,
75 pthread_cond_t &_StopWait ,
76 GraphExecutor::FiniteStateMachine ** _Automaton ,
77 GraphExecutor::FiniteStateMachine * theAutomaton ,
78 CORBA::ORB_ptr * _Orb ,
79 CORBA::ORB_ptr ORB ) {
81 _ControlState = SUPERV::VoidState ;
82 _currentState = GraphExecutor::UnKnownState ;
83 *_aReStartNode = NULL ;
84 _PyFuncRunned = false ;
85 *_MyPyRunMethod = NULL ;
86 pthread_mutex_init( &_MutexDataWait , NULL ) ;
88 pthread_mutex_init( &_MutexWait , NULL ) ;
89 if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
90 perror("pthread_cond_init( &_ReadyWait , NULL )") ;
93 if ( pthread_cond_init( &_RunningWait , NULL ) ) {
94 perror("pthread_cond_init( &_RunningWait , NULL )") ;
97 if ( pthread_cond_init( &_DoneWait , NULL ) ) {
98 perror("pthread_cond_init( &_DoneWait , NULL )") ;
101 if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
102 perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
105 if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
106 perror("pthread_cond_init( &_SuspendWait , NULL )") ;
109 _SuspendSync = false ;
110 if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
111 perror("pthread_cond_init( &_ResumeWait , NULL )") ;
114 _ResumeSync = false ;
115 if ( pthread_cond_init( &_KillWait , NULL ) ) {
116 perror("pthread_cond_init( &_KillWait , NULL )") ;
120 if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
121 perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
124 _ThreadStartedSync = false ;
125 if ( pthread_cond_init( &_StopWait , NULL ) ) {
126 perror("pthread_cond_init( &_StopWait , NULL )") ;
129 *_Automaton = theAutomaton ;
130 *_Orb = CORBA::ORB::_nil();
133 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
135 //GraphExecutor::InNode::InNode() :
136 // GraphBase::FactoryNode() {
137 GraphExecutor::InNode::InNode() {
138 InitInNode( _RewindStack ,
163 CORBA::ORB::_nil() ) ;
166 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
167 SALOME_NamingService* ptrNamingService ,
168 const SALOME_ModuleCatalog::Service& aService ,
169 const char * ComponentName ,
170 const char * NodeInterfaceName ,
171 const char * NodeName ,
172 const SUPERV::KindOfNode akind ,
173 GraphBase::ListOfFuncName aFuncName ,
174 GraphBase::ListOfPythonFunctions aPythonFunction ,
175 const SUPERV::SDate NodeFirstCreation ,
176 const SUPERV::SDate NodeLastModification ,
177 const char * NodeEditorRelease ,
178 const char * NodeAuthor ,
179 const char * NodeComputer ,
180 const char * NodeComment ,
181 const bool GeneratedName ,
184 int * Graph_prof_debug,
185 ofstream * Graph_fdebug) {
186 // ostream * Graph_fdebug = NULL ) :
187 // GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
188 // ComponentName , NodeInterfaceName ,
189 // NodeName , akind ,
190 // NodeFirstCreation , NodeLastModification ,
191 // NodeEditorRelease , NodeAuthor ,
192 // NodeComputer , NodeComment , GeneratedName ,
194 // Graph_prof_debug , Graph_fdebug ) {
195 InitInNode( _RewindStack ,
221 SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
224 _ComputingNode = NULL ;
225 _FactoryNode = NULL ;
229 _EndOfLoopNode = NULL ;
231 _EndOfSwitchNode = NULL ;
233 case SUPERV::ComputingNode : {
234 cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
235 _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
239 NodeLastModification ,
240 NodeEditorRelease , NodeAuthor ,
241 NodeComment , GeneratedName ,
243 Graph_prof_debug , Graph_fdebug ) ;
246 case SUPERV::FactoryNode : {
247 cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
248 _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
249 ComponentName , NodeInterfaceName ,
252 NodeLastModification ,
253 NodeEditorRelease , NodeAuthor ,
254 NodeComputer , NodeComment ,
255 GeneratedName , NodeX , NodeY ,
256 Graph_prof_debug , Graph_fdebug ) ;
257 _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
260 case SUPERV::InLineNode : {
261 cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
262 _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
263 aFuncName[0].c_str() , *aPythonFunction[0] ,
265 NodeFirstCreation , NodeLastModification ,
266 NodeEditorRelease , NodeAuthor ,
267 NodeComment , GeneratedName ,
269 Graph_prof_debug , Graph_fdebug ) ;
270 _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
273 case SUPERV::MacroNode : {
274 cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
275 _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
276 // aFuncName[0].c_str() , *aPythonFunction[0] ,
278 // NodeFirstCreation , NodeLastModification ,
279 // NodeEditorRelease , NodeAuthor ,
280 // NodeComment , GeneratedName ,
282 Graph_prof_debug , Graph_fdebug ) ;
283 _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
284 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
285 _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
286 _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
289 case SUPERV::GOTONode : {
290 cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
291 _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
292 aFuncName[0].c_str() , *aPythonFunction[0] ,
294 NodeFirstCreation , NodeLastModification ,
295 NodeEditorRelease , NodeAuthor ,
296 NodeComment , GeneratedName ,
298 Graph_prof_debug , Graph_fdebug ) ;
299 _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
300 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
303 case SUPERV::LoopNode : {
304 cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
305 _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
306 aFuncName[0].c_str() , *aPythonFunction[0] ,
307 aFuncName[1].c_str() , *aPythonFunction[1] ,
308 aFuncName[2].c_str() , *aPythonFunction[2] ,
310 NodeFirstCreation , NodeLastModification ,
311 NodeEditorRelease , NodeAuthor ,
312 NodeComment , GeneratedName ,
314 Graph_prof_debug , Graph_fdebug ) ;
315 _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
316 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
317 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
320 case SUPERV::EndLoopNode : {
321 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
322 _EndOfLoopNode = new GraphBase::EndOfLoopNode(
323 ORB , ptrNamingService ,
324 aFuncName[0].c_str() , *aPythonFunction[0] ,
326 NodeFirstCreation , NodeLastModification ,
327 NodeEditorRelease , NodeAuthor ,
328 NodeComment , GeneratedName ,
330 Graph_prof_debug , Graph_fdebug ) ;
331 _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
332 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
333 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
336 case SUPERV::SwitchNode : {
337 cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
338 _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
339 aFuncName[0].c_str() , *aPythonFunction[0] ,
341 NodeFirstCreation , NodeLastModification ,
342 NodeEditorRelease , NodeAuthor ,
343 NodeComment , GeneratedName ,
345 Graph_prof_debug , Graph_fdebug ) ;
346 _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
347 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
348 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
351 case SUPERV::EndSwitchNode : {
352 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
353 _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
354 ORB , ptrNamingService ,
355 aFuncName[0].c_str() , *aPythonFunction[0] ,
357 NodeFirstCreation , NodeLastModification ,
358 NodeEditorRelease , NodeAuthor ,
359 NodeComment , GeneratedName ,
361 Graph_prof_debug , Graph_fdebug ) ;
362 _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
363 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
364 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
367 case SUPERV::DataFlowGraph : {
368 cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
370 case SUPERV::DataStreamGraph : {
371 cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
373 case SUPERV::UnknownNode : {
374 cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
377 cdebug << "GraphExecutor::InNode::InNode " << (void *) this
378 << " _ComputingNode " << (void *) _ComputingNode ;
379 _ComputingNode->InNode( this ) ;
382 GraphExecutor::InNode::~InNode() {
385 void GraphExecutor::InNode::LockDataWait() {
386 if ( pthread_mutex_lock( &_MutexDataWait ) ) {
387 perror("Ready pthread_mutex_lock ") ;
392 void GraphExecutor::InNode::UnLockDataWait() {
394 if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
395 perror("Ready pthread_mutex_unlock ") ;
400 Engines::Component_var GraphExecutor::InNode::Component() const {
401 if ( IsFactoryNode() ) {
402 return _FactoryNode->Component() ;
405 CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
406 CORBA::Object_ptr obj ;
408 *anAnyComponent >>= obj ;
409 return Engines::Component::_narrow( obj ) ;
412 cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
415 return Engines::Component::_nil() ;
418 Engines::Container_var GraphExecutor::InNode::Container() const {
419 if ( IsFactoryNode() ) {
420 return _FactoryNode->Container() ;
422 return Engines::Container::_nil() ;
426 bool GraphExecutor::InNode::Ping() {
427 // cdebug_in << "GraphExecutor::InNode::Ping" << endl;
429 if ( IsFactoryNode() ) {
430 RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
432 if ( State() != GraphExecutor::SuspendedExecutingState ) {
434 _FactoryNode->Component()->ping() ;
437 cdebug << "InNode::Ping() ERROR catched" << endl ;
438 State( GraphExecutor::ErroredState ) ;
439 _OutNode->State( GraphExecutor::ErroredState ) ;
448 // cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
452 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
453 ThreadNo ( aThread ) ;
455 _OutNode->NewThread() ;
457 void GraphExecutor::InNode::ExitThread() {
459 _OutNode->ExitThread() ;
462 bool GraphExecutor::InNode::Suspend() {
463 cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
464 << " " << Automaton()->StateName( State() ) << endl;
465 bool RetVal = false ;
467 //If loop we need to suspend also ControlState( SUPERV::VoidState ) ;
468 ControlState( SUPERV::ToSuspendState ) ;
470 if ( _OutNode->IsDone() ) {
471 ControlState( SUPERV::VoidState ) ;
475 else if ( IsWaiting() || IsReady() ) {
476 ControlState( SUPERV::ToSuspendState ) ;
479 else if ( IsRunning() ) {
480 ControlState( SUPERV::ToSuspendState ) ;
481 if ( IsFactoryNode() || IsComputingNode() ) {
482 // We have to suspend in the container of that node
483 int TrySuspend = 10 ;
484 while ( TrySuspend ) {
485 if ( !CORBA::is_nil( Component() ) ) {
486 // We can call that component
488 RetVal = Component()->Suspend_impl() ;
491 cdebug << "InNode::Suspend() ERROR catched" << endl ;
492 State( GraphExecutor::ErroredState ) ;
493 _OutNode->State( GraphExecutor::ErroredState ) ;
497 cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
500 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
501 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
502 SendEvent( GraphExecutor::SuspendEvent ) ;
503 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
504 << Name() << " --> thread" << ThreadNo() << endl;
507 else if ( IsDone() ) {
508 ControlState( SUPERV::VoidState ) ;
509 RetVal = false ; // Too late ...
513 cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
515 MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
520 // Suspend in the Container failed : it is always false if it is a Python Container
521 cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
523 if ( TrySuspend == 1 ) {
524 if ( IsSuspended() ) {
534 cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
536 // Wait for the end of loading of the component
537 while ( IsLoading() ) {
540 if ( TrySuspend == 1 ) {
541 if ( IsSuspended() ) {
555 else if ( IsMacroNode() ) {
556 // It should be like that but it is not completely implemented
557 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
558 RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
560 State( GraphExecutor::SuspendedState ) ;
564 // Now we can suspend an InLineNode with the handler of the SuperVision Container
565 if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
566 perror("Suspend pthread_kill error") ;
567 State( GraphExecutor::ErroredState ) ;
568 _OutNode->State( GraphExecutor::ErroredState ) ;
576 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
577 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
578 SendEvent( GraphExecutor::SuspendEvent ) ;
579 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
580 << Name() << " --> thread" << ThreadNo() << endl;
582 else if ( IsDone() ) {
583 ControlState( SUPERV::VoidState ) ;
584 RetVal = false ; // Too late ...
587 cdebug << "component Suspended and !IsDone and !IsRunning !"
594 cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
595 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
599 cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
600 << Automaton()->StateName( State() ) << endl ;
604 bool GraphExecutor::InNode::ContainerKill() {
605 cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
606 << ThreadNo() << endl;
608 if ( IsFactoryNode() ) {
610 RetVal = Container()->Kill_impl() ;
612 cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
616 bool GraphExecutor::InNode::Kill() {
617 cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
618 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
619 << " SuspendedThreads " << _OutNode->SuspendedThreads()
620 << " EventQSize " << _OutNode->EventQSize() << endl;
623 ControlState( SUPERV::ToKillState ) ; // if loop
624 if ( _OutNode->IsDone() ) {
625 ControlState( SUPERV::VoidState ) ;
630 ControlState( SUPERV::ToKillState ) ;
632 if ( _OutNode->IsDone() ) {
633 ControlState( SUPERV::VoidState ) ;
639 if ( IsFactoryNode() || IsComputingNode() ) {
640 // We have to suspend in the container of that node
643 if ( !CORBA::is_nil( Component() ) ) {
644 // We can call that component
646 RetVal = Component()->Kill_impl() ;
649 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
650 State( GraphExecutor::ErroredState ) ;
651 _OutNode->State( GraphExecutor::ErroredState ) ;
655 cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
658 cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
659 << " --> thread" << ThreadNo() << " KillEvent " << endl;
660 SendEvent( GraphExecutor::KillEvent ) ;
661 cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
662 << Name() << " --> thread" << ThreadNo() << endl;
665 else if ( IsDone() ) {
666 ControlState( SUPERV::VoidState ) ;
667 RetVal = false ; // Too late ...
671 cdebug << "Kill component Killed and !IsDone and !IsRunning !"
677 // Kill in the Container failed : it is always false if it is a Python Container
678 cdebug << "InNode::Suspend cannot Kill component ! Python Component ?"
680 if ( TryKill == 1 ) {
691 cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
693 // Wait for the end of loading of the component
694 while ( IsLoading() ) {
697 if ( TryKill == 1 ) {
712 else if ( IsMacroNode() ) {
713 // It should be like that but it is not completely implemented
714 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
715 RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
717 State( GraphExecutor::KilledState ) ;
722 // Now we can kill an InLineNode with the handler of the SuperVision Container
723 cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
724 << _OutNode->MainThreadId() << " :" << endl ;
725 MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
726 << _OutNode->MainThreadId() << " :" ) ;
727 if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
728 // python signals run only in main thread ...
729 perror("Kill pthread_kill error") ;
730 State( GraphExecutor::ErroredState ) ;
731 _OutNode->State( GraphExecutor::ErroredState ) ;
735 cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
736 << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
737 MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
738 << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
743 else if ( IsSuspended() ) {
744 cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
745 << " --> thread" << ThreadNo() << " Resume()" << endl;
753 else if ( IsWaiting() ) {
756 else if ( IsReady() ) {
760 cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
761 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
767 cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
768 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
769 << " SuspendedThreads " << _OutNode->SuspendedThreads()
770 << " EventQSize " << _OutNode->EventQSize() << endl ;
774 bool GraphExecutor::InNode::KillDone() {
775 cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
778 if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
782 ControlState( SUPERV::ToKillDoneState ) ;
784 if ( _OutNode->IsDone() ) {
785 ControlState( SUPERV::VoidState ) ;
793 else if ( IsWaiting() ) {
797 cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
803 cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
807 bool GraphExecutor::InNode::Stop() {
808 cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
811 if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
815 ControlState( SUPERV::ToStopState ) ;
817 if ( _OutNode->IsDone() ) {
818 ControlState( SUPERV::VoidState ) ;
824 if ( IsFactoryNode() || IsComputingNode() ) {
825 if ( !CORBA::is_nil( Component() ) ) {
827 RetVal = Component()->Stop_impl() ;
830 cdebug << "InNode::Stop() ERROR catched" << endl ;
831 State( GraphExecutor::ErroredState ) ;
832 _OutNode->State( GraphExecutor::ErroredState ) ;
837 SendEvent( GraphExecutor::StopEvent ) ;
839 else if ( IsDone() ) {
840 ControlState( SUPERV::VoidState ) ;
841 RetVal = false ; // Too late ...
844 cdebug << "component Suspended and !IsDone and !IsRunning !"
850 cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
855 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
859 else if ( IsWaiting() ) {
863 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
869 cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
873 bool GraphExecutor::InNode::SuspendDone() {
874 cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
875 << ThreadNo() << endl;
877 if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
881 ControlState( SUPERV::ToSuspendDoneState ) ;
883 if ( _OutNode->IsDone() ) {
884 ControlState( SUPERV::VoidState ) ;
892 cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
896 bool GraphExecutor::InNode::Resume() {
897 cdebug_in << pthread_self() << "/" << ThreadNo()
898 << " GraphExecutor::InNode::Resume " << Name() << " "
899 << Automaton()->StateName( State() ) << endl;
900 bool RetVal = false ;
901 if ( IsSuspended() ) {
902 if ( State() == GraphExecutor::SuspendedReadyState ) {
903 ResumeAction( GraphExecutor::ToResumeEvent ) ;
906 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
907 if ( IsFactoryNode() || IsComputingNode() ) {
908 if ( pthread_mutex_lock( &_MutexWait ) ) {
909 perror("ResumeAction pthread_mutex_lock ") ;
913 RetVal = Component()->Resume_impl() ;
915 State( GraphExecutor::ExecutingState ) ;
919 cdebug << "InNode::Resume() ERROR catched" << endl ;
920 State( GraphExecutor::ErroredState ) ;
921 _OutNode->State( GraphExecutor::ErroredState ) ;
924 if ( pthread_mutex_unlock( &_MutexWait ) ) {
925 perror("ResumeAction pthread_mutex_unlock ") ;
929 else if ( IsMacroNode() ) {
930 cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
931 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
932 RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
934 State( GraphExecutor::ExecutingState ) ;
938 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
939 cdebug << ThreadNo() << "/" << pthread_self()
940 << "Resume of InLineNode pthread_kill" << Name() << endl ;
941 if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
942 perror("Resume pthread_kill error") ;
943 State( GraphExecutor::ErroredState ) ;
944 _OutNode->State( GraphExecutor::ErroredState ) ;
948 State( GraphExecutor::ExecutingState ) ;
953 else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
954 ResumeAction( GraphExecutor::ResumeEvent ) ;
957 else if ( State() == GraphExecutor::SuspendedErroredState ) {
958 ResumeAction( GraphExecutor::ResumeEvent ) ;
962 cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
963 << Automaton()->StateName( State() ) << endl ;
968 cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
969 << Automaton()->StateName( State() ) << endl ;
972 if ( ControlState() == SUPERV::ToSuspendStartState ) {
973 ControlState( SUPERV::VoidState ) ;
977 if ( ControlState() == SUPERV::ToSuspendRunState ||
978 ( ControlState() == SUPERV::ToSuspendState &&
979 State() == GraphExecutor::SuspendedReadyState) ) {
980 if ( IsSuspended() ) {
981 if ( State() == GraphExecutor::SuspendedReadyState ) {
985 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
987 RetVal = Component()->Resume_impl() ;
990 cdebug << "GraphExecutor::InNode::Resume State "
991 << Automaton()->StateName( State() ) << endl ;
994 if ( ControlState() != SUPERV::ToSuspendState ) {
995 ControlState( SUPERV::VoidState ) ;
998 else if ( IsRunning() ) {
1001 else if ( IsWaiting() ) {
1002 ControlState( SUPERV::VoidState ) ;
1005 else if ( IsDone() ) {
1009 else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1010 ( ControlState() == SUPERV::ToSuspendState &&
1011 State() == GraphExecutor::SuspendedSuccessedState) ) {
1012 if ( IsSuspended() ) {
1013 if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1017 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1022 cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1025 if ( ControlState() != SUPERV::ToSuspendState ) {
1026 ControlState( SUPERV::VoidState ) ;
1029 else if ( IsRunning() ) {
1030 ControlState( SUPERV::VoidState ) ;
1033 else if ( IsWaiting() ) {
1034 ControlState( SUPERV::VoidState ) ;
1037 else if ( IsDone() ) {
1038 ControlState( SUPERV::VoidState ) ;
1043 cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1044 << Automaton()->StateName( State() ) << endl ;
1048 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
1049 const bool AndSuspend ) {
1050 bool RetVal = false ;
1051 GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetGraphNode( AtNodeName )->GetInNode() ;
1052 cdebug_in << pthread_self() << "/" << ThreadNo()
1053 << " --> GraphExecutor::InNode::ReStartAt( "
1054 << AtNodeName << " , " << AndSuspend << ") " << endl
1055 << "thread " << aRestartNode->ThreadNo() << " "
1056 << Automaton()->StateName( aRestartNode->State() )
1057 << " from " << Name() << " " << Automaton()->StateName( State() )
1059 if ( IsWaiting() && aRestartNode->IsSuspended() ) {
1060 RetVal = aRestartNode->Resume() ;
1062 else if ( IsSuspended() ) {
1063 if ( strcmp( AtNodeName , Name() ) ) {
1064 aRestartNode->State( GraphExecutor::SuspendedSuccessedState ) ;
1067 ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
1070 ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
1074 cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << endl ;
1078 bool GraphExecutor::InNode::IsWaiting() {
1080 // cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1081 GraphExecutor::AutomatonState aState = State() ;
1082 if ( aState == GraphExecutor::DataUndefState ||
1083 aState == GraphExecutor::DataWaitingState ||
1084 aState == GraphExecutor::SuspendedReadyState )
1085 // aState == GraphExecutor::SuspendedExecutingState ||
1086 // aState == GraphExecutor::SuspendedSuccessedState ||
1087 // aState == GraphExecutor::SuspendedErroredState ||
1088 // aState == GraphExecutor::SuspendedState
1090 // cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1094 bool GraphExecutor::InNode::IsReady() {
1096 // cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1097 GraphExecutor::AutomatonState aState = State() ;
1098 // if ( aState == GraphExecutor::DataUndefState ||
1099 // aState == GraphExecutor::DataWaitingState ||
1100 if ( aState == GraphExecutor::DataReadyState ||
1101 aState == GraphExecutor::ResumedReadyState )
1103 // cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1107 bool GraphExecutor::InNode::IsRunning() {
1109 // cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1110 GraphExecutor::AutomatonState aState = State() ;
1111 if ( aState == GraphExecutor::ExecutingState ||
1112 aState == GraphExecutor::ResumedExecutingState )
1114 // cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1118 bool GraphExecutor::InNode::IsDone() {
1120 // cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1121 GraphExecutor::AutomatonState aState = State() ;
1122 if ( aState == GraphExecutor::KilledReadyState ||
1123 aState == GraphExecutor::StoppedReadyState ||
1124 aState == GraphExecutor::KilledExecutingState ||
1125 aState == GraphExecutor::StoppedExecutingState ||
1126 aState == GraphExecutor::SuspendedSuccessedState ||
1127 aState == GraphExecutor::SuspendedErroredState ||
1128 // aState == GraphExecutor::SuccessedExecutingState ||
1129 // aState == GraphExecutor::ErroredExecutingState ||
1130 aState == GraphExecutor::SuccessedState ||
1131 aState == GraphExecutor::ErroredState ||
1132 aState == GraphExecutor::ResumedSuccessedState ||
1133 aState == GraphExecutor::ResumedErroredState ||
1134 aState == GraphExecutor::KilledSuccessedState ||
1135 aState == GraphExecutor::StoppedSuccessedState )
1137 // cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1141 bool GraphExecutor::InNode::IsSuspended() {
1143 // cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1144 GraphExecutor::AutomatonState aState = State() ;
1145 if ( aState == GraphExecutor::SuspendedReadyState ||
1146 aState == GraphExecutor::SuspendedExecutingState ||
1147 aState == GraphExecutor::SuspendedSuccessedState ||
1148 aState == GraphExecutor::SuspendedErroredState ||
1149 aState == GraphExecutor::SuspendedState )
1151 // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1154 bool GraphExecutor::InNode::IsKilled() {
1156 // cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1157 GraphExecutor::AutomatonState aState = State() ;
1158 if ( aState == GraphExecutor::KilledReadyState ||
1159 aState == GraphExecutor::KilledExecutingState ||
1160 aState == GraphExecutor::KilledSuccessedState ||
1161 aState == GraphExecutor::KilledErroredState ||
1162 aState == GraphExecutor::KilledState )
1164 // cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1167 bool GraphExecutor::InNode::IsStopped() {
1169 // cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1170 GraphExecutor::AutomatonState aState = State() ;
1171 if ( aState == GraphExecutor::StoppedReadyState ||
1172 aState == GraphExecutor::StoppedExecutingState ||
1173 aState == GraphExecutor::StoppedSuccessedState ||
1174 aState == GraphExecutor::StoppedErroredState ||
1175 aState == GraphExecutor::StoppedState )
1177 // cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1181 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1182 bool RetVal = false ;
1183 if ( pthread_mutex_lock( &_MutexWait ) ) {
1184 perror("pthread_mutex_lock _Wait") ;
1188 case SUPERV::ReadyState : {
1189 RetVal = IsReady() ;
1190 cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1191 << " " << Automaton()->StateName( _currentState )
1192 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1193 while ( !RetVal && !IsDone() ) {
1194 cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1195 pthread_cond_wait( &_ReadyWait , &_MutexWait );
1196 RetVal = IsReady() ;
1197 cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1198 << Automaton()->StateName( _currentState ) << " " << RetVal
1201 cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1202 << " " << Automaton()->StateName( _currentState )
1203 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1206 case SUPERV::RunningState : {
1207 RetVal = IsRunning() ;
1208 cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1209 << " " << Automaton()->StateName( _currentState )
1210 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1211 while ( !RetVal && !IsDone() ) {
1212 cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1213 pthread_cond_wait( &_RunningWait , &_MutexWait );
1214 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1215 RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1216 State() == GraphExecutor::ErroredExecutingState ;
1217 cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1218 << Automaton()->StateName( _currentState ) << " " << RetVal
1219 << " " << Name() << endl ;
1221 cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1222 << " " << Automaton()->StateName( _currentState )
1223 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1226 case SUPERV::DoneState : {
1228 cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1229 << " " << Automaton()->StateName( _currentState )
1230 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1232 cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1233 pthread_cond_wait( &_DoneWait , &_MutexWait );
1235 cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1236 << Automaton()->StateName( _currentState ) << " " << RetVal
1239 cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1240 << " " << Automaton()->StateName( _currentState )
1241 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1244 case SUPERV::SuspendState : {
1245 RetVal = IsSuspended() ;
1246 cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1247 << " " << Automaton()->StateName( _currentState )
1248 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1249 while ( !RetVal && !IsDone() ) {
1250 cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1251 pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1252 RetVal = IsSuspended() ;
1253 cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1254 << Automaton()->StateName( _currentState ) << " " << RetVal
1257 cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1258 << " " << Automaton()->StateName( _currentState )
1259 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1263 cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1267 if ( pthread_mutex_unlock( &_MutexWait ) ) {
1268 perror("pthread_mutex_lock _Wait") ;
1274 bool GraphExecutor::InNode::ReadyWait() {
1275 // cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1277 aret = StateWait( SUPERV::ReadyState ) ;
1278 // cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1282 bool GraphExecutor::InNode::RunningWait() {
1283 cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1284 << " " << Automaton()->StateName( State() ) << endl;
1286 aret = StateWait( SUPERV::RunningState ) ;
1287 cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1288 << " " << Automaton()->StateName( State() ) << endl;
1292 bool GraphExecutor::InNode::DoneWait() {
1293 // cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1295 aret = StateWait( SUPERV::DoneState ) ;
1299 bool GraphExecutor::InNode::SuspendedWait() {
1300 // cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1302 aret = StateWait( SUPERV::SuspendState ) ;
1306 void GraphExecutor::InNode::InitialState()
1308 cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1311 _ControlState = SUPERV::VoidState ;
1312 CreateNewThread( false ) ;
1313 CreateNewThreadIf( false ) ;
1314 _SuspendSync = false ;
1315 _ResumeSync = false ;
1317 // ThreadNo( pthread_self() ) ;
1320 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1321 if ( GetNodeOutPort(i)->IsDataStream() ) {
1322 GetChangeNodeOutPort(i)->State( SUPERV::ReadyState ) ;
1323 GetChangeNodeOutPort(i)->Done( true ) ;
1325 else if ( i != 0 || !IsGOTONode() ) {
1326 GetChangeNodeOutPort(i)->State( SUPERV::WaitingState ) ;
1327 GetChangeNodeOutPort(i)->Done( false ) ;
1331 int Pc = GetNodeInPortsSize() ;
1332 for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1333 const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1334 GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1335 if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1336 anOutPort->PortStatus( DataConnected );
1337 anOutPort->State( SUPERV::ReadyState ) ;
1338 anOutPort->Done( true ) ;
1339 CORBA::Any * anAny = new CORBA::Any() ;
1340 *anAny <<= (long ) 1 ;
1341 anOutPort->Value( anAny ) ;
1343 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1344 else if ( anInPort->IsGate() && anOutPort ) {
1345 anOutPort->State( SUPERV::WaitingState ) ;
1346 anOutPort->Done( false ) ;
1347 const GraphBase::ComputingNode * aFromNode = _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ;
1348 if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) { // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.
1349 // before was "else if ( IsOneOfInlineNodes() )"
1350 // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1351 anOutPort->PortStatus( DataConnected );
1352 anOutPort->State( SUPERV::ReadyState ) ;
1353 anOutPort->Done( true ) ;
1356 if ( anInPort->IsGate() && anOutPort == NULL ) {
1358 cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected Pc " << Pc << endl ;
1360 else if ( anOutPort ) {
1361 if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1363 anOutPort->State( SUPERV::ReadyState ) ;
1364 anOutPort->Done( true ) ;
1365 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1366 << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1368 else if ( anOutPort->IsPortConnected() ) {
1369 anOutPort->State( SUPERV::WaitingState ) ;
1370 anOutPort->Done( false ) ;
1371 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1372 << " " << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1375 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1376 << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1377 << theAutomaton->StateName( anOutPort->State() ) << " Pc " << Pc << endl ;
1381 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1382 << " no corresponding OutPort Pc " << Pc << endl ;
1385 if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1386 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1387 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1388 << " with state " << theAutomaton->StateName( anOutPort->State() ) << endl ;
1389 GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1391 else if ( anOutPort->IsDataConnected() ) {
1392 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1393 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1394 << " with state ReadyState" << endl ;
1395 GetChangeNodeInPort(i)->State( SUPERV::ReadyState ) ;
1398 cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1399 << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1400 << " with state " << anOutPort->State() << endl ;
1404 cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1405 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1407 if ( anOutPort->State() == SUPERV::WaitingState ) {
1408 cdebug << "WaitingState" ;
1410 else if ( anOutPort->State() == SUPERV::ReadyState ) {
1411 cdebug << "ReadyState" ;
1416 cdebug << " PortConnected("
1417 << anOutPort->IsPortConnected() << ") DataConnected("
1418 << anOutPort->IsDataConnected() << ")" << endl ;
1422 _currentState = Pc > 0 ? GraphExecutor::DataWaitingState
1423 : GraphExecutor::DataReadyState ;
1424 if ( Pc == GetNodeInPortsSize() ) {
1425 _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1428 else if ( Pc != 0 ) {
1429 _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1433 _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1437 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1438 cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1439 << theAutomaton->StateName( GetChangeNodeOutPort(i)->State() )
1440 << " " << GetNodeOutPort(i)->Kind() << endl ;
1443 cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1446 cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1449 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1450 cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
1452 if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1453 if ( IsLoopNode() ) {
1454 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1455 PyObject * PyMoreMethod = NULL ;
1456 PyObject * PyNextMethod = NULL ;
1457 if ( PyRunMethod ) {
1460 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1461 InLineNode()->PythonFunction() ,
1463 InLineNode()->PyRunMethod( PyRunMethod ) ;
1466 PyMoreMethod = LoopNode()->PyMoreMethod() ;
1467 if ( PyMoreMethod ) {
1470 PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1471 LoopNode()->MorePythonFunction() ,
1473 LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1477 PyNextMethod = LoopNode()->PyNextMethod() ;
1478 if ( PyNextMethod ) {
1481 PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1482 LoopNode()->NextPythonFunction() ,
1484 LoopNode()->PyNextMethod( PyNextMethod ) ;
1487 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1488 << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1490 else if ( IsInLineNode() || IsSwitchNode() ) {
1491 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1492 if ( PyRunMethod ) {
1495 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1496 InLineNode()->PythonFunction() ,
1498 InLineNode()->PyRunMethod( PyRunMethod ) ;
1500 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1502 else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1503 (*InLineNode()->PythonFunction()).length() ) {
1504 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1505 if ( PyRunMethod ) {
1508 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1509 InLineNode()->PythonFunction() ,
1511 InLineNode()->PyRunMethod( PyRunMethod ) ;
1513 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1516 Err = WithErr && Err ;
1517 cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1519 cdebug << " Error " << Err ;
1525 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1526 CORBA::Long cpu = 0 ;
1527 // cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1528 if ( IsOneOfInLineNodes() ) {
1529 // cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1530 // cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1531 cpu = PyCpuUsed( tot ) ;
1534 if ( !CORBA::is_nil( Component() ) ) {
1535 // cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1536 // cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1538 cpu = Component()->CpuUsed_impl() ;
1541 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1542 State( GraphExecutor::ErroredState ) ;
1543 _OutNode->State( GraphExecutor::ErroredState ) ;
1548 // cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1549 // cout << "CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1553 #include <sys/time.h>
1554 #include <sys/resource.h>
1557 long GraphExecutor::InNode::PyCpu() {
1558 struct rusage usage ;
1560 if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1561 perror("GraphExecutor::InNode::PyCpu") ;
1564 // return usage.ru_utime.__time_t tv_sec ;
1565 // cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1566 // << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1568 cpu = usage.ru_utime.tv_sec ;
1572 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1574 if ( _PyTotCpuUsed == -1 ) {
1575 if ( _Pythread == pthread_self() ) {
1576 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1577 // << " _PyTotCpuUsed " << _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1578 // << _PyCpuUsed << endl ;
1579 cpu = PyCpu() - _PyCpuUsed ;
1581 _PyTotCpuUsed = cpu ;
1589 cpu = _PyTotCpuUsed ;
1591 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1592 // << _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1596 void GraphExecutor::InNode::SetPyCpuUsed() {
1597 _PyTotCpuUsed = -1 ;
1599 _Pythread = pthread_self() ;
1600 _PyCpuUsed = PyCpu() ;
1601 // cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1602 // << _PyCpuUsed << endl ;
1605 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1606 _Loading = Loading ;
1608 // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works:
1609 // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1610 // after Loading is finished (here below), ExecutingState must be pushed for GUI.
1612 _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );