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 ,
82 _ControlState = SUPERV::VoidState ;
83 _currentState = GraphExecutor::UnKnownState ;
84 *_aReStartNode = NULL ;
85 _PyFuncRunned = false ;
86 *_MyPyRunMethod = NULL ;
87 pthread_mutex_init( &_MutexDataWait , NULL ) ;
89 pthread_mutex_init( &_MutexWait , NULL ) ;
90 if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
91 perror("pthread_cond_init( &_ReadyWait , NULL )") ;
94 if ( pthread_cond_init( &_RunningWait , NULL ) ) {
95 perror("pthread_cond_init( &_RunningWait , NULL )") ;
98 if ( pthread_cond_init( &_DoneWait , NULL ) ) {
99 perror("pthread_cond_init( &_DoneWait , NULL )") ;
102 if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
103 perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
106 if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
107 perror("pthread_cond_init( &_SuspendWait , NULL )") ;
110 _SuspendSync = false ;
111 if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
112 perror("pthread_cond_init( &_ResumeWait , NULL )") ;
115 _ResumeSync = false ;
116 if ( pthread_cond_init( &_KillWait , NULL ) ) {
117 perror("pthread_cond_init( &_KillWait , NULL )") ;
121 if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
122 perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
125 _ThreadStartedSync = false ;
126 if ( pthread_cond_init( &_StopWait , NULL ) ) {
127 perror("pthread_cond_init( &_StopWait , NULL )") ;
130 *_Automaton = theAutomaton ;
131 *_Orb = CORBA::ORB::_nil();
135 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
137 //GraphExecutor::InNode::InNode() :
138 // GraphBase::FactoryNode() {
139 GraphExecutor::InNode::InNode() {
140 InitInNode( _RewindStack ,
169 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
170 SALOME_NamingService* ptrNamingService ,
171 const SALOME_ModuleCatalog::Service& aService ,
172 const char * ComponentName ,
173 const char * NodeInterfaceName ,
174 const char * NodeName ,
175 const SUPERV::KindOfNode akind ,
176 GraphBase::ListOfFuncName aFuncName ,
177 GraphBase::ListOfPythonFunctions aPythonFunction ,
178 const SUPERV::SDate NodeFirstCreation ,
179 const SUPERV::SDate NodeLastModification ,
180 const char * NodeEditorRelease ,
181 const char * NodeAuthor ,
182 const char * NodeComputer ,
183 const char * NodeComment ,
184 const bool GeneratedName ,
187 int * Graph_prof_debug,
188 ofstream * Graph_fdebug) {
189 // ostream * Graph_fdebug = NULL ) :
190 // GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
191 // ComponentName , NodeInterfaceName ,
192 // NodeName , akind ,
193 // NodeFirstCreation , NodeLastModification ,
194 // NodeEditorRelease , NodeAuthor ,
195 // NodeComputer , NodeComment , GeneratedName ,
197 // Graph_prof_debug , Graph_fdebug ) {
198 InitInNode( _RewindStack ,
225 SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
227 _ComputingNode = NULL ;
228 _FactoryNode = NULL ;
232 _EndOfLoopNode = NULL ;
234 _EndOfSwitchNode = NULL ;
236 case SUPERV::ComputingNode : {
237 cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
238 _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
242 NodeLastModification ,
243 NodeEditorRelease , NodeAuthor ,
244 NodeComment , GeneratedName ,
246 Graph_prof_debug , Graph_fdebug ) ;
249 case SUPERV::FactoryNode : {
250 cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
251 _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
252 ComponentName , NodeInterfaceName ,
255 NodeLastModification ,
256 NodeEditorRelease , NodeAuthor ,
257 NodeComputer , NodeComment ,
258 GeneratedName , NodeX , NodeY ,
259 Graph_prof_debug , Graph_fdebug ) ;
260 _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
263 case SUPERV::InLineNode : {
264 cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
265 _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
266 aFuncName[0].c_str() , *aPythonFunction[0] ,
268 NodeFirstCreation , NodeLastModification ,
269 NodeEditorRelease , NodeAuthor ,
270 NodeComment , GeneratedName ,
272 Graph_prof_debug , Graph_fdebug ) ;
273 _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
276 case SUPERV::MacroNode : {
277 cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
278 _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
279 // aFuncName[0].c_str() , *aPythonFunction[0] ,
281 // NodeFirstCreation , NodeLastModification ,
282 // NodeEditorRelease , NodeAuthor ,
283 // NodeComment , GeneratedName ,
285 Graph_prof_debug , Graph_fdebug ) ;
286 _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
287 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
288 _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
289 _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
292 case SUPERV::GOTONode : {
293 cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
294 _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
295 aFuncName[0].c_str() , *aPythonFunction[0] ,
297 NodeFirstCreation , NodeLastModification ,
298 NodeEditorRelease , NodeAuthor ,
299 NodeComment , GeneratedName ,
301 Graph_prof_debug , Graph_fdebug ) ;
302 _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
303 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
306 case SUPERV::LoopNode : {
307 cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
308 _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
309 aFuncName[0].c_str() , *aPythonFunction[0] ,
310 aFuncName[1].c_str() , *aPythonFunction[1] ,
311 aFuncName[2].c_str() , *aPythonFunction[2] ,
313 NodeFirstCreation , NodeLastModification ,
314 NodeEditorRelease , NodeAuthor ,
315 NodeComment , GeneratedName ,
317 Graph_prof_debug , Graph_fdebug ) ;
318 _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
319 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
320 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
323 case SUPERV::EndLoopNode : {
324 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
325 _EndOfLoopNode = new GraphBase::EndOfLoopNode(
326 ORB , ptrNamingService ,
327 aFuncName[0].c_str() , *aPythonFunction[0] ,
329 NodeFirstCreation , NodeLastModification ,
330 NodeEditorRelease , NodeAuthor ,
331 NodeComment , GeneratedName ,
333 Graph_prof_debug , Graph_fdebug ) ;
334 _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
335 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
336 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
339 case SUPERV::SwitchNode : {
340 cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
341 _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
342 aFuncName[0].c_str() , *aPythonFunction[0] ,
344 NodeFirstCreation , NodeLastModification ,
345 NodeEditorRelease , NodeAuthor ,
346 NodeComment , GeneratedName ,
348 Graph_prof_debug , Graph_fdebug ) ;
349 _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
350 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
351 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
354 case SUPERV::EndSwitchNode : {
355 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
356 _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
357 ORB , ptrNamingService ,
358 aFuncName[0].c_str() , *aPythonFunction[0] ,
360 NodeFirstCreation , NodeLastModification ,
361 NodeEditorRelease , NodeAuthor ,
362 NodeComment , GeneratedName ,
364 Graph_prof_debug , Graph_fdebug ) ;
365 _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
366 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
367 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
370 case SUPERV::DataFlowGraph : {
371 cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
373 case SUPERV::DataStreamGraph : {
374 cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
376 case SUPERV::UnknownNode : {
377 cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
380 cdebug << "GraphExecutor::InNode::InNode " << (void *) this
381 << " _ComputingNode " << (void *) _ComputingNode ;
382 _ComputingNode->InNode( this ) ;
385 GraphExecutor::InNode::~InNode() {
388 void GraphExecutor::InNode::LockDataWait() {
389 // cdebug_in << "GraphExecutor::InNode::LockDataWait " << endl ;
390 if ( pthread_mutex_lock( &_MutexDataWait ) ) {
391 perror("Ready pthread_mutex_lock ") ;
395 // cdebug_out << "GraphExecutor::InNode::LockDataWait " << endl ;
397 void GraphExecutor::InNode::UnLockDataWait() {
398 // cdebug_in << "GraphExecutor::InNode::UnLockDataWait " << endl ;
400 if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
401 perror("Ready pthread_mutex_unlock ") ;
404 // cdebug_out << "GraphExecutor::InNode::UnLockDataWait " << endl ;
407 Engines::Component_var GraphExecutor::InNode::Component() const {
408 if ( IsFactoryNode() ) {
409 return _FactoryNode->Component() ;
412 //JR 30.03.2005 CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
413 const CORBA::Any anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
414 CORBA::Object_ptr obj ;
416 //JR 30.03.2005 *anAnyComponent >>= obj ;
417 anAnyComponent >>= obj ;
418 return Engines::Component::_narrow( obj ) ;
421 cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
424 return Engines::Component::_nil() ;
427 Engines::Container_var GraphExecutor::InNode::Container() const {
428 if ( IsFactoryNode() ) {
429 return _FactoryNode->Container() ;
431 return Engines::Container::_nil() ;
435 bool GraphExecutor::InNode::Ping() {
436 // cdebug_in << "GraphExecutor::InNode::Ping" << endl;
438 if ( IsFactoryNode() ) {
439 RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
441 if ( State() != GraphExecutor::SuspendedExecutingState ) {
443 _FactoryNode->Component()->ping() ;
446 cdebug << "InNode::Ping() ERROR catched" << endl ;
447 State( GraphExecutor::ErroredState ) ;
448 _OutNode->State( GraphExecutor::ErroredState ) ;
457 // cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
461 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
462 ThreadNo ( aThread ) ;
464 _OutNode->NewThread() ;
466 void GraphExecutor::InNode::ExitThread() {
468 _OutNode->ExitThread() ;
471 bool GraphExecutor::InNode::Suspend() {
472 cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
473 << " " << Automaton()->StateName( State() ) << endl;
474 bool RetVal = false ;
476 //If loop we need to suspend also ControlState( SUPERV::VoidState ) ;
477 ControlState( SUPERV::ToSuspendState ) ;
479 if ( _OutNode->IsDone() ) {
480 ControlState( SUPERV::VoidState ) ;
484 else if ( IsWaiting() || IsReady() ) {
485 ControlState( SUPERV::ToSuspendState ) ;
488 else if ( IsRunning() ) {
489 ControlState( SUPERV::ToSuspendState ) ;
490 if ( IsFactoryNode() || IsComputingNode() ) {
491 // We have to suspend in the container of that node
492 int TrySuspend = 10 ;
493 while ( TrySuspend ) {
494 if ( !CORBA::is_nil( Component() ) ) {
495 // We can call that component
497 RetVal = Component()->Suspend_impl() ;
500 cdebug << "InNode::Suspend() ERROR catched" << endl ;
501 State( GraphExecutor::ErroredState ) ;
502 _OutNode->State( GraphExecutor::ErroredState ) ;
506 cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
509 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
510 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
511 SendEvent( GraphExecutor::SuspendEvent ) ;
512 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
513 << Name() << " --> thread" << ThreadNo() << endl;
516 else if ( IsDone() ) {
517 ControlState( SUPERV::VoidState ) ;
518 RetVal = false ; // Too late ...
522 cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
524 MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
529 // Suspend in the Container failed : it is always false if it is a Python Container
530 cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
532 if ( TrySuspend == 1 ) {
533 if ( IsSuspended() ) {
543 cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
545 // Wait for the end of loading of the component
546 while ( IsLoading() ) {
549 if ( TrySuspend == 1 ) {
550 if ( IsSuspended() ) {
564 else if ( IsMacroNode() ) {
565 // It should be like that but it is not completely implemented
566 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
567 RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
569 State( GraphExecutor::SuspendedState ) ;
573 // Now we can suspend an InLineNode with the handler of the SuperVision Container
574 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
575 State( GraphExecutor::ErroredState ) ;
576 _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false;
577 cdebug << "Suspend of InLine nodes is NOT implemented." << endl;
578 MESSAGE( "Suspend of InLine nodes is NOT implemented." );
580 if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
581 perror("Suspend pthread_kill error") ;
582 State( GraphExecutor::ErroredState ) ;
583 _OutNode->State( GraphExecutor::ErroredState ) ;
591 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
592 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
593 SendEvent( GraphExecutor::SuspendEvent ) ;
594 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
595 << Name() << " --> thread" << ThreadNo() << endl;
597 else if ( IsDone() ) {
598 ControlState( SUPERV::VoidState ) ;
599 RetVal = false ; // Too late ...
602 cdebug << "component Suspended and !IsDone and !IsRunning !"
610 cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
611 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
615 cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
616 << Automaton()->StateName( State() ) << endl ;
620 bool GraphExecutor::InNode::ContainerKill() {
621 cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
622 << ThreadNo() << endl;
624 if ( IsFactoryNode() ) {
626 RetVal = Container()->Kill_impl() ;
628 cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
632 bool GraphExecutor::InNode::Kill() {
633 cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
634 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
635 << " SuspendedThreads " << _OutNode->SuspendedThreads()
636 << " EventQSize " << _OutNode->EventQSize() << endl;
639 ControlState( SUPERV::ToKillState ) ; // if loop
640 if ( _OutNode->IsDone() ) {
641 ControlState( SUPERV::VoidState ) ;
646 ControlState( SUPERV::ToKillState ) ;
648 if ( _OutNode->IsDone() ) {
649 ControlState( SUPERV::VoidState ) ;
655 if ( IsFactoryNode() || IsComputingNode() ) {
656 // We have to suspend in the container of that node
659 if ( !CORBA::is_nil( Component() ) ) {
660 // We can call that component
662 RetVal = Component()->Kill_impl() ;
665 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
666 State( GraphExecutor::ErroredState ) ;
667 _OutNode->State( GraphExecutor::ErroredState ) ;
671 cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
674 cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
675 << " --> thread" << ThreadNo() << " KillEvent " << endl;
676 SendEvent( GraphExecutor::KillEvent ) ;
677 cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
678 << Name() << " --> thread" << ThreadNo() << endl;
681 else if ( IsDone() ) {
682 ControlState( SUPERV::VoidState ) ;
683 RetVal = false ; // Too late ...
687 cdebug << "Kill component Killed and !IsDone and !IsRunning !"
693 // Kill in the Container failed : it is always false if it is a Python Container
694 cdebug << "InNode::Suspend cannot Kill component ! Python Component ?"
696 if ( TryKill == 1 ) {
707 cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
709 // Wait for the end of loading of the component
710 while ( IsLoading() ) {
713 if ( TryKill == 1 ) {
728 else if ( IsMacroNode() ) {
729 // It should be like that but it is not completely implemented
730 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
731 RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
733 State( GraphExecutor::KilledState ) ;
738 // Now we can kill an InLineNode with the handler of the SuperVision Container
739 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
740 State( GraphExecutor::ErroredState ) ;
741 _OutNode->State( GraphExecutor::ErroredState ) ;
743 cdebug << "Kill of InLine nodes is NOT implemented." << endl;
744 MESSAGE( "Kill of InLine nodes is NOT implemented." );
746 cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
747 << _OutNode->MainThreadId() << " :" << endl ;
748 MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
749 << _OutNode->MainThreadId() << " :" ) ;
750 if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
751 // python signals run only in main thread ...
752 perror("Kill pthread_kill error") ;
753 State( GraphExecutor::ErroredState ) ;
754 _OutNode->State( GraphExecutor::ErroredState ) ;
758 cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
759 << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
760 MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
761 << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
767 else if ( IsSuspended() ) {
768 cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
769 << " --> thread" << ThreadNo() << " Resume()" << endl;
777 else if ( IsWaiting() ) {
780 else if ( IsReady() ) {
784 cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
785 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
792 // JR 24.03.2005 Debug it may have be killed if we have Suspend-Resume-Kill
793 if ( !RetVal && IsKilled() ) {
796 cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
797 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
798 << " SuspendedThreads " << _OutNode->SuspendedThreads()
799 << " EventQSize " << _OutNode->EventQSize() << " returns " << RetVal << endl ;
803 bool GraphExecutor::InNode::KillDone() {
804 cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
807 if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
811 ControlState( SUPERV::ToKillDoneState ) ;
813 if ( _OutNode->IsDone() ) {
814 ControlState( SUPERV::VoidState ) ;
822 else if ( IsWaiting() ) {
826 cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
832 cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
836 bool GraphExecutor::InNode::Stop() {
837 cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
840 if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
844 ControlState( SUPERV::ToStopState ) ;
846 if ( _OutNode->IsDone() ) {
847 ControlState( SUPERV::VoidState ) ;
853 if ( IsFactoryNode() || IsComputingNode() ) {
854 if ( !CORBA::is_nil( Component() ) ) {
856 RetVal = Component()->Stop_impl() ;
859 cdebug << "InNode::Stop() ERROR catched" << endl ;
860 State( GraphExecutor::ErroredState ) ;
861 _OutNode->State( GraphExecutor::ErroredState ) ;
866 SendEvent( GraphExecutor::StopEvent ) ;
868 else if ( IsDone() ) {
869 ControlState( SUPERV::VoidState ) ;
870 RetVal = false ; // Too late ...
873 cdebug << "component Suspended and !IsDone and !IsRunning !"
879 cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
884 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
888 else if ( IsWaiting() ) {
892 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
898 cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
902 bool GraphExecutor::InNode::SuspendDone() {
903 cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
904 << ThreadNo() << endl;
906 if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
910 ControlState( SUPERV::ToSuspendDoneState ) ;
912 if ( _OutNode->IsDone() ) {
913 ControlState( SUPERV::VoidState ) ;
921 cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
925 bool GraphExecutor::InNode::Resume() {
926 cdebug_in << pthread_self() << "/" << ThreadNo()
927 << " GraphExecutor::InNode::Resume " << Name() << " "
928 << Automaton()->StateName( State() ) << endl;
929 bool RetVal = false ;
930 if ( IsSuspended() ) {
931 if ( State() == GraphExecutor::SuspendedReadyState ) {
932 ResumeAction( GraphExecutor::ToResumeEvent ) ;
935 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
936 if ( IsFactoryNode() || IsComputingNode() ) {
937 if ( pthread_mutex_lock( &_MutexWait ) ) {
938 perror("ResumeAction pthread_mutex_lock ") ;
942 RetVal = Component()->Resume_impl() ;
944 State( GraphExecutor::ExecutingState ) ;
948 cdebug << "InNode::Resume() ERROR catched" << endl ;
949 State( GraphExecutor::ErroredState ) ;
950 _OutNode->State( GraphExecutor::ErroredState ) ;
953 if ( pthread_mutex_unlock( &_MutexWait ) ) {
954 perror("ResumeAction pthread_mutex_unlock ") ;
958 else if ( IsMacroNode() ) {
959 cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
960 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
961 RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
963 State( GraphExecutor::ExecutingState ) ;
967 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
968 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
969 State( GraphExecutor::ErroredState ) ;
970 _OutNode->State( GraphExecutor::ErroredState ) ;
972 cdebug << "Resume of InLine nodes is NOT implemented." << endl;
973 MESSAGE( "Resume of InLine nodes is NOT implemented." );
975 cdebug << ThreadNo() << "/" << pthread_self()
976 << "Resume of InLineNode pthread_kill" << Name() << endl ;
977 if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
978 perror("Resume pthread_kill error") ;
979 State( GraphExecutor::ErroredState ) ;
980 _OutNode->State( GraphExecutor::ErroredState ) ;
984 State( GraphExecutor::ExecutingState ) ;
990 else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
991 ResumeAction( GraphExecutor::ResumeEvent ) ;
994 else if ( State() == GraphExecutor::SuspendedErroredState ) {
995 ResumeAction( GraphExecutor::ResumeEvent ) ;
999 cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
1000 << Automaton()->StateName( State() ) << endl ;
1005 cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
1006 << Automaton()->StateName( State() ) << endl ;
1009 if ( ControlState() == SUPERV::ToSuspendStartState ) {
1010 ControlState( SUPERV::VoidState ) ;
1014 if ( ControlState() == SUPERV::ToSuspendRunState ||
1015 ( ControlState() == SUPERV::ToSuspendState &&
1016 State() == GraphExecutor::SuspendedReadyState) ) {
1017 if ( IsSuspended() ) {
1018 if ( State() == GraphExecutor::SuspendedReadyState ) {
1022 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
1024 RetVal = Component()->Resume_impl() ;
1027 cdebug << "GraphExecutor::InNode::Resume State "
1028 << Automaton()->StateName( State() ) << endl ;
1031 if ( ControlState() != SUPERV::ToSuspendState ) {
1032 ControlState( SUPERV::VoidState ) ;
1035 else if ( IsRunning() ) {
1038 else if ( IsWaiting() ) {
1039 ControlState( SUPERV::VoidState ) ;
1042 else if ( IsDone() ) {
1046 else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1047 ( ControlState() == SUPERV::ToSuspendState &&
1048 State() == GraphExecutor::SuspendedSuccessedState) ) {
1049 if ( IsSuspended() ) {
1050 if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1054 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1059 cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1062 if ( ControlState() != SUPERV::ToSuspendState ) {
1063 ControlState( SUPERV::VoidState ) ;
1066 else if ( IsRunning() ) {
1067 ControlState( SUPERV::VoidState ) ;
1070 else if ( IsWaiting() ) {
1071 ControlState( SUPERV::VoidState ) ;
1074 else if ( IsDone() ) {
1075 ControlState( SUPERV::VoidState ) ;
1080 cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1081 << Automaton()->StateName( State() ) << endl ;
1085 bool GraphExecutor::InNode::IsWaiting() {
1087 // cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1088 GraphExecutor::AutomatonState aState = State() ;
1089 if ( aState == GraphExecutor::DataUndefState ||
1090 aState == GraphExecutor::DataWaitingState ||
1091 aState == GraphExecutor::SuspendedReadyState )
1092 // aState == GraphExecutor::SuspendedExecutingState ||
1093 // aState == GraphExecutor::SuspendedSuccessedState ||
1094 // aState == GraphExecutor::SuspendedErroredState ||
1095 // aState == GraphExecutor::SuspendedState
1097 // cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1101 bool GraphExecutor::InNode::IsReady() {
1103 // cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1104 GraphExecutor::AutomatonState aState = State() ;
1105 // if ( aState == GraphExecutor::DataUndefState ||
1106 // aState == GraphExecutor::DataWaitingState ||
1107 if ( aState == GraphExecutor::DataReadyState ||
1108 aState == GraphExecutor::ResumedReadyState )
1110 // cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1114 bool GraphExecutor::InNode::IsRunning() {
1116 // cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1117 GraphExecutor::AutomatonState aState = State() ;
1118 if ( aState == GraphExecutor::ExecutingState ||
1119 aState == GraphExecutor::ResumedExecutingState )
1121 // cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1125 bool GraphExecutor::InNode::IsDone() {
1127 // cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1128 GraphExecutor::AutomatonState aState = State() ;
1129 if ( aState == GraphExecutor::KilledReadyState ||
1130 aState == GraphExecutor::StoppedReadyState ||
1131 aState == GraphExecutor::KilledExecutingState ||
1132 aState == GraphExecutor::StoppedExecutingState ||
1133 aState == GraphExecutor::SuspendedSuccessedState ||
1134 aState == GraphExecutor::SuspendedErroredState ||
1135 // aState == GraphExecutor::SuccessedExecutingState ||
1136 // aState == GraphExecutor::ErroredExecutingState ||
1137 aState == GraphExecutor::SuccessedState ||
1138 aState == GraphExecutor::ErroredState ||
1139 aState == GraphExecutor::ResumedSuccessedState ||
1140 aState == GraphExecutor::ResumedErroredState ||
1141 aState == GraphExecutor::KilledSuccessedState ||
1142 aState == GraphExecutor::StoppedSuccessedState )
1144 // cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1148 bool GraphExecutor::InNode::IsSuspended() {
1150 // cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1151 GraphExecutor::AutomatonState aState = State() ;
1152 if ( aState == GraphExecutor::SuspendedReadyState ||
1153 aState == GraphExecutor::SuspendedExecutingState ||
1154 aState == GraphExecutor::SuspendedSuccessedState ||
1155 aState == GraphExecutor::SuspendedErroredState ||
1156 aState == GraphExecutor::SuspendedState )
1158 // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1161 bool GraphExecutor::InNode::IsKilled() {
1163 // cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1164 GraphExecutor::AutomatonState aState = State() ;
1165 if ( aState == GraphExecutor::KilledReadyState ||
1166 aState == GraphExecutor::KilledExecutingState ||
1167 aState == GraphExecutor::KilledSuccessedState ||
1168 aState == GraphExecutor::KilledErroredState ||
1169 aState == GraphExecutor::KilledState )
1171 // cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1174 bool GraphExecutor::InNode::IsStopped() {
1176 // cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1177 GraphExecutor::AutomatonState aState = State() ;
1178 if ( aState == GraphExecutor::StoppedReadyState ||
1179 aState == GraphExecutor::StoppedExecutingState ||
1180 aState == GraphExecutor::StoppedSuccessedState ||
1181 aState == GraphExecutor::StoppedErroredState ||
1182 aState == GraphExecutor::StoppedState )
1184 // cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1188 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1189 bool RetVal = false ;
1190 if ( pthread_mutex_lock( &_MutexWait ) ) {
1191 perror("pthread_mutex_lock _Wait") ;
1195 case SUPERV::ReadyState : {
1196 RetVal = IsReady() ;
1197 cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1198 << " " << Automaton()->StateName( _currentState )
1199 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1200 while ( !RetVal && !IsDone() ) {
1201 cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1202 pthread_cond_wait( &_ReadyWait , &_MutexWait );
1203 RetVal = IsReady() ;
1204 cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1205 << Automaton()->StateName( _currentState ) << " " << RetVal
1208 cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1209 << " " << Automaton()->StateName( _currentState )
1210 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1213 case SUPERV::RunningState : {
1214 RetVal = IsRunning() ;
1215 cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1216 << " " << Automaton()->StateName( _currentState )
1217 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1218 while ( !RetVal && !IsDone() ) {
1219 cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1220 pthread_cond_wait( &_RunningWait , &_MutexWait );
1221 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1222 RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1223 State() == GraphExecutor::ErroredExecutingState ;
1224 cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1225 << Automaton()->StateName( _currentState ) << " " << RetVal
1226 << " " << Name() << endl ;
1228 cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1229 << " " << Automaton()->StateName( _currentState )
1230 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1233 case SUPERV::DoneState : {
1235 cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1236 << " " << Automaton()->StateName( _currentState )
1237 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1239 cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1240 pthread_cond_wait( &_DoneWait , &_MutexWait );
1242 cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1243 << Automaton()->StateName( _currentState ) << " " << RetVal
1246 cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1247 << " " << Automaton()->StateName( _currentState )
1248 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1251 case SUPERV::SuspendState : {
1252 RetVal = IsSuspended() ;
1253 cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1254 << " " << Automaton()->StateName( _currentState )
1255 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1256 while ( !RetVal && !IsDone() ) {
1257 cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1258 pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1259 RetVal = IsSuspended() ;
1260 cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1261 << Automaton()->StateName( _currentState ) << " " << RetVal
1264 cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1265 << " " << Automaton()->StateName( _currentState )
1266 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1270 cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1274 if ( pthread_mutex_unlock( &_MutexWait ) ) {
1275 perror("pthread_mutex_lock _Wait") ;
1281 bool GraphExecutor::InNode::ReadyWait() {
1282 // cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1284 aret = StateWait( SUPERV::ReadyState ) ;
1285 // cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1289 bool GraphExecutor::InNode::RunningWait() {
1290 cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1291 << " " << Automaton()->StateName( State() ) << endl;
1293 aret = StateWait( SUPERV::RunningState ) ;
1294 cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1295 << " " << Automaton()->StateName( State() ) << endl;
1299 bool GraphExecutor::InNode::DoneWait() {
1300 // cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1302 aret = StateWait( SUPERV::DoneState ) ;
1306 bool GraphExecutor::InNode::SuspendedWait() {
1307 // cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1309 aret = StateWait( SUPERV::SuspendState ) ;
1313 void GraphExecutor::InNode::InitialState()
1315 cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1318 _ControlState = SUPERV::VoidState ;
1319 CreateNewThread( false ) ;
1320 CreateNewThreadIf( false ) ;
1321 _SuspendSync = false ;
1322 _ResumeSync = false ;
1325 // asv : 13.12.04 : Decided to set "Loading" state for factory and computing nodes ONLY.
1326 // See extended comment in p.2.19 of "Bugs and Improvements" about IsLoading for InLine.
1327 if ( IsComputingNode() || IsFactoryNode() ) {
1331 // ThreadNo( pthread_self() ) ;
1334 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1335 if ( GetNodeOutPort(i)->IsDataStream() ) {
1336 GetChangeNodeOutPort(i)->PortState( SUPERV::ReadyState ) ;
1337 GetChangeNodeOutPort(i)->PortDone( true ) ;
1339 else if ( i != 0 || !IsGOTONode() ) {
1340 GetChangeNodeOutPort(i)->PortState( SUPERV::WaitingState ) ;
1341 GetChangeNodeOutPort(i)->PortDone( false ) ;
1345 int Pc = GetNodeInPortsSize() ;
1346 for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1347 const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1348 GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1349 if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1350 anOutPort->PortStatus( DataConnected );
1351 anOutPort->PortState( SUPERV::ReadyState ) ;
1352 anOutPort->PortDone( true ) ;
1353 //JR 21.02.2005 Debug Memory leak : CORBA::Any * anAny = new CORBA::Any() ;
1354 CORBA::Any anAny = CORBA::Any() ;
1355 //JR 21.02.2005 Debug Memory leak : *anAny <<= (long ) 1 ;
1356 anAny <<= (long ) 1 ;
1357 anOutPort->Value( anAny ) ;
1359 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1360 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1361 << " InitLoop HeadNode" << endl ;
1363 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1364 else if ( anInPort->IsGate() && anOutPort ) {
1365 anOutPort->PortState( SUPERV::WaitingState ) ;
1366 anOutPort->PortDone( false ) ;
1367 const GraphBase::ComputingNode * aFromNode = _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ;
1368 //JR if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) {
1369 if ( aFromNode->IsGOTONode() || ( IsLoopNode() && CoupledNode() == aFromNode ) ) {
1370 // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.
1371 // before was "else if ( IsOneOfInlineNodes() )"
1372 // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1373 anOutPort->PortStatus( DataConnected );
1374 anOutPort->PortState( SUPERV::ReadyState ) ;
1375 anOutPort->PortDone( true ) ;
1377 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1378 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1379 << " Gate HeadNode" << endl ;
1382 cdebug << Name() << " IsHeadNode " << IsHeadNode() << " InPort" << i << " " << anInPort->PortName()
1383 << " " << anInPort->PortStatus() << endl ;
1385 if ( anInPort->IsGate() && anOutPort == NULL ) {
1387 cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected Pc " << Pc << endl ;
1389 else if ( anOutPort ) {
1390 if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1392 anOutPort->PortState( SUPERV::ReadyState ) ;
1393 anOutPort->PortDone( true ) ;
1394 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1395 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " Pc " << Pc << endl ;
1397 else if ( anOutPort->IsPortConnected() ) {
1398 anOutPort->PortState( SUPERV::WaitingState ) ;
1399 anOutPort->PortDone( false ) ;
1400 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1401 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " Pc " << Pc << endl ;
1404 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1405 << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1406 << theAutomaton->StateName( anOutPort->PortState() ) << " Pc " << Pc << endl ;
1410 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1411 << " no corresponding OutPort Pc " << Pc << endl ;
1414 if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1415 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1416 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1417 << " with state of OutPort : " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1418 GetChangeNodeInPort(i)->PortState( anOutPort->PortState() ) ;
1420 else if ( anOutPort->IsDataConnected() ) {
1421 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1422 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1423 << " with state ReadyState" << endl ;
1424 GetChangeNodeInPort(i)->PortState( SUPERV::ReadyState ) ;
1427 cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1428 << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1429 << " with state " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1433 cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1434 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1436 if ( anOutPort->PortState() == SUPERV::WaitingState ) {
1437 cdebug << "WaitingState" ;
1439 else if ( anOutPort->PortState() == SUPERV::ReadyState ) {
1440 cdebug << "ReadyState" ;
1445 cdebug << " OutPortStatus " << anOutPort->PortStatus() << " State "
1446 << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1450 _currentState = Pc > 0 ? GraphExecutor::DataWaitingState
1451 : GraphExecutor::DataReadyState ;
1452 if ( Pc == GetNodeInPortsSize() ) {
1453 _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1456 else if ( Pc != 0 ) {
1457 _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1461 _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1465 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1466 cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1467 << theAutomaton->StateName( GetChangeNodeOutPort(i)->PortState() )
1468 << " " << GetNodeOutPort(i)->Kind() << endl ;
1471 cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1474 cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1477 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1478 cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " WithErr " << WithErr
1479 << " PyFuncRunned() " << PyFuncRunned() << endl;
1481 if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1482 if ( IsLoopNode() ) {
1483 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1484 PyObject * PyMoreMethod = NULL ;
1485 PyObject * PyNextMethod = NULL ;
1486 if ( PyRunMethod ) {
1489 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1490 InLineNode()->PythonFunction() ,
1492 InLineNode()->PyRunMethod( PyRunMethod ) ;
1495 PyMoreMethod = LoopNode()->PyMoreMethod() ;
1496 if ( PyMoreMethod ) {
1499 PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1500 LoopNode()->MorePythonFunction() ,
1502 LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1506 PyNextMethod = LoopNode()->PyNextMethod() ;
1507 if ( PyNextMethod ) {
1510 PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1511 LoopNode()->NextPythonFunction() ,
1513 LoopNode()->PyNextMethod( PyNextMethod ) ;
1516 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1517 << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1519 else if ( IsInLineNode() || IsSwitchNode() ) {
1520 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1521 if ( PyRunMethod ) {
1524 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1525 InLineNode()->PythonFunction() ,
1527 InLineNode()->PyRunMethod( PyRunMethod ) ;
1529 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1531 else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1532 (*InLineNode()->PythonFunction()).length() ) {
1533 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1534 if ( PyRunMethod ) {
1537 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1538 InLineNode()->PythonFunction() ,
1540 InLineNode()->PyRunMethod( PyRunMethod ) ;
1542 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1545 Err = WithErr && Err ;
1546 cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1548 cdebug << " Error " << Err ;
1554 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1555 CORBA::Long cpu = 0 ;
1556 // cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1557 // << theAutomaton->StateName( _currentState ) << endl ;
1558 // cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1559 if ( IsOneOfInLineNodes() ) {
1560 // cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1561 // cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1562 cpu = PyCpuUsed( tot ) ;
1565 if ( !CORBA::is_nil( Component() ) ) {
1566 // cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1567 // cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1569 cpu = Component()->CpuUsed_impl() ;
1572 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1573 State( GraphExecutor::ErroredState ) ;
1574 _OutNode->State( GraphExecutor::ErroredState ) ;
1579 // cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1580 // cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1581 // << theAutomaton->StateName( _currentState ) << endl ;
1585 #include <sys/time.h>
1586 #include <sys/resource.h>
1589 long GraphExecutor::InNode::PyCpu() {
1590 struct rusage usage ;
1592 if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1593 perror("GraphExecutor::InNode::PyCpu") ;
1596 // return usage.ru_utime.__time_t tv_sec ;
1597 // cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1598 // << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1600 cpu = usage.ru_utime.tv_sec ;
1604 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1606 if ( _PyTotCpuUsed == -1 ) {
1607 if ( _Pythread == pthread_self() ) {
1608 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1609 // << " _PyTotCpuUsed " << _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1610 // << _PyCpuUsed << endl ;
1611 cpu = PyCpu() - _PyCpuUsed ;
1613 _PyTotCpuUsed = cpu ;
1621 cpu = _PyTotCpuUsed ;
1623 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1624 // << _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1628 void GraphExecutor::InNode::SetPyCpuUsed() {
1629 _PyTotCpuUsed = -1 ;
1631 _Pythread = pthread_self() ;
1632 _PyCpuUsed = PyCpu() ;
1633 // cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1634 // << _PyCpuUsed << endl ;
1637 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1638 _Loading = Loading ;
1640 // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works:
1641 // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1642 // after Loading is finished (here below), ExecutingState must be pushed for GUI.
1644 _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );