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 << "GraphExecutor::InNode::Ping Component ObjRef is NIL" << endl;
493 cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
497 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
498 ThreadNo ( aThread ) ;
500 _OutNode->NewThread() ;
502 void GraphExecutor::InNode::ExitThread() {
504 _OutNode->ExitThread() ;
507 bool GraphExecutor::InNode::Suspend() {
508 cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
509 << " " << Automaton()->StateName( State() ) << endl;
510 bool RetVal = false ;
512 //If loop we need to suspend also ControlState( SUPERV::VoidState ) ;
513 ControlState( SUPERV::ToSuspendState ) ;
515 if ( _OutNode->IsDone() ) {
516 ControlState( SUPERV::VoidState ) ;
520 else if ( IsWaiting() || IsReady() ) {
521 ControlState( SUPERV::ToSuspendState ) ;
524 else if ( IsRunning() ) {
525 ControlState( SUPERV::ToSuspendState ) ;
526 if ( IsFactoryNode() || IsComputingNode() ) {
527 // We have to suspend in the container of that node
528 int TrySuspend = 10 ;
529 while ( TrySuspend ) {
530 if ( !CORBA::is_nil( Component() ) ) {
531 // We can call that component
533 RetVal = Component()->Suspend_impl() ;
536 cdebug << "InNode::Suspend() ERROR catched" << endl ;
537 State( GraphExecutor::ErroredState ) ;
538 _OutNode->State( GraphExecutor::ErroredState ) ;
542 cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
545 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
546 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
547 SendEvent( GraphExecutor::SuspendEvent ) ;
548 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
549 << Name() << " --> thread" << ThreadNo() << endl;
552 else if ( IsDone() ) {
553 ControlState( SUPERV::VoidState ) ;
554 RetVal = false ; // Too late ...
558 cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
560 MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
565 // Suspend in the Container failed : it is always false if it is a Python Container
566 cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
568 if ( TrySuspend == 1 ) {
569 if ( IsSuspended() ) {
579 cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
581 // Wait for the end of loading of the component
582 while ( IsLoading() ) {
585 if ( TrySuspend == 1 ) {
586 if ( IsSuspended() ) {
600 else if ( IsMacroNode() ) {
601 // It should be like that but it is not completely implemented
602 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
603 RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
605 State( GraphExecutor::SuspendedState ) ;
609 // Now we can suspend an InLineNode with the handler of the SuperVision Container
610 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
611 State( GraphExecutor::ErroredState ) ;
612 _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false;
613 cdebug << "Suspend of InLine nodes is NOT implemented." << endl;
614 MESSAGE( "Suspend of InLine nodes is NOT implemented." );
616 if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
617 perror("Suspend pthread_kill error") ;
618 State( GraphExecutor::ErroredState ) ;
619 _OutNode->State( GraphExecutor::ErroredState ) ;
627 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
628 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
629 SendEvent( GraphExecutor::SuspendEvent ) ;
630 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
631 << Name() << " --> thread" << ThreadNo() << endl;
633 else if ( IsDone() ) {
634 ControlState( SUPERV::VoidState ) ;
635 RetVal = false ; // Too late ...
638 cdebug << "component Suspended and !IsDone and !IsRunning !"
646 cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
647 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
651 cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
652 << Automaton()->StateName( State() ) << endl ;
656 bool GraphExecutor::InNode::ContainerKill() {
657 cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
658 << ThreadNo() << endl;
660 if ( IsFactoryNode() ) {
662 RetVal = Container()->Kill_impl() ;
664 cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
668 bool GraphExecutor::InNode::Kill() {
669 cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
670 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
671 << " SuspendedThreads " << _OutNode->SuspendedThreads()
672 << " EventQSize " << _OutNode->EventQSize() << endl;
675 ControlState( SUPERV::ToKillState ) ; // if loop
676 if ( _OutNode->IsDone() ) {
677 ControlState( SUPERV::VoidState ) ;
682 ControlState( SUPERV::ToKillState ) ;
684 if ( _OutNode->IsDone() ) {
685 ControlState( SUPERV::VoidState ) ;
691 if ( IsFactoryNode() || IsComputingNode() ) {
692 // We have to suspend in the container of that node
695 if ( !CORBA::is_nil( Component() ) ) {
696 // We can call that component
698 RetVal = Component()->Kill_impl() ;
701 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
702 State( GraphExecutor::ErroredState ) ;
703 _OutNode->State( GraphExecutor::ErroredState ) ;
707 cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
710 cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
711 << " --> thread" << ThreadNo() << " KillEvent " << endl;
712 SendEvent( GraphExecutor::KillEvent ) ;
713 cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
714 << Name() << " --> thread" << ThreadNo() << endl;
717 else if ( IsDone() ) {
718 ControlState( SUPERV::VoidState ) ;
719 RetVal = false ; // Too late ...
723 cdebug << "Kill component Killed and !IsDone and !IsRunning !"
729 // Kill in the Container failed : it is always false if it is a Python Container
730 cdebug << "InNode::Suspend cannot Kill component ! Python Component ?"
732 if ( TryKill == 1 ) {
743 cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
745 // Wait for the end of loading of the component
746 while ( IsLoading() ) {
749 if ( TryKill == 1 ) {
764 else if ( IsMacroNode() ) {
765 // It should be like that but it is not completely implemented
766 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
767 RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
769 State( GraphExecutor::KilledState ) ;
774 // Now we can kill an InLineNode with the handler of the SuperVision Container
775 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
776 State( GraphExecutor::ErroredState ) ;
777 _OutNode->State( GraphExecutor::ErroredState ) ;
779 cdebug << "Kill of InLine nodes is NOT implemented." << endl;
780 MESSAGE( "Kill of InLine nodes is NOT implemented." );
782 cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
783 << _OutNode->MainThreadId() << " :" << endl ;
784 MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
785 << _OutNode->MainThreadId() << " :" ) ;
786 if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
787 // python signals run only in main thread ...
788 perror("Kill pthread_kill error") ;
789 State( GraphExecutor::ErroredState ) ;
790 _OutNode->State( GraphExecutor::ErroredState ) ;
794 cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
795 << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
796 MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
797 << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
803 else if ( IsSuspended() ) {
804 cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
805 << " --> thread" << ThreadNo() << " Resume()" << endl;
813 else if ( IsWaiting() ) {
816 else if ( IsReady() ) {
820 cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
821 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
828 // JR 24.03.2005 Debug it may have be killed if we have Suspend-Resume-Kill
829 if ( !RetVal && IsKilled() ) {
832 cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
833 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
834 << " SuspendedThreads " << _OutNode->SuspendedThreads()
835 << " EventQSize " << _OutNode->EventQSize() << " returns " << RetVal << endl ;
839 bool GraphExecutor::InNode::KillDone() {
840 cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
843 if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
847 ControlState( SUPERV::ToKillDoneState ) ;
849 if ( _OutNode->IsDone() ) {
850 ControlState( SUPERV::VoidState ) ;
858 else if ( IsWaiting() ) {
862 cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
868 cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
872 bool GraphExecutor::InNode::Stop() {
873 cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
876 if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
880 ControlState( SUPERV::ToStopState ) ;
882 if ( _OutNode->IsDone() ) {
883 ControlState( SUPERV::VoidState ) ;
889 if ( IsFactoryNode() || IsComputingNode() ) {
890 if ( !CORBA::is_nil( Component() ) ) {
892 RetVal = Component()->Stop_impl() ;
895 cdebug << "InNode::Stop() ERROR catched" << endl ;
896 State( GraphExecutor::ErroredState ) ;
897 _OutNode->State( GraphExecutor::ErroredState ) ;
902 SendEvent( GraphExecutor::StopEvent ) ;
904 else if ( IsDone() ) {
905 ControlState( SUPERV::VoidState ) ;
906 RetVal = false ; // Too late ...
909 cdebug << "component Suspended and !IsDone and !IsRunning !"
915 cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
920 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
924 else if ( IsWaiting() ) {
928 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
934 cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
938 bool GraphExecutor::InNode::SuspendDone() {
939 cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
940 << ThreadNo() << endl;
942 if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
946 ControlState( SUPERV::ToSuspendDoneState ) ;
948 if ( _OutNode->IsDone() ) {
949 ControlState( SUPERV::VoidState ) ;
957 cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
961 bool GraphExecutor::InNode::Resume() {
962 cdebug_in << pthread_self() << "/" << ThreadNo()
963 << " GraphExecutor::InNode::Resume " << Name() << " "
964 << Automaton()->StateName( State() ) << endl;
965 bool RetVal = false ;
966 if ( IsSuspended() ) {
967 if ( State() == GraphExecutor::SuspendedReadyState ) {
968 ResumeAction( GraphExecutor::ToResumeEvent ) ;
971 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
972 if ( IsFactoryNode() || IsComputingNode() ) {
973 if ( pthread_mutex_lock( &_MutexWait ) ) {
974 perror("ResumeAction pthread_mutex_lock ") ;
978 RetVal = Component()->Resume_impl() ;
980 State( GraphExecutor::ExecutingState ) ;
984 cdebug << "InNode::Resume() ERROR catched" << endl ;
985 State( GraphExecutor::ErroredState ) ;
986 _OutNode->State( GraphExecutor::ErroredState ) ;
989 if ( pthread_mutex_unlock( &_MutexWait ) ) {
990 perror("ResumeAction pthread_mutex_unlock ") ;
994 else if ( IsMacroNode() ) {
995 cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
996 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
997 RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
999 State( GraphExecutor::ExecutingState ) ;
1003 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
1004 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
1005 State( GraphExecutor::ErroredState ) ;
1006 _OutNode->State( GraphExecutor::ErroredState ) ;
1008 cdebug << "Resume of InLine nodes is NOT implemented." << endl;
1009 MESSAGE( "Resume of InLine nodes is NOT implemented." );
1011 cdebug << ThreadNo() << "/" << pthread_self()
1012 << "Resume of InLineNode pthread_kill" << Name() << endl ;
1013 if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
1014 perror("Resume pthread_kill error") ;
1015 State( GraphExecutor::ErroredState ) ;
1016 _OutNode->State( GraphExecutor::ErroredState ) ;
1020 State( GraphExecutor::ExecutingState ) ;
1026 else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1027 ResumeAction( GraphExecutor::ResumeEvent ) ;
1030 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1031 ResumeAction( GraphExecutor::ResumeEvent ) ;
1035 cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
1036 << Automaton()->StateName( State() ) << endl ;
1041 cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
1042 << Automaton()->StateName( State() ) << endl ;
1045 if ( ControlState() == SUPERV::ToSuspendStartState ) {
1046 ControlState( SUPERV::VoidState ) ;
1050 if ( ControlState() == SUPERV::ToSuspendRunState ||
1051 ( ControlState() == SUPERV::ToSuspendState &&
1052 State() == GraphExecutor::SuspendedReadyState) ) {
1053 if ( IsSuspended() ) {
1054 if ( State() == GraphExecutor::SuspendedReadyState ) {
1058 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
1060 RetVal = Component()->Resume_impl() ;
1063 cdebug << "GraphExecutor::InNode::Resume State "
1064 << Automaton()->StateName( State() ) << endl ;
1067 if ( ControlState() != SUPERV::ToSuspendState ) {
1068 ControlState( SUPERV::VoidState ) ;
1071 else if ( IsRunning() ) {
1074 else if ( IsWaiting() ) {
1075 ControlState( SUPERV::VoidState ) ;
1078 else if ( IsDone() ) {
1082 else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1083 ( ControlState() == SUPERV::ToSuspendState &&
1084 State() == GraphExecutor::SuspendedSuccessedState) ) {
1085 if ( IsSuspended() ) {
1086 if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1090 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1095 cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1098 if ( ControlState() != SUPERV::ToSuspendState ) {
1099 ControlState( SUPERV::VoidState ) ;
1102 else if ( IsRunning() ) {
1103 ControlState( SUPERV::VoidState ) ;
1106 else if ( IsWaiting() ) {
1107 ControlState( SUPERV::VoidState ) ;
1110 else if ( IsDone() ) {
1111 ControlState( SUPERV::VoidState ) ;
1116 cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1117 << Automaton()->StateName( State() ) << endl ;
1121 bool GraphExecutor::InNode::IsWaiting() {
1123 // cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1124 GraphExecutor::AutomatonState aState = State() ;
1125 if ( aState == GraphExecutor::DataUndefState ||
1126 aState == GraphExecutor::DataWaitingState ||
1127 aState == GraphExecutor::SuspendedReadyState )
1128 // aState == GraphExecutor::SuspendedExecutingState ||
1129 // aState == GraphExecutor::SuspendedSuccessedState ||
1130 // aState == GraphExecutor::SuspendedErroredState ||
1131 // aState == GraphExecutor::SuspendedState
1133 // cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1137 bool GraphExecutor::InNode::IsReady() {
1139 // cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1140 GraphExecutor::AutomatonState aState = State() ;
1141 // if ( aState == GraphExecutor::DataUndefState ||
1142 // aState == GraphExecutor::DataWaitingState ||
1143 if ( aState == GraphExecutor::DataReadyState ||
1144 aState == GraphExecutor::ResumedReadyState )
1146 // cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1150 bool GraphExecutor::InNode::IsRunning() {
1152 // cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1153 GraphExecutor::AutomatonState aState = State() ;
1154 if ( aState == GraphExecutor::ExecutingState ||
1155 aState == GraphExecutor::ResumedExecutingState )
1157 // cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1161 bool GraphExecutor::InNode::IsDone() {
1163 // cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1164 GraphExecutor::AutomatonState aState = State() ;
1165 if ( aState == GraphExecutor::KilledReadyState ||
1166 aState == GraphExecutor::StoppedReadyState ||
1167 aState == GraphExecutor::KilledExecutingState ||
1168 aState == GraphExecutor::StoppedExecutingState ||
1169 aState == GraphExecutor::SuspendedSuccessedState ||
1170 aState == GraphExecutor::SuspendedErroredState ||
1171 // aState == GraphExecutor::SuccessedExecutingState ||
1172 // aState == GraphExecutor::ErroredExecutingState ||
1173 aState == GraphExecutor::SuccessedState ||
1174 aState == GraphExecutor::ErroredState ||
1175 aState == GraphExecutor::ResumedSuccessedState ||
1176 aState == GraphExecutor::ResumedErroredState ||
1177 aState == GraphExecutor::KilledSuccessedState ||
1178 aState == GraphExecutor::StoppedSuccessedState )
1180 // cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1184 bool GraphExecutor::InNode::IsSuspended() {
1186 // cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1187 GraphExecutor::AutomatonState aState = State() ;
1188 if ( aState == GraphExecutor::SuspendedReadyState ||
1189 aState == GraphExecutor::SuspendedExecutingState ||
1190 aState == GraphExecutor::SuspendedSuccessedState ||
1191 aState == GraphExecutor::SuspendedErroredState ||
1192 aState == GraphExecutor::SuspendedState )
1194 // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1197 bool GraphExecutor::InNode::IsKilled() {
1199 // cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1200 GraphExecutor::AutomatonState aState = State() ;
1201 if ( aState == GraphExecutor::KilledReadyState ||
1202 aState == GraphExecutor::KilledExecutingState ||
1203 aState == GraphExecutor::KilledSuccessedState ||
1204 aState == GraphExecutor::KilledErroredState ||
1205 aState == GraphExecutor::KilledState )
1207 // cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1210 bool GraphExecutor::InNode::IsStopped() {
1212 // cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1213 GraphExecutor::AutomatonState aState = State() ;
1214 if ( aState == GraphExecutor::StoppedReadyState ||
1215 aState == GraphExecutor::StoppedExecutingState ||
1216 aState == GraphExecutor::StoppedSuccessedState ||
1217 aState == GraphExecutor::StoppedErroredState ||
1218 aState == GraphExecutor::StoppedState )
1220 // cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1224 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1225 bool RetVal = false ;
1226 if ( pthread_mutex_lock( &_MutexWait ) ) {
1227 perror("pthread_mutex_lock _Wait") ;
1231 case SUPERV::ReadyState : {
1232 RetVal = IsReady() ;
1233 cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1234 << " " << Automaton()->StateName( _currentState )
1235 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1236 while ( !RetVal && !IsDone() ) {
1237 cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1238 pthread_cond_wait( &_ReadyWait , &_MutexWait );
1239 RetVal = IsReady() ;
1240 cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1241 << Automaton()->StateName( _currentState ) << " " << RetVal
1244 cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1245 << " " << Automaton()->StateName( _currentState )
1246 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1249 case SUPERV::RunningState : {
1250 RetVal = IsRunning() ;
1251 cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1252 << " " << Automaton()->StateName( _currentState )
1253 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1254 // mkr : IPAL10056 : additional checking for node aborted
1255 while ( !RetVal && !IsDone() && !_OutNode->IsNodeAborted() ) {
1256 cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1257 pthread_cond_wait( &_RunningWait , &_MutexWait );
1258 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1259 RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1260 State() == GraphExecutor::ErroredExecutingState ;
1261 cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1262 << Automaton()->StateName( _currentState ) << " " << RetVal
1263 << " " << Name() << endl ;
1265 cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1266 << " " << Automaton()->StateName( _currentState )
1267 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1270 case SUPERV::DoneState : {
1272 cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1273 << " " << Automaton()->StateName( _currentState )
1274 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1276 cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1277 pthread_cond_wait( &_DoneWait , &_MutexWait );
1279 cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1280 << Automaton()->StateName( _currentState ) << " " << RetVal
1283 cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1284 << " " << Automaton()->StateName( _currentState )
1285 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1288 case SUPERV::SuspendState : {
1289 RetVal = IsSuspended() ;
1290 cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1291 << " " << Automaton()->StateName( _currentState )
1292 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1293 while ( !RetVal && !IsDone() ) {
1294 cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1295 pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1296 RetVal = IsSuspended() ;
1297 cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1298 << Automaton()->StateName( _currentState ) << " " << RetVal
1301 cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1302 << " " << Automaton()->StateName( _currentState )
1303 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1307 cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1311 if ( pthread_mutex_unlock( &_MutexWait ) ) {
1312 perror("pthread_mutex_lock _Wait") ;
1318 bool GraphExecutor::InNode::ReadyWait() {
1319 // cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1321 aret = StateWait( SUPERV::ReadyState ) ;
1322 // cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1326 bool GraphExecutor::InNode::RunningWait() {
1327 cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1328 << " " << Automaton()->StateName( State() ) << endl;
1330 aret = StateWait( SUPERV::RunningState ) ;
1331 cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1332 << " " << Automaton()->StateName( State() ) << endl;
1336 bool GraphExecutor::InNode::DoneWait() {
1337 // cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1339 aret = StateWait( SUPERV::DoneState ) ;
1343 bool GraphExecutor::InNode::SuspendedWait() {
1344 // cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1346 aret = StateWait( SUPERV::SuspendState ) ;
1350 void GraphExecutor::InNode::InitialState()
1352 cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1355 _ControlState = SUPERV::VoidState ;
1356 CreateNewThread( false ) ;
1357 //JR 15.04.2005 Debug PAL8624 RetroConception :
1358 // CreateNewThreadIf( false ) ;
1359 HasAllDataReady( false ) ;
1360 _SuspendSync = false ;
1361 _ResumeSync = false ;
1364 // asv : 13.12.04 : Decided to set "Loading" state for factory and computing nodes ONLY.
1365 // See extended comment in p.2.19 of "Bugs and Improvements" about IsLoading for InLine.
1366 if ( IsComputingNode() || IsFactoryNode() ) {
1370 // ThreadNo( pthread_self() ) ;
1373 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1374 if ( GetNodeOutPort(i)->IsDataStream() ) {
1375 GetChangeNodeOutPort(i)->PortState( SUPERV::ReadyState ) ;
1376 GetChangeNodeOutPort(i)->PortDone( true ) ;
1378 //JR Debug 01.07.2005 :
1379 // else if ( i != 0 || !IsGOTONode() ) {
1381 GetChangeNodeOutPort(i)->PortState( SUPERV::WaitingState ) ;
1382 GetChangeNodeOutPort(i)->PortDone( false ) ;
1386 int InPortsCount = GetNodeInPortsSize() ;
1387 for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1388 GraphBase::InPort * anInPort = GetChangeNodeInPort(i) ;
1389 anInPort->PortState( SUPERV::WaitingState ) ;
1390 GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1391 if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1392 anOutPort->PortStatus( DataConnected );
1393 anOutPort->PortState( SUPERV::ReadyState ) ;
1394 anOutPort->PortDone( true ) ;
1395 //JR 21.02.2005 Debug Memory leak : CORBA::Any * anAny = new CORBA::Any() ;
1396 CORBA::Any anAny = CORBA::Any() ;
1397 //JR 21.02.2005 Debug Memory leak : *anAny <<= (long ) 1 ;
1398 anAny <<= (long ) 1 ;
1399 anOutPort->SetValue( anAny ) ;
1401 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1402 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1403 << " InitLoop HeadNode" << endl ;
1405 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1406 else if ( anInPort->IsGate() && anOutPort ) {
1407 anOutPort->PortState( SUPERV::WaitingState ) ;
1408 anOutPort->PortDone( false ) ;
1409 const GraphBase::ComputingNode * aFromNode = _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ;
1410 //JR if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) {
1411 if ( aFromNode->IsGOTONode() || ( IsLoopNode() && CoupledNode() == aFromNode ) ) {
1412 // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.
1413 // before was "else if ( IsOneOfInlineNodes() )"
1414 // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1415 anOutPort->PortStatus( DataConnected );
1416 anOutPort->PortState( SUPERV::ReadyState ) ;
1417 anOutPort->PortDone( true ) ;
1419 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1420 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1421 << " Gate HeadNode" << endl ;
1424 cdebug << Name() << " IsHeadNode " << IsHeadNode() << " InPort" << i << " "
1425 << anInPort->PortName() << " " << anInPort->PortStatus() << endl ;
1427 if ( anInPort->IsGate() && anOutPort == NULL ) {
1429 cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected InPortsCount "
1430 << InPortsCount << endl ;
1432 else if ( anOutPort ) {
1433 if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1435 anOutPort->PortState( SUPERV::ReadyState ) ;
1436 anOutPort->PortDone( true ) ;
1437 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1438 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1439 << InPortsCount << endl ;
1441 else if ( anOutPort->IsPortConnected() ) {
1442 anOutPort->PortState( SUPERV::WaitingState ) ;
1443 anOutPort->PortDone( false ) ;
1444 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " "
1445 << anInPort->PortStatus()
1446 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1447 << InPortsCount << endl ;
1450 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1451 << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1452 << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1453 << InPortsCount << endl ;
1457 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1458 << " no corresponding OutPort InPortsCount " << InPortsCount << endl ;
1461 if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1462 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1463 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1464 << " with state of OutPort : " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1465 GetChangeNodeInPort(i)->PortState( anOutPort->PortState() ) ;
1467 else if ( anOutPort->IsDataConnected() ) {
1468 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1469 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1470 << " with state ReadyState" << endl ;
1471 GetChangeNodeInPort(i)->PortState( SUPERV::ReadyState ) ;
1474 cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1475 << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1476 << " with state " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1480 cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1481 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1483 if ( anOutPort->PortState() == SUPERV::WaitingState ) {
1484 cdebug << "WaitingState" ;
1486 else if ( anOutPort->PortState() == SUPERV::ReadyState ) {
1487 cdebug << "ReadyState" ;
1492 cdebug << " OutPortStatus " << anOutPort->PortStatus() << " State "
1493 << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1497 _currentState = InPortsCount > 0 ? GraphExecutor::DataWaitingState
1498 : GraphExecutor::DataReadyState ;
1499 if ( InPortsCount == GetNodeInPortsSize() ) {
1500 _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1503 else if ( InPortsCount != 0 ) {
1504 _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1508 _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1512 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1513 cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1514 << theAutomaton->StateName( GetChangeNodeOutPort(i)->PortState() )
1515 << " " << GetNodeOutPort(i)->Kind() << endl ;
1518 cdebug_out << "GraphExecutor::InNode::InitialState Node " << Name() << " CurrentState = "
1519 << theAutomaton->StateName( _currentState ) << " HasAllDataReady "
1520 << HasAllDataReady() << endl;
1523 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1524 cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " WithErr " << WithErr
1525 << " PyFuncRunned() " << PyFuncRunned() << endl;
1528 if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1529 if ( IsLoopNode() ) {
1530 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1531 PyObject * PyMoreMethod = NULL ;
1532 PyObject * PyNextMethod = NULL ;
1533 if ( PyRunMethod ) {
1537 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1538 InLineNode()->PythonFunction() ,
1540 InLineNode()->PyRunMethod( PyRunMethod ) ;
1542 Err = Err || OneErr ;
1543 if ( OneErr && WithErr ) {
1544 string anErrorMessage = string( "Error while declaring the Python function " ) +
1545 string( LoopNode()->PyFuncName() ) + string( " in Node " ) +
1547 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1549 PyMoreMethod = LoopNode()->PyMoreMethod() ;
1550 if ( PyMoreMethod ) {
1554 PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1555 LoopNode()->MorePythonFunction() ,
1557 LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1559 Err = Err || OneErr ;
1560 if ( OneErr && WithErr ) {
1561 string anErrorMessage = string( "Error while declaring the Python function " ) +
1562 string( LoopNode()->PyMoreName() ) + string( " in Node " ) +
1564 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1566 PyNextMethod = LoopNode()->PyNextMethod() ;
1567 if ( PyNextMethod ) {
1571 PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1572 LoopNode()->NextPythonFunction() ,
1574 LoopNode()->PyNextMethod( PyNextMethod ) ;
1576 Err = Err || OneErr ;
1577 if ( OneErr && WithErr ) {
1578 string anErrorMessage = string( "Error while declaring the Python function " ) +
1579 string( LoopNode()->PyNextName() ) + string( " in Node " ) +
1581 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1583 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) "
1584 << PyRunMethod << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod
1587 else if ( IsInLineNode() || IsSwitchNode() ) {
1588 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1589 if ( PyRunMethod ) {
1593 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1594 InLineNode()->PythonFunction() ,
1596 InLineNode()->PyRunMethod( PyRunMethod ) ;
1598 Err = Err || OneErr ;
1599 if ( OneErr && WithErr ) {
1600 string anErrorMessage = string( "Error while declaring the Python function " ) +
1601 string( InLineNode()->PyFuncName() ) + string( " in Node " ) +
1603 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1605 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1607 else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1608 (*InLineNode()->PythonFunction()).length() ) {
1609 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1610 if ( PyRunMethod ) {
1614 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1615 InLineNode()->PythonFunction() ,
1617 InLineNode()->PyRunMethod( PyRunMethod ) ;
1619 Err = Err || OneErr ;
1620 if ( OneErr && WithErr ) {
1621 string anErrorMessage = string( "Error while declaring the Python function " ) +
1622 string( InLineNode()->PyFuncName() ) + string( " in Node " ) +
1624 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1626 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1629 Err = WithErr && Err ;
1630 cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1632 cdebug << " Error " << Err ;
1638 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1639 CORBA::Long cpu = 0 ;
1640 // cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " ) " << Name() << endl ;
1641 // cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1642 // << theAutomaton->StateName( _currentState ) << endl ;
1643 if ( IsOneOfInLineNodes() ) {
1644 // cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1645 // cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1646 cpu = PyCpuUsed( tot ) ;
1649 if ( !CORBA::is_nil( Component() ) ) {
1650 // cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1651 // cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1653 cpu = Component()->CpuUsed_impl() ;
1656 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched "
1658 State( GraphExecutor::ErroredState ) ;
1659 _OutNode->State( GraphExecutor::ErroredState ) ;
1664 cdebug << "CpuUsed " << Name() << " Component() is NIL" << endl ;
1668 // cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1669 // cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1670 // << theAutomaton->StateName( _currentState ) << endl ;
1674 #include <sys/time.h>
1675 #include <sys/resource.h>
1678 long GraphExecutor::InNode::PyCpu() {
1679 struct rusage usage ;
1681 if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1682 perror("GraphExecutor::InNode::PyCpu") ;
1685 // return usage.ru_utime.__time_t tv_sec ;
1686 // cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1687 // << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1689 cpu = usage.ru_utime.tv_sec ;
1693 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1695 if ( _PyTotCpuUsed == -1 ) {
1696 if ( _Pythread == pthread_self() ) {
1697 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1698 // << " _PyTotCpuUsed " << _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1699 // << _PyCpuUsed << endl ;
1700 cpu = PyCpu() - _PyCpuUsed ;
1702 _PyTotCpuUsed = cpu ;
1710 cpu = _PyTotCpuUsed ;
1712 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1713 // << _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1717 void GraphExecutor::InNode::SetPyCpuUsed() {
1718 _PyTotCpuUsed = -1 ;
1720 _Pythread = pthread_self() ;
1721 _PyCpuUsed = PyCpu() ;
1722 // cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1723 // << _PyCpuUsed << endl ;
1726 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1727 _Loading = Loading ;
1729 // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works:
1730 // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1731 // after Loading is finished (here below), ExecutingState must be pushed for GUI.
1733 _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );