1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
23 // File : DataFlowExecutor_InNode.cxx
24 // Author : Jean Rahuel, CEA
38 #include <SALOMEconfig.h>
39 #include CORBA_CLIENT_HEADER(SALOME_Component)
40 //#include "SALOME_NamingService.hxx"
41 #include "SALOME_LifeCycleCORBA.hxx"
43 #include "DataFlowBase_FactoryNode.hxx"
44 #include "DataFlowBase_GOTONode.hxx"
45 #include "DataFlowBase_LoopNode.hxx"
46 #include "DataFlowBase_EndOfLoopNode.hxx"
47 #include "DataFlowBase_SwitchNode.hxx"
48 #include "DataFlowBase_EndOfSwitchNode.hxx"
50 #include "DataFlowExecutor_DataFlow.hxx"
51 #include "DataFlowEditor_DataFlow.hxx" // GraphEditor package must be built BEFORE
53 static void InitInNode( int &_RewindStack ,
54 SUPERV::ControlState &_ControlState ,
55 GraphExecutor::AutomatonState &_currentState ,
56 GraphExecutor::InNode ** _aReStartNode ,
57 bool & _PyFuncRunned ,
58 PyObject ** _MyPyRunMethod ,
59 // pthread_mutex_t &_MutexDataWait ,
61 pthread_mutex_t &_MutexDataReady ,
62 pthread_mutex_t &_MutexWait ,
63 pthread_cond_t &_ReadyWait ,
64 pthread_cond_t &_RunningWait ,
65 pthread_cond_t &_DoneWait ,
66 pthread_cond_t &_SuspendedWait ,
67 pthread_cond_t &_SuspendWait ,
69 pthread_cond_t &_ResumeWait ,
71 pthread_cond_t &_KillWait ,
73 pthread_cond_t &_ThreadStartedWait ,
74 bool &_ThreadStartedSync ,
75 pthread_cond_t &_StopWait ,
76 GraphExecutor::FiniteStateMachine ** _Automaton ,
77 GraphExecutor::FiniteStateMachine * theAutomaton ,
78 CORBA::ORB_ptr * _Orb ,
82 _ControlState = SUPERV::VoidState ;
83 _currentState = GraphExecutor::UnKnownState ;
84 *_aReStartNode = NULL ;
85 _PyFuncRunned = false ;
86 *_MyPyRunMethod = NULL ;
87 // pthread_mutex_init( &_MutexDataWait , NULL ) ;
88 // _DataWait = false ;
89 pthread_mutex_init( &_MutexDataReady , NULL ) ;
90 pthread_mutex_init( &_MutexWait , NULL ) ;
91 if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
92 perror("pthread_cond_init( &_ReadyWait , NULL )") ;
95 if ( pthread_cond_init( &_RunningWait , NULL ) ) {
96 perror("pthread_cond_init( &_RunningWait , NULL )") ;
99 if ( pthread_cond_init( &_DoneWait , NULL ) ) {
100 perror("pthread_cond_init( &_DoneWait , NULL )") ;
103 if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
104 perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
107 if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
108 perror("pthread_cond_init( &_SuspendWait , NULL )") ;
111 _SuspendSync = false ;
112 if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
113 perror("pthread_cond_init( &_ResumeWait , NULL )") ;
116 _ResumeSync = false ;
117 if ( pthread_cond_init( &_KillWait , NULL ) ) {
118 perror("pthread_cond_init( &_KillWait , NULL )") ;
122 if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
123 perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
126 _ThreadStartedSync = false ;
127 if ( pthread_cond_init( &_StopWait , NULL ) ) {
128 perror("pthread_cond_init( &_StopWait , NULL )") ;
131 *_Automaton = theAutomaton ;
132 *_Orb = CORBA::ORB::_nil();
136 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
138 //GraphExecutor::InNode::InNode() :
139 // GraphBase::FactoryNode() {
140 GraphExecutor::InNode::InNode() {
141 InitInNode( _RewindStack ,
171 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
172 SALOME_NamingService* ptrNamingService ,
173 const SALOME_ModuleCatalog::Service& aService ,
174 const char * ComponentName ,
175 const char * NodeInterfaceName ,
176 const char * NodeName ,
177 const SUPERV::KindOfNode akind ,
178 GraphBase::ListOfFuncName aFuncName ,
179 GraphBase::ListOfPythonFunctions aPythonFunction ,
180 const SUPERV::SDate NodeFirstCreation ,
181 const SUPERV::SDate NodeLastModification ,
182 const char * NodeEditorRelease ,
183 const char * NodeAuthor ,
184 const char * NodeComputer ,
185 const char * NodeComment ,
186 const bool GeneratedName ,
189 int * Graph_prof_debug,
190 ofstream * Graph_fdebug) {
191 // ostream * Graph_fdebug = NULL ) :
192 // GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
193 // ComponentName , NodeInterfaceName ,
194 // NodeName , akind ,
195 // NodeFirstCreation , NodeLastModification ,
196 // NodeEditorRelease , NodeAuthor ,
197 // NodeComputer , NodeComment , GeneratedName ,
199 // Graph_prof_debug , Graph_fdebug ) {
200 InitInNode( _RewindStack ,
228 SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
230 _ComputingNode = NULL ;
231 _FactoryNode = NULL ;
235 _EndOfLoopNode = NULL ;
237 _EndOfSwitchNode = NULL ;
239 case SUPERV::ComputingNode : {
240 cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
241 _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
245 NodeLastModification ,
246 NodeEditorRelease , NodeAuthor ,
247 NodeComment , GeneratedName ,
249 Graph_prof_debug , Graph_fdebug ) ;
252 case SUPERV::FactoryNode : {
253 cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
254 _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
255 ComponentName , NodeInterfaceName ,
258 NodeLastModification ,
259 NodeEditorRelease , NodeAuthor ,
260 NodeComputer , NodeComment ,
261 GeneratedName , NodeX , NodeY ,
262 Graph_prof_debug , Graph_fdebug ) ;
263 _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
266 case SUPERV::InLineNode : {
267 cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
268 _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
269 aFuncName[0].c_str() , *aPythonFunction[0] ,
271 NodeFirstCreation , NodeLastModification ,
272 NodeEditorRelease , NodeAuthor ,
273 NodeComment , GeneratedName ,
275 Graph_prof_debug , Graph_fdebug ) ;
276 _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
279 case SUPERV::MacroNode : {
280 cdebug << "GraphExecutor::InNode::InNode SUPERV::MacroNode : " << NodeName << endl ;
281 _GraphMacroNode = new GraphBase::Graph( ORB , ptrNamingService ,
282 // aFuncName[0].c_str() , *aPythonFunction[0] ,
284 // NodeFirstCreation , NodeLastModification ,
285 // NodeEditorRelease , NodeAuthor ,
286 // NodeComment , GeneratedName ,
288 Graph_prof_debug , Graph_fdebug ) ;
289 _ComputingNode = (GraphBase::ComputingNode *) _GraphMacroNode ;
290 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
291 _GOTONode = (GraphBase::GOTONode *) _InLineNode ;
292 _GraphMacroNode->Coordinates( NodeX , NodeY ) ;
295 case SUPERV::GOTONode : {
296 cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
297 _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
298 aFuncName[0].c_str() , *aPythonFunction[0] ,
300 NodeFirstCreation , NodeLastModification ,
301 NodeEditorRelease , NodeAuthor ,
302 NodeComment , GeneratedName ,
304 Graph_prof_debug , Graph_fdebug ) ;
305 _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
306 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
309 case SUPERV::LoopNode : {
310 cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
311 _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
312 aFuncName[0].c_str() , *aPythonFunction[0] ,
313 aFuncName[1].c_str() , *aPythonFunction[1] ,
314 aFuncName[2].c_str() , *aPythonFunction[2] ,
316 NodeFirstCreation , NodeLastModification ,
317 NodeEditorRelease , NodeAuthor ,
318 NodeComment , GeneratedName ,
320 Graph_prof_debug , Graph_fdebug ) ;
321 _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
322 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
323 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
326 case SUPERV::EndLoopNode : {
327 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
328 _EndOfLoopNode = new GraphBase::EndOfLoopNode(
329 ORB , ptrNamingService ,
330 aFuncName[0].c_str() , *aPythonFunction[0] ,
332 NodeFirstCreation , NodeLastModification ,
333 NodeEditorRelease , NodeAuthor ,
334 NodeComment , GeneratedName ,
336 Graph_prof_debug , Graph_fdebug ) ;
337 _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
338 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
339 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
342 case SUPERV::SwitchNode : {
343 cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
344 _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
345 aFuncName[0].c_str() , *aPythonFunction[0] ,
347 NodeFirstCreation , NodeLastModification ,
348 NodeEditorRelease , NodeAuthor ,
349 NodeComment , GeneratedName ,
351 Graph_prof_debug , Graph_fdebug ) ;
352 _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
353 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
354 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
357 case SUPERV::EndSwitchNode : {
358 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
359 _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
360 ORB , ptrNamingService ,
361 aFuncName[0].c_str() , *aPythonFunction[0] ,
363 NodeFirstCreation , NodeLastModification ,
364 NodeEditorRelease , NodeAuthor ,
365 NodeComment , GeneratedName ,
367 Graph_prof_debug , Graph_fdebug ) ;
368 _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
369 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
370 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
373 case SUPERV::DataFlowGraph : {
374 cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowGraph ERROR : " << NodeName ;
376 case SUPERV::DataStreamGraph : {
377 cdebug << "GraphEditor::InNode::InNode SUPERV::DataStreamGraph ERROR : " << NodeName ;
379 case SUPERV::UnknownNode : {
380 cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
383 cdebug << "GraphExecutor::InNode::InNode " << (void *) this
384 << " _ComputingNode " << (void *) _ComputingNode ;
385 _ComputingNode->InNode( this ) ;
388 GraphExecutor::InNode::~InNode() {
391 //JR 15.04.2005 Debug PAL8624 RetroConception :
393 void GraphExecutor::InNode::LockDataWait() {
394 // cdebug_in << "GraphExecutor::InNode::LockDataWait " << endl ;
395 if ( pthread_mutex_lock( &_MutexDataWait ) ) {
396 perror("Ready pthread_mutex_lock ") ;
400 // cdebug_out << "GraphExecutor::InNode::LockDataWait " << endl ;
402 void GraphExecutor::InNode::UnLockDataWait() {
403 // cdebug_in << "GraphExecutor::InNode::UnLockDataWait " << endl ;
405 if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
406 perror("Ready pthread_mutex_unlock ") ;
409 // cdebug_out << "GraphExecutor::InNode::UnLockDataWait " << endl ;
413 //JR 15.04.2005 Debug PAL8624 RetroConception :
414 void GraphExecutor::InNode::LockDataReady() {
415 // cdebug_in << pthread_self() << "/" << ThreadNo()
416 // << "GraphExecutor::InNode::LockDataReady : " << Name() << " _MutexDataReadyLocked "
417 // << _MutexDataReadyLocked << " HasAllDataReady " << HasAllDataReady() << endl ;
418 if ( pthread_mutex_lock( &_MutexDataReady ) ) {
419 perror("MutexDataReady pthread_mutex_lock ") ;
422 _MutexDataReadyLocked = true ;
423 // cdebug_out << pthread_self() << "/" << ThreadNo()
424 // << "GraphExecutor::InNode::LockDataReady : " << Name() << endl ;
426 void GraphExecutor::InNode::UnLockDataReady() {
427 // cdebug_in << pthread_self() << "/" << ThreadNo()
428 // << "GraphExecutor::InNode::UnLockDataReady : " << Name() << " _MutexDataReadyLocked "
429 // << _MutexDataReadyLocked << " HasAllDataReady " << HasAllDataReady() << endl ;
430 if ( pthread_mutex_unlock( &_MutexDataReady ) ) {
431 perror("MutexDataReady pthread_mutex_unlock ") ;
434 _MutexDataReadyLocked = false ;
435 // cdebug_out << pthread_self() << "/" << ThreadNo()
436 // << "GraphExecutor::InNode::UnLockDataReady : " << Name() << endl ;
439 Engines::Component_var GraphExecutor::InNode::Component() const {
440 if ( IsFactoryNode() ) {
441 return _FactoryNode->Component() ;
444 //JR 30.03.2005 CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
445 const CORBA::Any anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
446 CORBA::Object_ptr obj ;
448 //JR 30.03.2005 *anAnyComponent >>= obj ;
449 anAnyComponent >>= obj ;
450 return Engines::Component::_narrow( obj ) ;
453 cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
456 return Engines::Component::_nil() ;
459 Engines::Container_var GraphExecutor::InNode::Container() const {
460 if ( IsFactoryNode() ) {
461 return _FactoryNode->Container() ;
463 return Engines::Container::_nil() ;
467 bool GraphExecutor::InNode::Ping() {
468 cdebug_in << "GraphExecutor::InNode::Ping" << endl;
470 if ( IsFactoryNode() ) {
471 RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
473 if ( State() != GraphExecutor::SuspendedExecutingState ) {
475 _FactoryNode->Component()->ping() ;
478 cdebug << "InNode::Ping() ERROR catched" << endl ;
479 State( GraphExecutor::ErroredState ) ;
480 _OutNode->State( GraphExecutor::ErroredState ) ;
489 cdebug << "GraphExecutor::InNode::Ping Component ObjRef is NIL" << endl;
492 cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
496 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
497 ThreadNo ( aThread ) ;
499 _OutNode->NewThread() ;
501 void GraphExecutor::InNode::ExitThread() {
503 _OutNode->ExitThread() ;
506 bool GraphExecutor::InNode::Suspend() {
507 cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
508 << " " << Automaton()->StateName( State() ) << endl;
509 bool RetVal = false ;
511 //If loop we need to suspend also ControlState( SUPERV::VoidState ) ;
512 ControlState( SUPERV::ToSuspendState ) ;
514 if ( _OutNode->IsDone() ) {
515 ControlState( SUPERV::VoidState ) ;
519 else if ( IsWaiting() || IsReady() ) {
520 ControlState( SUPERV::ToSuspendState ) ;
523 else if ( IsRunning() ) {
524 ControlState( SUPERV::ToSuspendState ) ;
525 if ( IsFactoryNode() || IsComputingNode() ) {
526 // We have to suspend in the container of that node
527 int TrySuspend = 10 ;
528 while ( TrySuspend ) {
529 if ( !CORBA::is_nil( Component() ) ) {
530 // We can call that component
532 RetVal = Component()->Suspend_impl() ;
535 cdebug << "InNode::Suspend() ERROR catched" << endl ;
536 State( GraphExecutor::ErroredState ) ;
537 _OutNode->State( GraphExecutor::ErroredState ) ;
541 cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ;
544 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
545 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
546 SendEvent( GraphExecutor::SuspendEvent ) ;
547 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
548 << Name() << " --> thread" << ThreadNo() << endl;
551 else if ( IsDone() ) {
552 ControlState( SUPERV::VoidState ) ;
553 RetVal = false ; // Too late ...
557 cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !"
559 MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ;
564 // Suspend in the Container failed : it is always false if it is a Python Container
565 cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?"
567 if ( TrySuspend == 1 ) {
568 if ( IsSuspended() ) {
578 cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?"
580 // Wait for the end of loading of the component
581 while ( IsLoading() ) {
584 if ( TrySuspend == 1 ) {
585 if ( IsSuspended() ) {
599 else if ( IsMacroNode() ) {
600 // It should be like that but it is not completely implemented
601 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
602 RetVal = aGraph->GraphEditor()->Executor()->Suspend() ;
604 State( GraphExecutor::SuspendedState ) ;
608 // Now we can suspend an InLineNode with the handler of the SuperVision Container
609 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
610 State( GraphExecutor::ErroredState ) ;
611 _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false;
612 cdebug << "Suspend of InLine nodes is NOT implemented." << endl;
613 MESSAGE( "Suspend of InLine nodes is NOT implemented." );
615 if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) {
616 perror("Suspend pthread_kill error") ;
617 State( GraphExecutor::ErroredState ) ;
618 _OutNode->State( GraphExecutor::ErroredState ) ;
626 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name()
627 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
628 SendEvent( GraphExecutor::SuspendEvent ) ;
629 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container"
630 << Name() << " --> thread" << ThreadNo() << endl;
632 else if ( IsDone() ) {
633 ControlState( SUPERV::VoidState ) ;
634 RetVal = false ; // Too late ...
637 cdebug << "component Suspended and !IsDone and !IsRunning !"
645 cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning()
646 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
650 cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
651 << Automaton()->StateName( State() ) << endl ;
655 bool GraphExecutor::InNode::ContainerKill() {
656 cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
657 << ThreadNo() << endl;
659 if ( IsFactoryNode() ) {
661 RetVal = Container()->Kill_impl() ;
663 cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
667 bool GraphExecutor::InNode::Kill() {
668 cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
669 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
670 << " SuspendedThreads " << _OutNode->SuspendedThreads()
671 << " EventQSize " << _OutNode->EventQSize() << endl;
674 ControlState( SUPERV::ToKillState ) ; // if loop
675 if ( _OutNode->IsDone() ) {
676 ControlState( SUPERV::VoidState ) ;
681 ControlState( SUPERV::ToKillState ) ;
683 if ( _OutNode->IsDone() ) {
684 ControlState( SUPERV::VoidState ) ;
690 if ( IsFactoryNode() || IsComputingNode() ) {
691 // We have to suspend in the container of that node
694 if ( !CORBA::is_nil( Component() ) ) {
695 // We can call that component
697 RetVal = Component()->Kill_impl() ;
700 cdebug << "InNode::Kill_impl ERROR catched" << endl ;
701 State( GraphExecutor::ErroredState ) ;
702 _OutNode->State( GraphExecutor::ErroredState ) ;
706 cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
709 cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
710 << " --> thread" << ThreadNo() << " KillEvent " << endl;
711 SendEvent( GraphExecutor::KillEvent ) ;
712 cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
713 << Name() << " --> thread" << ThreadNo() << endl;
716 else if ( IsDone() ) {
717 ControlState( SUPERV::VoidState ) ;
718 RetVal = false ; // Too late ...
722 cdebug << "Kill component Killed and !IsDone and !IsRunning !"
728 // Kill in the Container failed : it is always false if it is a Python Container
729 cdebug << "InNode::Suspend cannot Kill component ! Python Component ?"
731 if ( TryKill == 1 ) {
742 cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?"
744 // Wait for the end of loading of the component
745 while ( IsLoading() ) {
748 if ( TryKill == 1 ) {
763 else if ( IsMacroNode() ) {
764 // It should be like that but it is not completely implemented
765 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
766 RetVal = aGraph->GraphEditor()->Executor()->Kill() ;
768 State( GraphExecutor::KilledState ) ;
773 // Now we can kill an InLineNode with the handler of the SuperVision Container
774 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
775 State( GraphExecutor::ErroredState ) ;
776 _OutNode->State( GraphExecutor::ErroredState ) ;
778 cdebug << "Kill of InLine nodes is NOT implemented." << endl;
779 MESSAGE( "Kill of InLine nodes is NOT implemented." );
781 cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
782 << _OutNode->MainThreadId() << " :" << endl ;
783 MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId "
784 << _OutNode->MainThreadId() << " :" ) ;
785 if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) {
786 // python signals run only in main thread ...
787 perror("Kill pthread_kill error") ;
788 State( GraphExecutor::ErroredState ) ;
789 _OutNode->State( GraphExecutor::ErroredState ) ;
793 cdebug << pthread_self() << "pthread_kill of InLineNode " << Name()
794 << " done. MainThreadId " << _OutNode->MainThreadId() << endl ;
795 MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name()
796 << " done. MainThreadId " << _OutNode->MainThreadId() ) ;
802 else if ( IsSuspended() ) {
803 cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
804 << " --> thread" << ThreadNo() << " Resume()" << endl;
812 else if ( IsWaiting() ) {
815 else if ( IsReady() ) {
819 cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning()
820 << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady()
827 // JR 24.03.2005 Debug it may have be killed if we have Suspend-Resume-Kill
828 if ( !RetVal && IsKilled() ) {
831 cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
832 << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads()
833 << " SuspendedThreads " << _OutNode->SuspendedThreads()
834 << " EventQSize " << _OutNode->EventQSize() << " returns " << RetVal << endl ;
838 bool GraphExecutor::InNode::KillDone() {
839 cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
842 if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
846 ControlState( SUPERV::ToKillDoneState ) ;
848 if ( _OutNode->IsDone() ) {
849 ControlState( SUPERV::VoidState ) ;
857 else if ( IsWaiting() ) {
861 cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
867 cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
871 bool GraphExecutor::InNode::Stop() {
872 cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
875 if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
879 ControlState( SUPERV::ToStopState ) ;
881 if ( _OutNode->IsDone() ) {
882 ControlState( SUPERV::VoidState ) ;
888 if ( IsFactoryNode() || IsComputingNode() ) {
889 if ( !CORBA::is_nil( Component() ) ) {
891 RetVal = Component()->Stop_impl() ;
894 cdebug << "InNode::Stop() ERROR catched" << endl ;
895 State( GraphExecutor::ErroredState ) ;
896 _OutNode->State( GraphExecutor::ErroredState ) ;
901 SendEvent( GraphExecutor::StopEvent ) ;
903 else if ( IsDone() ) {
904 ControlState( SUPERV::VoidState ) ;
905 RetVal = false ; // Too late ...
908 cdebug << "component Suspended and !IsDone and !IsRunning !"
914 cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ;
919 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
923 else if ( IsWaiting() ) {
927 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
933 cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
937 bool GraphExecutor::InNode::SuspendDone() {
938 cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
939 << ThreadNo() << endl;
941 if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
945 ControlState( SUPERV::ToSuspendDoneState ) ;
947 if ( _OutNode->IsDone() ) {
948 ControlState( SUPERV::VoidState ) ;
956 cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
960 bool GraphExecutor::InNode::Resume() {
961 cdebug_in << pthread_self() << "/" << ThreadNo()
962 << " GraphExecutor::InNode::Resume " << Name() << " "
963 << Automaton()->StateName( State() ) << endl;
964 bool RetVal = false ;
965 if ( IsSuspended() ) {
966 if ( State() == GraphExecutor::SuspendedReadyState ) {
967 ResumeAction( GraphExecutor::ToResumeEvent ) ;
970 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
971 if ( IsFactoryNode() || IsComputingNode() ) {
972 if ( pthread_mutex_lock( &_MutexWait ) ) {
973 perror("ResumeAction pthread_mutex_lock ") ;
977 RetVal = Component()->Resume_impl() ;
979 State( GraphExecutor::ExecutingState ) ;
983 cdebug << "InNode::Resume() ERROR catched" << endl ;
984 State( GraphExecutor::ErroredState ) ;
985 _OutNode->State( GraphExecutor::ErroredState ) ;
988 if ( pthread_mutex_unlock( &_MutexWait ) ) {
989 perror("ResumeAction pthread_mutex_unlock ") ;
993 else if ( IsMacroNode() ) {
994 cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ;
995 GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ;
996 RetVal = aGraph->GraphEditor()->Executor()->Resume() ;
998 State( GraphExecutor::ExecutingState ) ;
1002 // Resume of InLinePythonNode in the Node of the SuperVisionContainer ...
1003 // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
1004 State( GraphExecutor::ErroredState ) ;
1005 _OutNode->State( GraphExecutor::ErroredState ) ;
1007 cdebug << "Resume of InLine nodes is NOT implemented." << endl;
1008 MESSAGE( "Resume of InLine nodes is NOT implemented." );
1010 cdebug << ThreadNo() << "/" << pthread_self()
1011 << "Resume of InLineNode pthread_kill" << Name() << endl ;
1012 if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) {
1013 perror("Resume pthread_kill error") ;
1014 State( GraphExecutor::ErroredState ) ;
1015 _OutNode->State( GraphExecutor::ErroredState ) ;
1019 State( GraphExecutor::ExecutingState ) ;
1025 else if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1026 ResumeAction( GraphExecutor::ResumeEvent ) ;
1029 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1030 ResumeAction( GraphExecutor::ResumeEvent ) ;
1034 cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
1035 << Automaton()->StateName( State() ) << endl ;
1040 cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
1041 << Automaton()->StateName( State() ) << endl ;
1044 if ( ControlState() == SUPERV::ToSuspendStartState ) {
1045 ControlState( SUPERV::VoidState ) ;
1049 if ( ControlState() == SUPERV::ToSuspendRunState ||
1050 ( ControlState() == SUPERV::ToSuspendState &&
1051 State() == GraphExecutor::SuspendedReadyState) ) {
1052 if ( IsSuspended() ) {
1053 if ( State() == GraphExecutor::SuspendedReadyState ) {
1057 else if ( State() == GraphExecutor::SuspendedExecutingState ) {
1059 RetVal = Component()->Resume_impl() ;
1062 cdebug << "GraphExecutor::InNode::Resume State "
1063 << Automaton()->StateName( State() ) << endl ;
1066 if ( ControlState() != SUPERV::ToSuspendState ) {
1067 ControlState( SUPERV::VoidState ) ;
1070 else if ( IsRunning() ) {
1073 else if ( IsWaiting() ) {
1074 ControlState( SUPERV::VoidState ) ;
1077 else if ( IsDone() ) {
1081 else if ( ControlState() == SUPERV::ToSuspendDoneState ||
1082 ( ControlState() == SUPERV::ToSuspendState &&
1083 State() == GraphExecutor::SuspendedSuccessedState) ) {
1084 if ( IsSuspended() ) {
1085 if ( State() == GraphExecutor::SuspendedSuccessedState ) {
1089 else if ( State() == GraphExecutor::SuspendedErroredState ) {
1094 cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
1097 if ( ControlState() != SUPERV::ToSuspendState ) {
1098 ControlState( SUPERV::VoidState ) ;
1101 else if ( IsRunning() ) {
1102 ControlState( SUPERV::VoidState ) ;
1105 else if ( IsWaiting() ) {
1106 ControlState( SUPERV::VoidState ) ;
1109 else if ( IsDone() ) {
1110 ControlState( SUPERV::VoidState ) ;
1115 cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " "
1116 << Automaton()->StateName( State() ) << endl ;
1120 bool GraphExecutor::InNode::IsWaiting() {
1122 // cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
1123 GraphExecutor::AutomatonState aState = State() ;
1124 if ( aState == GraphExecutor::DataUndefState ||
1125 aState == GraphExecutor::DataWaitingState ||
1126 aState == GraphExecutor::SuspendedReadyState )
1127 // aState == GraphExecutor::SuspendedExecutingState ||
1128 // aState == GraphExecutor::SuspendedSuccessedState ||
1129 // aState == GraphExecutor::SuspendedErroredState ||
1130 // aState == GraphExecutor::SuspendedState
1132 // cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
1136 bool GraphExecutor::InNode::IsReady() {
1138 // cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
1139 GraphExecutor::AutomatonState aState = State() ;
1140 // if ( aState == GraphExecutor::DataUndefState ||
1141 // aState == GraphExecutor::DataWaitingState ||
1142 if ( aState == GraphExecutor::DataReadyState ||
1143 aState == GraphExecutor::ResumedReadyState )
1145 // cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
1149 bool GraphExecutor::InNode::IsRunning() {
1151 // cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
1152 GraphExecutor::AutomatonState aState = State() ;
1153 if ( aState == GraphExecutor::ExecutingState ||
1154 aState == GraphExecutor::ResumedExecutingState )
1156 // cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
1160 bool GraphExecutor::InNode::IsDone() {
1162 // cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
1163 GraphExecutor::AutomatonState aState = State() ;
1164 if ( aState == GraphExecutor::KilledReadyState ||
1165 aState == GraphExecutor::StoppedReadyState ||
1166 aState == GraphExecutor::KilledExecutingState ||
1167 aState == GraphExecutor::StoppedExecutingState ||
1168 aState == GraphExecutor::SuspendedSuccessedState ||
1169 aState == GraphExecutor::SuspendedErroredState ||
1170 // aState == GraphExecutor::SuccessedExecutingState ||
1171 // aState == GraphExecutor::ErroredExecutingState ||
1172 aState == GraphExecutor::SuccessedState ||
1173 aState == GraphExecutor::ErroredState ||
1174 aState == GraphExecutor::ResumedSuccessedState ||
1175 aState == GraphExecutor::ResumedErroredState ||
1176 aState == GraphExecutor::KilledSuccessedState ||
1177 aState == GraphExecutor::StoppedSuccessedState )
1179 // cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
1183 bool GraphExecutor::InNode::IsSuspended() {
1185 // cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
1186 GraphExecutor::AutomatonState aState = State() ;
1187 if ( aState == GraphExecutor::SuspendedReadyState ||
1188 aState == GraphExecutor::SuspendedExecutingState ||
1189 aState == GraphExecutor::SuspendedSuccessedState ||
1190 aState == GraphExecutor::SuspendedErroredState ||
1191 aState == GraphExecutor::SuspendedState )
1193 // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
1196 bool GraphExecutor::InNode::IsKilled() {
1198 // cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
1199 GraphExecutor::AutomatonState aState = State() ;
1200 if ( aState == GraphExecutor::KilledReadyState ||
1201 aState == GraphExecutor::KilledExecutingState ||
1202 aState == GraphExecutor::KilledSuccessedState ||
1203 aState == GraphExecutor::KilledErroredState ||
1204 aState == GraphExecutor::KilledState )
1206 // cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
1209 bool GraphExecutor::InNode::IsStopped() {
1211 // cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
1212 GraphExecutor::AutomatonState aState = State() ;
1213 if ( aState == GraphExecutor::StoppedReadyState ||
1214 aState == GraphExecutor::StoppedExecutingState ||
1215 aState == GraphExecutor::StoppedSuccessedState ||
1216 aState == GraphExecutor::StoppedErroredState ||
1217 aState == GraphExecutor::StoppedState )
1219 // cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
1223 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
1224 bool RetVal = false ;
1225 if ( pthread_mutex_lock( &_MutexWait ) ) {
1226 perror("pthread_mutex_lock _Wait") ;
1230 case SUPERV::ReadyState : {
1231 RetVal = IsReady() ;
1232 cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
1233 << " " << Automaton()->StateName( _currentState )
1234 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1235 while ( !RetVal && !IsDone() ) {
1236 cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
1237 pthread_cond_wait( &_ReadyWait , &_MutexWait );
1238 RetVal = IsReady() ;
1239 cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
1240 << Automaton()->StateName( _currentState ) << " " << RetVal
1243 cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
1244 << " " << Automaton()->StateName( _currentState )
1245 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
1248 case SUPERV::RunningState : {
1249 RetVal = IsRunning() ;
1250 cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
1251 << " " << Automaton()->StateName( _currentState )
1252 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1253 // mkr : IPAL10056 : additional checking for node aborted
1254 while ( !RetVal && !IsDone() && !_OutNode->IsNodeAborted() ) {
1255 cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ;
1256 pthread_cond_wait( &_RunningWait , &_MutexWait );
1257 //We may have pthread_cond_waited but !IsRunning and !IsDone :
1258 RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState ||
1259 State() == GraphExecutor::ErroredExecutingState ;
1260 cdebug << pthread_self() << " pthread_cond_waited RunningWait "
1261 << Automaton()->StateName( _currentState ) << " " << RetVal
1262 << " " << Name() << endl ;
1264 cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
1265 << " " << Automaton()->StateName( _currentState )
1266 << " pthread_cond_wait _RunningWait " << Name() << endl ;
1269 case SUPERV::DoneState : {
1271 cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
1272 << " " << Automaton()->StateName( _currentState )
1273 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1275 cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
1276 pthread_cond_wait( &_DoneWait , &_MutexWait );
1278 cdebug << pthread_self() << " pthread_cond_waited DoneWait "
1279 << Automaton()->StateName( _currentState ) << " " << RetVal
1282 cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
1283 << " " << Automaton()->StateName( _currentState )
1284 << " pthread_cond_wait _DoneWait " << Name() << endl ;
1287 case SUPERV::SuspendState : {
1288 RetVal = IsSuspended() ;
1289 cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
1290 << " " << Automaton()->StateName( _currentState )
1291 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1292 while ( !RetVal && !IsDone() ) {
1293 cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
1294 pthread_cond_wait( &_SuspendedWait , &_MutexWait );
1295 RetVal = IsSuspended() ;
1296 cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
1297 << Automaton()->StateName( _currentState ) << " " << RetVal
1300 cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1301 << " " << Automaton()->StateName( _currentState )
1302 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1306 cdebug << " SUPERV::OutNode::StateWait Error Undefined State : "
1310 if ( pthread_mutex_unlock( &_MutexWait ) ) {
1311 perror("pthread_mutex_lock _Wait") ;
1317 bool GraphExecutor::InNode::ReadyWait() {
1318 // cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1320 aret = StateWait( SUPERV::ReadyState ) ;
1321 // cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1325 bool GraphExecutor::InNode::RunningWait() {
1326 cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1327 << " " << Automaton()->StateName( State() ) << endl;
1329 aret = StateWait( SUPERV::RunningState ) ;
1330 cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name()
1331 << " " << Automaton()->StateName( State() ) << endl;
1335 bool GraphExecutor::InNode::DoneWait() {
1336 // cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1338 aret = StateWait( SUPERV::DoneState ) ;
1342 bool GraphExecutor::InNode::SuspendedWait() {
1343 // cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1345 aret = StateWait( SUPERV::SuspendState ) ;
1349 void GraphExecutor::InNode::InitialState()
1351 cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1354 _ControlState = SUPERV::VoidState ;
1355 CreateNewThread( false ) ;
1356 //JR 15.04.2005 Debug PAL8624 RetroConception :
1357 // CreateNewThreadIf( false ) ;
1358 HasAllDataReady( false ) ;
1359 _SuspendSync = false ;
1360 _ResumeSync = false ;
1363 // asv : 13.12.04 : Decided to set "Loading" state for factory and computing nodes ONLY.
1364 // See extended comment in p.2.19 of "Bugs and Improvements" about IsLoading for InLine.
1365 if ( IsComputingNode() || IsFactoryNode() ) {
1369 // ThreadNo( pthread_self() ) ;
1372 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1373 if ( GetNodeOutPort(i)->IsDataStream() ) {
1374 GetChangeNodeOutPort(i)->PortState( SUPERV::ReadyState ) ;
1375 GetChangeNodeOutPort(i)->PortDone( true ) ;
1377 //JR Debug 01.07.2005 :
1378 // else if ( i != 0 || !IsGOTONode() ) {
1380 GetChangeNodeOutPort(i)->PortState( SUPERV::WaitingState ) ;
1381 GetChangeNodeOutPort(i)->PortDone( false ) ;
1385 int InPortsCount = GetNodeInPortsSize() ;
1386 for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1387 GraphBase::InPort * anInPort = GetChangeNodeInPort(i) ;
1388 anInPort->PortState( SUPERV::WaitingState ) ;
1389 GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1390 if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1391 anOutPort->PortStatus( DataConnected );
1392 anOutPort->PortState( SUPERV::ReadyState ) ;
1393 anOutPort->PortDone( true ) ;
1394 //JR 21.02.2005 Debug Memory leak : CORBA::Any * anAny = new CORBA::Any() ;
1395 CORBA::Any anAny = CORBA::Any() ;
1396 //JR 21.02.2005 Debug Memory leak : *anAny <<= (CORBA::Long ) 1 ;
1397 anAny <<= (CORBA::Long ) 1 ;
1398 anOutPort->SetValue( anAny ) ;
1400 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1401 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1402 << " InitLoop HeadNode" << endl ;
1404 // JR 15_09_2004 if backward link from GOTONode or EndLoopNode ==> DataConnected
1405 else if ( anInPort->IsGate() && anOutPort ) {
1406 anOutPort->PortState( SUPERV::WaitingState ) ;
1407 anOutPort->PortDone( false ) ;
1408 const GraphBase::ComputingNode * aFromNode = _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() ) ;
1409 //JR if ( aFromNode->IsGOTONode() || aFromNode->IsEndLoopNode() ) {
1410 if ( aFromNode->IsGOTONode() || ( IsLoopNode() && CoupledNode() == aFromNode ) ) {
1411 // ASV: bug with synchronization of Inline nodes (via Gate ports) fixed.
1412 // before was "else if ( IsOneOfInlineNodes() )"
1413 // IsOneOfInline() == ( Inline || IsOneOfGOTO() ), so Inline are removed..
1414 anOutPort->PortStatus( DataConnected );
1415 anOutPort->PortState( SUPERV::ReadyState ) ;
1416 anOutPort->PortDone( true ) ;
1418 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1419 << " OutPort " << anOutPort->PortStatus() << theAutomaton->StateName( anOutPort->PortState() )
1420 << " Gate HeadNode" << endl ;
1423 cdebug << Name() << " IsHeadNode " << IsHeadNode() << " InPort" << i << " "
1424 << anInPort->PortName() << " " << anInPort->PortStatus() << endl ;
1426 if ( anInPort->IsGate() && anOutPort == NULL ) {
1428 cdebug << "InPort" << i << " " << anInPort->PortName() << " Not connected InPortsCount "
1429 << InPortsCount << endl ;
1431 else if ( anOutPort ) {
1432 if ( anOutPort->IsDataConnected() || anOutPort->IsDataStream() ) {
1434 anOutPort->PortState( SUPERV::ReadyState ) ;
1435 anOutPort->PortDone( true ) ;
1436 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1437 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1438 << InPortsCount << endl ;
1440 else if ( anOutPort->IsPortConnected() ) {
1441 anOutPort->PortState( SUPERV::WaitingState ) ;
1442 anOutPort->PortDone( false ) ;
1443 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " "
1444 << anInPort->PortStatus()
1445 << " " << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1446 << InPortsCount << endl ;
1449 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << anInPort->PortStatus()
1450 << " OutPort " << anOutPort->NodeName() << " " << anOutPort->PortName() << " "
1451 << theAutomaton->StateName( anOutPort->PortState() ) << " InPortsCount "
1452 << InPortsCount << endl ;
1456 cdebug << "InPort" << i << " " << anInPort->PortName() << " " << " " << anInPort->PortStatus()
1457 << " no corresponding OutPort InPortsCount " << InPortsCount << endl ;
1460 if ( !anOutPort->IsDataStream() || anInPort->IsDataStream() ) {
1461 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1462 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1463 << " with state of OutPort : " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1464 GetChangeNodeInPort(i)->PortState( anOutPort->PortState() ) ;
1466 else if ( anOutPort->IsDataConnected() ) {
1467 cdebug << "InPort" << i << " state change : " << anInPort->PortName() << " from OutPort "
1468 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1469 << " with state ReadyState" << endl ;
1470 GetChangeNodeInPort(i)->PortState( SUPERV::ReadyState ) ;
1473 cdebug << "InPort" << i << " state NOT changed : " << anInPort->PortName() << " from OutPort "
1474 << anOutPort->PortName() << " " << anOutPort->PortStatus() << " from Node " << anOutPort->NodeName()
1475 << " with state " << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1479 cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1480 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1482 if ( anOutPort->PortState() == SUPERV::WaitingState ) {
1483 cdebug << "WaitingState" ;
1485 else if ( anOutPort->PortState() == SUPERV::ReadyState ) {
1486 cdebug << "ReadyState" ;
1491 cdebug << " OutPortStatus " << anOutPort->PortStatus() << " State "
1492 << theAutomaton->StateName( anOutPort->PortState() ) << endl ;
1496 _currentState = InPortsCount > 0 ? GraphExecutor::DataWaitingState
1497 : GraphExecutor::DataReadyState ;
1498 if ( InPortsCount == GetNodeInPortsSize() ) {
1499 _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1502 else if ( InPortsCount != 0 ) {
1503 _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1507 _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1511 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1512 cdebug << "OutPort" << i << " : " << GetNodeOutPort(i)->PortName() << " "
1513 << theAutomaton->StateName( GetChangeNodeOutPort(i)->PortState() )
1514 << " " << GetNodeOutPort(i)->Kind() << endl ;
1517 cdebug_out << "GraphExecutor::InNode::InitialState Node " << Name() << " CurrentState = "
1518 << theAutomaton->StateName( _currentState ) << " HasAllDataReady "
1519 << HasAllDataReady() << endl;
1522 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1523 //JR Look at DataFlowExecutor for the meaning of 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 // JR Debug : if we must have a python function and if we have not : error
1541 if ( PyRunMethod ) {
1542 InLineNode()->PyRunMethod( PyRunMethod ) ;
1544 else if ( WithErr && strlen( InLineNode()->PyFuncName() ) ) {
1548 Err = Err || OneErr ;
1549 if ( OneErr && WithErr ) {
1550 string anErrorMessage = string( "Error while declaring the Python function " ) +
1551 string( LoopNode()->PyFuncName() ) + string( " in Node " ) +
1553 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1555 PyMoreMethod = LoopNode()->PyMoreMethod() ;
1556 if ( PyMoreMethod ) {
1560 PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1561 LoopNode()->MorePythonFunction() ,
1563 // JR Debug : if we must have a python function and if we have not : error
1564 if ( PyMoreMethod ) {
1565 LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1567 else if ( WithErr && strlen( LoopNode()->PyMoreName() ) ) {
1571 Err = Err || OneErr ;
1572 if ( OneErr && WithErr ) {
1573 string anErrorMessage = string( "Error while declaring the Python function " ) +
1574 string( LoopNode()->PyMoreName() ) + string( " in Node " ) +
1576 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1578 PyNextMethod = LoopNode()->PyNextMethod() ;
1579 if ( PyNextMethod ) {
1583 PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1584 LoopNode()->NextPythonFunction() ,
1586 // JR Debug : if we must have a python function and if we have not : error
1587 if ( PyNextMethod ) {
1588 LoopNode()->PyNextMethod( PyNextMethod ) ;
1590 else if ( WithErr && strlen( LoopNode()->PyNextName() ) ) {
1594 Err = Err || OneErr ;
1595 if ( OneErr && WithErr ) {
1596 string anErrorMessage = string( "Error while declaring the Python function " ) +
1597 string( LoopNode()->PyNextName() ) + string( " in Node " ) +
1599 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1603 PyFuncRunned( false ) ;
1605 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) "
1606 << PyRunMethod << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod
1609 else if ( IsInLineNode() || IsSwitchNode() ) {
1610 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1611 if ( PyRunMethod ) {
1615 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1616 InLineNode()->PythonFunction() ,
1618 // JR Debug : if we must have a python function and if we have not : error
1619 if ( PyRunMethod != NULL ) {
1620 InLineNode()->PyRunMethod( PyRunMethod ) ;
1622 else if ( WithErr && strlen( InLineNode()->PyFuncName() ) ) {
1626 Err = Err || OneErr ;
1627 if ( OneErr && WithErr ) {
1628 string anErrorMessage = string( "Error while declaring the Python function " ) +
1629 string( InLineNode()->PyFuncName() ) + string( " in Node " ) +
1631 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1633 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1635 else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1636 (*InLineNode()->PythonFunction()).length() ) {
1637 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1638 if ( PyRunMethod ) {
1642 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1643 InLineNode()->PythonFunction() ,
1645 // JR Debug : if we must have a python function and if we have not : error
1646 if ( PyRunMethod != NULL ) {
1647 InLineNode()->PyRunMethod( PyRunMethod ) ;
1649 else if ( WithErr && strlen( InLineNode()->PyFuncName() ) ) {
1653 Err = Err || OneErr ;
1654 if ( OneErr && WithErr ) {
1655 string anErrorMessage = string( "Error while declaring the Python function " ) +
1656 string( InLineNode()->PyFuncName() ) + string( " in Node " ) +
1658 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1660 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1663 //JR Look at DataFlowExecutor :
1664 // Err = WithErr && Err ;
1665 cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1666 if ( WithErr && Err ) {
1667 cdebug << " Error " << WithErr && Err ;
1673 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1674 CORBA::Long cpu = 0 ;
1675 // cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " ) " << Name() << endl ;
1676 // cout << "Begin CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1677 // << theAutomaton->StateName( _currentState ) << endl ;
1678 if ( IsOneOfInLineNodes() ) {
1679 // cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1680 // cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1681 cpu = PyCpuUsed( tot ) ;
1684 if ( !CORBA::is_nil( Component() ) ) {
1685 // cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1686 // cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1688 cpu = Component()->CpuUsed_impl() ;
1691 if ( _OutNode->IsDone() ) {
1692 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() WARNING catched Graph is done "
1693 << Automaton()->StateName( _OutNode->State() ) << endl ;
1696 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() WARNING catched "
1697 << Automaton()->StateName( _OutNode->State() ) << endl ;
1698 //JR NPAL14110 09.02.2007 : If there is a shutdown of components ===> NodeState must not
1699 // be aborted ... ==> Commented :
1700 //JRState( GraphExecutor::ErroredState ) ;
1701 //JR_OutNode->State( GraphExecutor::ErroredState ) ;
1707 cdebug << "CpuUsed " << Name() << " Component() is NIL" << endl ;
1711 // cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1712 // cout << "End CpuUsed " << Name() << " CpuUsed : " << cpu << " State "
1713 // << theAutomaton->StateName( _currentState ) << endl ;
1717 #include <sys/time.h>
1718 #include <sys/resource.h>
1721 long GraphExecutor::InNode::PyCpu() {
1722 struct rusage usage ;
1724 if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1725 perror("GraphExecutor::InNode::PyCpu") ;
1728 // return usage.ru_utime.__time_t tv_sec ;
1729 // cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1730 // << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1732 cpu = usage.ru_utime.tv_sec ;
1736 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1738 if ( _PyTotCpuUsed == -1 ) {
1739 if ( _Pythread == pthread_self() ) {
1740 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1741 // << " _PyTotCpuUsed " << _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1742 // << _PyCpuUsed << endl ;
1743 cpu = PyCpu() - _PyCpuUsed ;
1745 _PyTotCpuUsed = cpu ;
1753 cpu = _PyTotCpuUsed ;
1755 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1756 // << _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1760 void GraphExecutor::InNode::SetPyCpuUsed() {
1761 _PyTotCpuUsed = -1 ;
1763 _Pythread = pthread_self() ;
1764 _PyCpuUsed = PyCpu() ;
1765 // cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1766 // << _PyCpuUsed << endl ;
1769 void GraphExecutor::InNode::IsLoading( bool Loading ) {
1770 _Loading = Loading ;
1772 // asv : 09.12.04 : "Bugs and Improvents" 2.19 : how it works:
1773 // LoadingState is returned by OutNode::State( NodeName ) if InNode->IsLoading()
1774 // after Loading is finished (here below), ExecutingState must be pushed for GUI.
1776 _OutNode->PushEvent( this, GraphExecutor::ExecuteEvent, GraphExecutor::ExecutingState );