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 &_MutexDataReady ,
63 pthread_mutex_t &_MutexWait ,
64 pthread_cond_t &_ReadyWait ,
65 pthread_cond_t &_RunningWait ,
66 pthread_cond_t &_DoneWait ,
67 pthread_cond_t &_SuspendedWait ,
68 pthread_cond_t &_SuspendWait ,
70 pthread_cond_t &_ResumeWait ,
72 pthread_cond_t &_KillWait ,
74 pthread_cond_t &_ThreadStartedWait ,
75 bool &_ThreadStartedSync ,
76 pthread_cond_t &_StopWait ,
77 GraphExecutor::FiniteStateMachine ** _Automaton ,
78 GraphExecutor::FiniteStateMachine * theAutomaton ,
79 CORBA::ORB_ptr * _Orb ,
83 _ControlState = SUPERV::VoidState ;
84 _currentState = GraphExecutor::UnKnownState ;
85 *_aReStartNode = NULL ;
86 _PyFuncRunned = false ;
87 *_MyPyRunMethod = NULL ;
88 // pthread_mutex_init( &_MutexDataWait , NULL ) ;
89 // _DataWait = false ;
90 pthread_mutex_init( &_MutexDataReady , NULL ) ;
91 pthread_mutex_init( &_MutexWait , NULL ) ;
92 if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
93 perror("pthread_cond_init( &_ReadyWait , NULL )") ;
96 if ( pthread_cond_init( &_RunningWait , NULL ) ) {
97 perror("pthread_cond_init( &_RunningWait , NULL )") ;
100 if ( pthread_cond_init( &_DoneWait , NULL ) ) {
101 perror("pthread_cond_init( &_DoneWait , NULL )") ;
104 if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
105 perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
108 if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
109 perror("pthread_cond_init( &_SuspendWait , NULL )") ;
112 _SuspendSync = false ;
113 if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
114 perror("pthread_cond_init( &_ResumeWait , NULL )") ;
117 _ResumeSync = false ;
118 if ( pthread_cond_init( &_KillWait , NULL ) ) {
119 perror("pthread_cond_init( &_KillWait , NULL )") ;
123 if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
124 perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
127 _ThreadStartedSync = false ;
128 if ( pthread_cond_init( &_StopWait , NULL ) ) {
129 perror("pthread_cond_init( &_StopWait , NULL )") ;
132 *_Automaton = theAutomaton ;
133 *_Orb = CORBA::ORB::_nil();
137 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
139 //GraphExecutor::InNode::InNode() :
140 // GraphBase::FactoryNode() {
141 GraphExecutor::InNode::InNode() {
142 InitInNode( _RewindStack ,
172 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
173 SALOME_NamingService* ptrNamingService ,
174 const SALOME_ModuleCatalog::Service& aService ,
175 const char * ComponentName ,
176 const char * NodeInterfaceName ,
177 const char * NodeName ,
178 const SUPERV::KindOfNode akind ,
179 GraphBase::ListOfFuncName aFuncName ,
180 GraphBase::ListOfPythonFunctions aPythonFunction ,
181 const SUPERV::SDate NodeFirstCreation ,
182 const SUPERV::SDate NodeLastModification ,
183 const char * NodeEditorRelease ,
184 const char * NodeAuthor ,
185 const char * NodeComputer ,
186 const char * NodeComment ,
187 const bool GeneratedName ,
190 int * Graph_prof_debug,
191 ofstream * Graph_fdebug) {
192 // ostream * Graph_fdebug = NULL ) :
193 // GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
194 // ComponentName , NodeInterfaceName ,
195 // NodeName , akind ,
196 // NodeFirstCreation , NodeLastModification ,
197 // NodeEditorRelease , NodeAuthor ,
198 // NodeComputer , NodeComment , GeneratedName ,
200 // Graph_prof_debug , Graph_fdebug ) {
201 InitInNode( _RewindStack ,
229 SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
231 _ComputingNode = NULL ;
232 _FactoryNode = NULL ;
236 _EndOfLoopNode = NULL ;
238 _EndOfSwitchNode = NULL ;
240 case SUPERV::ComputingNode : {
241 cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
242 _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
246 NodeLastModification ,
247 NodeEditorRelease , NodeAuthor ,
248 NodeComment , GeneratedName ,
250 Graph_prof_debug , Graph_fdebug ) ;
253 case SUPERV::FactoryNode : {
254 cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
255 _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
256 ComponentName , NodeInterfaceName ,
259 NodeLastModification ,
260 NodeEditorRelease , NodeAuthor ,
261 NodeComputer , NodeComment ,
262 GeneratedName , NodeX , NodeY ,
263 Graph_prof_debug , Graph_fdebug ) ;
264 _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
267 case SUPERV::InLineNode : {
268 cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
269 _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
270 aFuncName[0].c_str() , *aPythonFunction[0] ,
272 NodeFirstCreation , NodeLastModification ,
273 NodeEditorRelease , NodeAuthor ,
274 NodeComment , GeneratedName ,
276 Graph_prof_debug , Graph_fdebug ) ;
277 _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
280 case SUPERV::MacroNode : {
281 cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
282 _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
283 // aFuncName[0].c_str() , *aPythonFunction[0] ,
285 // NodeFirstCreation , NodeLastModification ,
286 // NodeEditorRelease , NodeAuthor ,
287 // NodeComment , GeneratedName ,
289 Graph_prof_debug , Graph_fdebug ) ;
290 _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
291 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
292 _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
293 _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
296 case SUPERV::GOTONode : {
297 cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
298 _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
299 aFuncName[0].c_str() , *aPythonFunction[0] ,
301 NodeFirstCreation , NodeLastModification ,
302 NodeEditorRelease , NodeAuthor ,
303 NodeComment , GeneratedName ,
305 Graph_prof_debug , Graph_fdebug ) ;
306 _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
307 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
310 case SUPERV::LoopNode : {
311 cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
312 _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
313 aFuncName[0].c_str() , *aPythonFunction[0] ,
314 aFuncName[1].c_str() , *aPythonFunction[1] ,
315 aFuncName[2].c_str() , *aPythonFunction[2] ,
317 NodeFirstCreation , NodeLastModification ,
318 NodeEditorRelease , NodeAuthor ,
319 NodeComment , GeneratedName ,
321 Graph_prof_debug , Graph_fdebug ) ;
322 _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
323 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
324 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
327 case SUPERV::EndLoopNode : {
328 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
329 _EndOfLoopNode = new GraphBase::EndOfLoopNode(
330 ORB , ptrNamingService ,
331 aFuncName[0].c_str() , *aPythonFunction[0] ,
333 NodeFirstCreation , NodeLastModification ,
334 NodeEditorRelease , NodeAuthor ,
335 NodeComment , GeneratedName ,
337 Graph_prof_debug , Graph_fdebug ) ;
338 _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
339 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
340 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
343 case SUPERV::SwitchNode : {
344 cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
345 _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
346 aFuncName[0].c_str() , *aPythonFunction[0] ,
348 NodeFirstCreation , NodeLastModification ,
349 NodeEditorRelease , NodeAuthor ,
350 NodeComment , GeneratedName ,
352 Graph_prof_debug , Graph_fdebug ) ;
353 _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
354 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
355 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
358 case SUPERV::EndSwitchNode : {
359 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
360 _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
361 ORB , ptrNamingService ,
362 aFuncName[0].c_str() , *aPythonFunction[0] ,
364 NodeFirstCreation , NodeLastModification ,
365 NodeEditorRelease , NodeAuthor ,
366 NodeComment , GeneratedName ,
368 Graph_prof_debug , Graph_fdebug ) ;
369 _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
370 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
371 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
374 case SUPERV::DataFlowGraph : {
375 cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
377 case SUPERV::DataStreamGraph : {
378 cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
380 case SUPERV::UnknownNode : {
381 cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
384 cdebug << "GraphExecutor::InNode::InNode " << (void *) this
385 << " _ComputingNode " << (void *) _ComputingNode ;
386 _ComputingNode->InNode( this ) ;
389 GraphExecutor::InNode::~InNode() {
392 //JR 15.04.2005 Debug PAL8624 RetroConception :
394 void GraphExecutor::InNode::LockDataWait() {
395 // cdebug_in << "GraphExecutor::InNode::LockDataWait " << endl ;
396 if ( pthread_mutex_lock( &_MutexDataWait ) ) {
397 perror("Ready pthread_mutex_lock ") ;
401 // cdebug_out << "GraphExecutor::InNode::LockDataWait " << endl ;
403 void GraphExecutor::InNode::UnLockDataWait() {
404 // cdebug_in << "GraphExecutor::InNode::UnLockDataWait " << endl ;
406 if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
407 perror("Ready pthread_mutex_unlock ") ;
410 // cdebug_out << "GraphExecutor::InNode::UnLockDataWait " << endl ;
414 //JR 15.04.2005 Debug PAL8624 RetroConception :
415 void GraphExecutor::InNode::LockDataReady() {
416 // cdebug_in << pthread_self() << "/" << ThreadNo()
417 // << "GraphExecutor::InNode::LockDataReady : " << Name() << " _MutexDataReadyLocked "
418 // << _MutexDataReadyLocked << " HasAllDataReady " << HasAllDataReady() << endl ;
419 if ( pthread_mutex_lock( &_MutexDataReady ) ) {
420 perror("MutexDataReady pthread_mutex_lock ") ;
423 _MutexDataReadyLocked = true ;
424 // cdebug_out << pthread_self() << "/" << ThreadNo()
425 // << "GraphExecutor::InNode::LockDataReady : " << Name() << endl ;
427 void GraphExecutor::InNode::UnLockDataReady() {
428 // cdebug_in << pthread_self() << "/" << ThreadNo()
429 // << "GraphExecutor::InNode::UnLockDataReady : " << Name() << " _MutexDataReadyLocked "
430 // << _MutexDataReadyLocked << " HasAllDataReady " << HasAllDataReady() << endl ;
431 if ( pthread_mutex_unlock( &_MutexDataReady ) ) {
432 perror("MutexDataReady pthread_mutex_unlock ") ;
435 _MutexDataReadyLocked = false ;
436 // cdebug_out << pthread_self() << "/" << ThreadNo()
437 // << "GraphExecutor::InNode::UnLockDataReady : " << Name() << endl ;
440 Engines::Component_var GraphExecutor::InNode::Component() const {
441 if ( IsFactoryNode() ) {
442 return _FactoryNode->Component() ;
445 //JR 30.03.2005 CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
446 const CORBA::Any anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
447 CORBA::Object_ptr obj ;
449 //JR 30.03.2005 *anAnyComponent >>= obj ;
450 anAnyComponent >>= obj ;
451 return Engines::Component::_narrow( obj ) ;
454 cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
457 return Engines::Component::_nil() ;
460 Engines::Container_var GraphExecutor::InNode::Container() const {
461 if ( IsFactoryNode() ) {
462 return _FactoryNode->Container() ;
464 return Engines::Container::_nil() ;
468 bool GraphExecutor::InNode::Ping() {
469 // cdebug_in << "GraphExecutor::InNode::Ping" << endl;
471 if ( IsFactoryNode() ) {
472 RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
474 if ( State() != GraphExecutor::SuspendedExecutingState ) {
476 _FactoryNode->Component()->ping() ;
479 cdebug << "InNode::Ping() ERROR catched" << endl ;
480 State( GraphExecutor::ErroredState ) ;
481 _OutNode->State( GraphExecutor::ErroredState ) ;
490 // cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
494 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
495 ThreadNo ( aThread ) ;
497 _OutNode->NewThread() ;
499 void GraphExecutor::InNode::ExitThread() {
501 _OutNode->ExitThread() ;
504 bool GraphExecutor::InNode::Suspend() {
505 cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
506 << " " << Automaton()->StateName( State() ) << endl;
507 bool RetVal = false ;
509 //If loop we need to suspend also ControlState( SUPERV::VoidState ) ;
510 ControlState( SUPERV::ToSuspendState ) ;
512 if ( _OutNode->IsDone() ) {
513 ControlState( SUPERV::VoidState ) ;
517 else if ( IsWaiting() || IsReady() ) {
518 ControlState( SUPERV::ToSuspendState ) ;
521 else if ( IsRunning() ) {
522 ControlState( SUPERV::ToSuspendState ) ;
523 if ( IsFactoryNode() || IsComputingNode() ) {
524 // We have to suspend in the container of that node
525 int TrySuspend = 10 ;
526 while ( TrySuspend ) {
527 if ( !CORBA::is_nil( Component() ) ) {
528 // We can call that component
530 RetVal = Component()->Suspend_impl() ;
533 cdebug << "InNode::Suspend() ERROR catched" << endl ;
534 State( GraphExecutor::ErroredState ) ;
535 _OutNode->State( GraphExecutor::ErroredState ) ;
539 cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
542 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
543 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
544 SendEvent( GraphExecutor::SuspendEvent ) ;
545 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
546 << Name() << " --> thread" << ThreadNo() << endl;
549 else if ( IsDone() ) {
550 ControlState( SUPERV::VoidState ) ;
551 RetVal = false ; // Too late ...
555 cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
557 MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
562 // Suspend in the Container failed : it is always false if it is a Python Container
563 cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
565 if ( TrySuspend == 1 ) {
566 if ( IsSuspended() ) {
576 cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
578 // Wait for the end of loading of the component
579 while ( IsLoading() ) {
582 if ( TrySuspend == 1 ) {
583 if ( IsSuspended() ) {
597 else if ( IsMacroNode() ) {
598 // It should be like that but it is not completely implemented
599 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
600 RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
602 State( GraphExecutor::SuspendedState ) ;
606 // Now we can suspend an InLineNode with the handler of the SuperVision Container
607 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
608 State( GraphExecutor::ErroredState ) ;
609 _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false;
610 cdebug << "Suspend of InLine nodes is NOT implemented." << endl;
611 MESSAGE( "Suspend of InLine nodes is NOT implemented." );
613 if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
614 perror("Suspend pthread_kill error") ;
615 State( GraphExecutor::ErroredState ) ;
616 _OutNode->State( GraphExecutor::ErroredState ) ;
624 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
625 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
626 SendEvent( GraphExecutor::SuspendEvent ) ;
627 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
628 << Name() << " --> thread" << ThreadNo() << endl;
630 else if ( IsDone() ) {
631 ControlState( SUPERV::VoidState ) ;
632 RetVal = false ; // Too late ...
635 cdebug << "component Suspended and !IsDone and !IsRunning !"
643 cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
644 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
648 cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
649 << Automaton()->StateName( State() ) << endl ;
653 bool GraphExecutor::InNode::ContainerKill() {
654 cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
655 << ThreadNo() << endl;
657 if ( IsFactoryNode() ) {
659 RetVal = Container()->Kill_impl() ;
661 cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
665 bool GraphExecutor::InNode::Kill() {
666 cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
667 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
668 << " SuspendedThreads " << _OutNode->SuspendedThreads()
669 << " EventQSize " << _OutNode->EventQSize() << endl;
672 ControlState( SUPERV::ToKillState ) ; // if loop
673 if ( _OutNode->IsDone() ) {
674 ControlState( SUPERV::VoidState ) ;
679 ControlState( SUPERV::ToKillState ) ;
681 if ( _OutNode->IsDone() ) {
682 ControlState( SUPERV::VoidState ) ;
688 if ( IsFactoryNode() || IsComputingNode() ) {
689 // We have to suspend in the container of that node
692 if ( !CORBA::is_nil( Component() ) ) {
693 // We can call that component
695 RetVal = Component()->Kill_impl() ;
698 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
699 State( GraphExecutor::ErroredState ) ;
700 _OutNode->State( GraphExecutor::ErroredState ) ;
704 cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
707 cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
708 << " --> thread" << ThreadNo() << " KillEvent " << endl;
709 SendEvent( GraphExecutor::KillEvent ) ;
710 cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
711 << Name() << " --> thread" << ThreadNo() << endl;
714 else if ( IsDone() ) {
715 ControlState( SUPERV::VoidState ) ;
716 RetVal = false ; // Too late ...
720 cdebug << "Kill component Killed and !IsDone and !IsRunning !"
726 // Kill in the Container failed : it is always false if it is a Python Container
727 cdebug << "InNode::Suspend cannot Kill component ! Python Component ?"
729 if ( TryKill == 1 ) {
740 cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
742 // Wait for the end of loading of the component
743 while ( IsLoading() ) {
746 if ( TryKill == 1 ) {
761 else if ( IsMacroNode() ) {
762 // It should be like that but it is not completely implemented
763 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
764 RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
766 State( GraphExecutor::KilledState ) ;
771 // Now we can kill an InLineNode with the handler of the SuperVision Container
772 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
773 State( GraphExecutor::ErroredState ) ;
774 _OutNode->State( GraphExecutor::ErroredState ) ;
776 cdebug << "Kill of InLine nodes is NOT implemented." << endl;
777 MESSAGE( "Kill of InLine nodes is NOT implemented." );
779 cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
780 << _OutNode->MainThreadId() << " :" << endl ;
781 MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
782 << _OutNode->MainThreadId() << " :" ) ;
783 if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
784 // python signals run only in main thread ...
785 perror("Kill pthread_kill error") ;
786 State( GraphExecutor::ErroredState ) ;
787 _OutNode->State( GraphExecutor::ErroredState ) ;
791 cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
792 << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
793 MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
794 << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
800 else if ( IsSuspended() ) {
801 cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
802 << " --> thread" << ThreadNo() << " Resume()" << endl;
810 else if ( IsWaiting() ) {
813 else if ( IsReady() ) {
817 cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
818 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
825 // JR 24.03.2005 Debug it may have be killed if we have Suspend-Resume-Kill
826 if ( !RetVal && IsKilled() ) {
829 cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
830 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
831 << " SuspendedThreads " << _OutNode->SuspendedThreads()
832 << " EventQSize " << _OutNode->EventQSize() << " returns " << RetVal << endl ;
836 bool GraphExecutor::InNode::KillDone() {
837 cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
840 if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
844 ControlState( SUPERV::ToKillDoneState ) ;
846 if ( _OutNode->IsDone() ) {
847 ControlState( SUPERV::VoidState ) ;
855 else if ( IsWaiting() ) {
859 cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
865 cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
869 bool GraphExecutor::InNode::Stop() {
870 cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
873 if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
877 ControlState( SUPERV::ToStopState ) ;
879 if ( _OutNode->IsDone() ) {
880 ControlState( SUPERV::VoidState ) ;
886 if ( IsFactoryNode() || IsComputingNode() ) {
887 if ( !CORBA::is_nil( Component() ) ) {
889 RetVal = Component()->Stop_impl() ;
892 cdebug << "InNode::Stop() ERROR catched" << endl ;
893 State( GraphExecutor::ErroredState ) ;
894 _OutNode->State( GraphExecutor::ErroredState ) ;
899 SendEvent( GraphExecutor::StopEvent ) ;
901 else if ( IsDone() ) {
902 ControlState( SUPERV::VoidState ) ;
903 RetVal = false ; // Too late ...
906 cdebug << "component Suspended and !IsDone and !IsRunning !"
912 cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
917 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
921 else if ( IsWaiting() ) {
925 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
931 cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
935 bool GraphExecutor::InNode::SuspendDone() {
936 cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
937 << ThreadNo() << endl;
939 if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
943 ControlState( SUPERV::ToSuspendDoneState ) ;
945 if ( _OutNode->IsDone() ) {
946 ControlState( SUPERV::VoidState ) ;
954 cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
958 bool GraphExecutor::InNode::Resume() {
959 cdebug_in << pthread_self() << "/" << ThreadNo()
960 << " GraphExecutor::InNode::Resume " << Name() << " "
961 << Automaton()->StateName( State() ) << endl;
962 bool RetVal = false ;
963 if ( IsSuspended() ) {
964 if ( State() == GraphExecutor::SuspendedReadyState ) {
965 ResumeAction( GraphExecutor::ToResumeEvent ) ;
968 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
969 if ( IsFactoryNode() || IsComputingNode() ) {
970 if ( pthread_mutex_lock( &_MutexWait ) ) {
971 perror("ResumeAction pthread_mutex_lock ") ;
975 RetVal = Component()->Resume_impl() ;
977 State( GraphExecutor::ExecutingState ) ;
981 cdebug << "InNode::Resume() ERROR catched" << endl ;
982 State( GraphExecutor::ErroredState ) ;
983 _OutNode->State( GraphExecutor::ErroredState ) ;
986 if ( pthread_mutex_unlock( &_MutexWait ) ) {
987 perror("ResumeAction pthread_mutex_unlock ") ;
991 else if ( IsMacroNode() ) {
992 cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
993 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
994 RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
996 State( GraphExecutor::ExecutingState ) ;
1000 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
1001 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
1002 State( GraphExecutor::ErroredState ) ;
1003 _OutNode->State( GraphExecutor::ErroredState ) ;
1005 cdebug << "Resume of InLine nodes is NOT implemented." << endl;
1006 MESSAGE( "Resume of InLine nodes is NOT implemented." );
1008 cdebug << ThreadNo() << "/" << pthread_self()
1009 << "Resume of InLineNode pthread_kill" << Name() << endl ;
1010 if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
1011 perror("Resume pthread_kill error") ;
1012 State( GraphExecutor::ErroredState ) ;
1013 _OutNode->State( GraphExecutor::ErroredState ) ;
1017 State( GraphExecutor::ExecutingState ) ;
1023 else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1024 ResumeAction( GraphExecutor::ResumeEvent ) ;
1027 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1028 ResumeAction( GraphExecutor::ResumeEvent ) ;
1032 cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
1033 << Automaton()->StateName( State() ) << endl ;
1038 cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
1039 << Automaton()->StateName( State() ) << endl ;
1042 if ( ControlState() == SUPERV::ToSuspendStartState ) {
1043 ControlState( SUPERV::VoidState ) ;
1047 if ( ControlState() == SUPERV::ToSuspendRunState ||
1048 ( ControlState() == SUPERV::ToSuspendState &&
1049 State() == GraphExecutor::SuspendedReadyState) ) {
1050 if ( IsSuspended() ) {
1051 if ( State() == GraphExecutor::SuspendedReadyState ) {
1055 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
1057 RetVal = Component()->Resume_impl() ;
1060 cdebug << "GraphExecutor::InNode::Resume State "
1061 << Automaton()->StateName( State() ) << endl ;
1064 if ( ControlState() != SUPERV::ToSuspendState ) {
1065 ControlState( SUPERV::VoidState ) ;
1068 else if ( IsRunning() ) {
1071 else if ( IsWaiting() ) {
1072 ControlState( SUPERV::VoidState ) ;
1075 else if ( IsDone() ) {
1079 else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1080 ( ControlState() == SUPERV::ToSuspendState &&
1081 State() == GraphExecutor::SuspendedSuccessedState) ) {
1082 if ( IsSuspended() ) {
1083 if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1087 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1092 cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1095 if ( ControlState() != SUPERV::ToSuspendState ) {
1096 ControlState( SUPERV::VoidState ) ;
1099 else if ( IsRunning() ) {
1100 ControlState( SUPERV::VoidState ) ;
1103 else if ( IsWaiting() ) {
1104 ControlState( SUPERV::VoidState ) ;
1107 else if ( IsDone() ) {
1108 ControlState( SUPERV::VoidState ) ;
1113 cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1114 << Automaton()->StateName( State() ) << endl ;
1118 bool GraphExecutor::InNode::IsWaiting() {
1120 // cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1121 GraphExecutor::AutomatonState aState = State() ;
1122 if ( aState == GraphExecutor::DataUndefState ||
1123 aState == GraphExecutor::DataWaitingState ||
1124 aState == GraphExecutor::SuspendedReadyState )
1125 // aState == GraphExecutor::SuspendedExecutingState ||
1126 // aState == GraphExecutor::SuspendedSuccessedState ||
1127 // aState == GraphExecutor::SuspendedErroredState ||
1128 // aState == GraphExecutor::SuspendedState
1130 // cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1134 bool GraphExecutor::InNode::IsReady() {
1136 // cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1137 GraphExecutor::AutomatonState aState = State() ;
1138 // if ( aState == GraphExecutor::DataUndefState ||
1139 // aState == GraphExecutor::DataWaitingState ||
1140 if ( aState == GraphExecutor::DataReadyState ||
1141 aState == GraphExecutor::ResumedReadyState )
1143 // cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1147 bool GraphExecutor::InNode::IsRunning() {
1149 // cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1150 GraphExecutor::AutomatonState aState = State() ;
1151 if ( aState == GraphExecutor::ExecutingState ||
1152 aState == GraphExecutor::ResumedExecutingState )
1154 // cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1158 bool GraphExecutor::InNode::IsDone() {
1160 // cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1161 GraphExecutor::AutomatonState aState = State() ;
1162 if ( aState == GraphExecutor::KilledReadyState ||
1163 aState == GraphExecutor::StoppedReadyState ||
1164 aState == GraphExecutor::KilledExecutingState ||
1165 aState == GraphExecutor::StoppedExecutingState ||
1166 aState == GraphExecutor::SuspendedSuccessedState ||
1167 aState == GraphExecutor::SuspendedErroredState ||
1168 // aState == GraphExecutor::SuccessedExecutingState ||
1169 // aState == GraphExecutor::ErroredExecutingState ||
1170 aState == GraphExecutor::SuccessedState ||
1171 aState == GraphExecutor::ErroredState ||
1172 aState == GraphExecutor::ResumedSuccessedState ||
1173 aState == GraphExecutor::ResumedErroredState ||
1174 aState == GraphExecutor::KilledSuccessedState ||
1175 aState == GraphExecutor::StoppedSuccessedState )
1177 // cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1181 bool GraphExecutor::InNode::IsSuspended() {
1183 // cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1184 GraphExecutor::AutomatonState aState = State() ;
1185 if ( aState == GraphExecutor::SuspendedReadyState ||
1186 aState == GraphExecutor::SuspendedExecutingState ||
1187 aState == GraphExecutor::SuspendedSuccessedState ||
1188 aState == GraphExecutor::SuspendedErroredState ||
1189 aState == GraphExecutor::SuspendedState )
1191 // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1194 bool GraphExecutor::InNode::IsKilled() {
1196 // cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1197 GraphExecutor::AutomatonState aState = State() ;
1198 if ( aState == GraphExecutor::KilledReadyState ||
1199 aState == GraphExecutor::KilledExecutingState ||
1200 aState == GraphExecutor::KilledSuccessedState ||
1201 aState == GraphExecutor::KilledErroredState ||
1202 aState == GraphExecutor::KilledState )
1204 // cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1207 bool GraphExecutor::InNode::IsStopped() {
1209 // cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1210 GraphExecutor::AutomatonState aState = State() ;
1211 if ( aState == GraphExecutor::StoppedReadyState ||
1212 aState == GraphExecutor::StoppedExecutingState ||
1213 aState == GraphExecutor::StoppedSuccessedState ||
1214 aState == GraphExecutor::StoppedErroredState ||
1215 aState == GraphExecutor::StoppedState )
1217 // cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1221 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1222 bool RetVal = false ;
1223 if ( pthread_mutex_lock( &_MutexWait ) ) {
1224 perror("pthread_mutex_lock _Wait") ;
1228 case SUPERV::ReadyState : {
1229 RetVal = IsReady() ;
1230 cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1231 << " " << Automaton()->StateName( _currentState )
1232 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1233 while ( !RetVal && !IsDone() ) {
1234 cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1235 pthread_cond_wait( &_ReadyWait , &_MutexWait );
1236 RetVal = IsReady() ;
1237 cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1238 << Automaton()->StateName( _currentState ) << " " << RetVal
1241 cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1242 << " " << Automaton()->StateName( _currentState )
1243 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1246 case SUPERV::RunningState : {
1247 RetVal = IsRunning() ;
1248 cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1249 << " " << Automaton()->StateName( _currentState )
1250 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1251 while ( !RetVal && !IsDone() ) {
1252 cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1253 pthread_cond_wait( &_RunningWait , &_MutexWait );
1254 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1255 RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1256 State() == GraphExecutor::ErroredExecutingState ;
1257 cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1258 << Automaton()->StateName( _currentState ) << " " << RetVal
1259 << " " << Name() << endl ;
1261 cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1262 << " " << Automaton()->StateName( _currentState )
1263 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1266 case SUPERV::DoneState : {
1268 cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1269 << " " << Automaton()->StateName( _currentState )
1270 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1272 cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1273 pthread_cond_wait( &_DoneWait , &_MutexWait );
1275 cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1276 << Automaton()->StateName( _currentState ) << " " << RetVal
1279 cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1280 << " " << Automaton()->StateName( _currentState )
1281 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1284 case SUPERV::SuspendState : {
1285 RetVal = IsSuspended() ;
1286 cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1287 << " " << Automaton()->StateName( _currentState )
1288 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1289 while ( !RetVal && !IsDone() ) {
1290 cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1291 pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1292 RetVal = IsSuspended() ;
1293 cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1294 << Automaton()->StateName( _currentState ) << " " << RetVal
1297 cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1298 << " " << Automaton()->StateName( _currentState )
1299 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1303 cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1307 if ( pthread_mutex_unlock( &_MutexWait ) ) {
1308 perror("pthread_mutex_lock _Wait") ;
1314 bool GraphExecutor::InNode::ReadyWait() {
1315 // cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1317 aret = StateWait( SUPERV::ReadyState ) ;
1318 // cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1322 bool GraphExecutor::InNode::RunningWait() {
1323 cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1324 << " " << Automaton()->StateName( State() ) << endl;
1326 aret = StateWait( SUPERV::RunningState ) ;
1327 cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1328 << " " << Automaton()->StateName( State() ) << endl;
1332 bool GraphExecutor::InNode::DoneWait() {
1333 // cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1335 aret = StateWait( SUPERV::DoneState ) ;
1339 bool GraphExecutor::InNode::SuspendedWait() {
1340 // cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1342 aret = StateWait( SUPERV::SuspendState ) ;
1346 void GraphExecutor::InNode::InitialState()
1348 cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1351 _ControlState = SUPERV::VoidState ;
1352 CreateNewThread( false ) ;
1353 //JR 15.04.2005 Debug PAL8624 RetroConception :
1354 // CreateNewThreadIf( false ) ;
1355 HasAllDataReady( false ) ;
1356 _SuspendSync = false ;
1357 _ResumeSync = false ;
1360 // asv : 13.12.04 : Decided to set "Loading" state for factory and computing nodes ONLY.
1361 // See extended comment in p.2.19 of "Bugs and Improvements" about IsLoading for InLine.
1362 if ( IsComputingNode() || IsFactoryNode() ) {
1366 // ThreadNo( pthread_self() ) ;
1369 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1370 if ( GetNodeOutPort(i)->IsDataStream() ) {
1371 GetChangeNodeOutPort(i)->PortState( SUPERV::ReadyState ) ;
1372 GetChangeNodeOutPort(i)->PortDone( true ) ;
1374 else if ( i != 0 || !IsGOTONode() ) {
1375 GetChangeNodeOutPort(i)->PortState( SUPERV::WaitingState ) ;
1376 GetChangeNodeOutPort(i)->PortDone( false ) ;
1380 int InPortsCount = GetNodeInPortsSize() ;
1381 for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1382 const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1383 GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1384 if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1385 anOutPort->PortStatus( DataConnected );
1386 anOutPort->PortState( SUPERV::ReadyState ) ;
1387 anOutPort->PortDone( true ) ;
1388 //JR 21.02.2005 Debug Memory leak : CORBA::Any * anAny = new CORBA::Any() ;
1389 CORBA::Any anAny = CORBA::Any() ;
1390 //JR 21.02.2005 Debug Memory leak : *anAny <<= (long ) 1 ;
1391 anAny <<= (long ) 1 ;
1392 anOutPort->SetValue( anAny ) ;
1394 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1395 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1396 << " InitLoop HeadNode" << endl ;
1398 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1399 else if ( anInPort->IsGate() && anOutPort ) {
1400 anOutPort->PortState( SUPERV::WaitingState ) ;
1401 anOutPort->PortDone( false ) ;
1402 const GraphBase::ComputingNode * aFromNode = _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ;
1403 //JR if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) {
1404 if ( aFromNode->IsGOTONode() || ( IsLoopNode() && CoupledNode() == aFromNode ) ) {
1405 // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.
1406 // before was "else if ( IsOneOfInlineNodes() )"
1407 // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1408 anOutPort->PortStatus( DataConnected );
1409 anOutPort->PortState( SUPERV::ReadyState ) ;
1410 anOutPort->PortDone( true ) ;
1412 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1413 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1414 << " Gate HeadNode" << endl ;
1417 cdebug << Name() << " IsHeadNode " << IsHeadNode() << " InPort" << i << " "
1418 << anInPort->PortName() << " " << anInPort->PortStatus() << endl ;
1420 if ( anInPort->IsGate() && anOutPort == NULL ) {
1422 cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected InPortsCount "
1423 << InPortsCount << endl ;
1425 else if ( anOutPort ) {
1426 if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1428 anOutPort->PortState( SUPERV::ReadyState ) ;
1429 anOutPort->PortDone( true ) ;
1430 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1431 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1432 << InPortsCount << endl ;
1434 else if ( anOutPort->IsPortConnected() ) {
1435 anOutPort->PortState( SUPERV::WaitingState ) ;
1436 anOutPort->PortDone( false ) ;
1437 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " "
1438 << anInPort->PortStatus()
1439 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1440 << InPortsCount << endl ;
1443 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1444 << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1445 << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1446 << InPortsCount << endl ;
1450 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1451 << " no corresponding OutPort InPortsCount " << InPortsCount << endl ;
1454 if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1455 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1456 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1457 << " with state of OutPort : " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1458 GetChangeNodeInPort(i)->PortState( anOutPort->PortState() ) ;
1460 else if ( anOutPort->IsDataConnected() ) {
1461 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1462 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1463 << " with state ReadyState" << endl ;
1464 GetChangeNodeInPort(i)->PortState( SUPERV::ReadyState ) ;
1467 cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1468 << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1469 << " with state " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1473 cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1474 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1476 if ( anOutPort->PortState() == SUPERV::WaitingState ) {
1477 cdebug << "WaitingState" ;
1479 else if ( anOutPort->PortState() == SUPERV::ReadyState ) {
1480 cdebug << "ReadyState" ;
1485 cdebug << " OutPortStatus " << anOutPort->PortStatus() << " State "
1486 << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1490 _currentState = InPortsCount > 0 ? GraphExecutor::DataWaitingState
1491 : GraphExecutor::DataReadyState ;
1492 if ( InPortsCount == GetNodeInPortsSize() ) {
1493 _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1496 else if ( InPortsCount != 0 ) {
1497 _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1501 _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1505 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1506 cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1507 << theAutomaton->StateName( GetChangeNodeOutPort(i)->PortState() )
1508 << " " << GetNodeOutPort(i)->Kind() << endl ;
1511 cdebug_out << "GraphExecutor::InNode::InitialState Node " << Name() << " CurrentState = "
1512 << theAutomaton->StateName( _currentState ) << " HasAllDataReady "
1513 << HasAllDataReady() << endl;
1516 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1517 cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " WithErr " << WithErr
1518 << " PyFuncRunned() " << PyFuncRunned() << endl;
1520 if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1521 if ( IsLoopNode() ) {
1522 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1523 PyObject * PyMoreMethod = NULL ;
1524 PyObject * PyNextMethod = NULL ;
1525 if ( PyRunMethod ) {
1528 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1529 InLineNode()->PythonFunction() ,
1531 InLineNode()->PyRunMethod( PyRunMethod ) ;
1534 PyMoreMethod = LoopNode()->PyMoreMethod() ;
1535 if ( PyMoreMethod ) {
1538 PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1539 LoopNode()->MorePythonFunction() ,
1541 LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1545 PyNextMethod = LoopNode()->PyNextMethod() ;
1546 if ( PyNextMethod ) {
1549 PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1550 LoopNode()->NextPythonFunction() ,
1552 LoopNode()->PyNextMethod( PyNextMethod ) ;
1555 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1556 << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1558 else if ( IsInLineNode() || IsSwitchNode() ) {
1559 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1560 if ( PyRunMethod ) {
1563 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1564 InLineNode()->PythonFunction() ,
1566 InLineNode()->PyRunMethod( PyRunMethod ) ;
1568 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1570 else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1571 (*InLineNode()->PythonFunction()).length() ) {
1572 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1573 if ( PyRunMethod ) {
1576 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1577 InLineNode()->PythonFunction() ,
1579 InLineNode()->PyRunMethod( PyRunMethod ) ;
1581 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1584 Err = WithErr && Err ;
1585 cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1587 cdebug << " Error " << Err ;
1593 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1594 CORBA::Long cpu = 0 ;
1595 // cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1596 // << theAutomaton->StateName( _currentState ) << endl ;
1597 // cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1598 if ( IsOneOfInLineNodes() ) {
1599 // cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1600 // cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1601 cpu = PyCpuUsed( tot ) ;
1604 if ( !CORBA::is_nil( Component() ) ) {
1605 // cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1606 // cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1608 cpu = Component()->CpuUsed_impl() ;
1611 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1612 State( GraphExecutor::ErroredState ) ;
1613 _OutNode->State( GraphExecutor::ErroredState ) ;
1618 // cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1619 // cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1620 // << theAutomaton->StateName( _currentState ) << endl ;
1624 #include <sys/time.h>
1625 #include <sys/resource.h>
1628 long GraphExecutor::InNode::PyCpu() {
1629 struct rusage usage ;
1631 if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1632 perror("GraphExecutor::InNode::PyCpu") ;
1635 // return usage.ru_utime.__time_t tv_sec ;
1636 // cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1637 // << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1639 cpu = usage.ru_utime.tv_sec ;
1643 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1645 if ( _PyTotCpuUsed == -1 ) {
1646 if ( _Pythread == pthread_self() ) {
1647 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1648 // << " _PyTotCpuUsed " << _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1649 // << _PyCpuUsed << endl ;
1650 cpu = PyCpu() - _PyCpuUsed ;
1652 _PyTotCpuUsed = cpu ;
1660 cpu = _PyTotCpuUsed ;
1662 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1663 // << _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1667 void GraphExecutor::InNode::SetPyCpuUsed() {
1668 _PyTotCpuUsed = -1 ;
1670 _Pythread = pthread_self() ;
1671 _PyCpuUsed = PyCpu() ;
1672 // cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1673 // << _PyCpuUsed << endl ;
1676 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1677 _Loading = Loading ;
1679 // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works:
1680 // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1681 // after Loading is finished (here below), ExecutingState must be pushed for GUI.
1683 _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );