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
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_OutNode.hxx"
52 static void InitInNode( int &_RewindStack ,
53 SUPERV::ControlState &_ControlState ,
54 SUPERV::AutomatonState &_currentState ,
55 GraphExecutor::InNode ** _aReStartNode ,
56 bool & _PyFuncRunned ,
57 PyObject ** _MyPyRunMethod ,
58 pthread_mutex_t &_MutexDataWait ,
60 pthread_mutex_t &_MutexWait ,
61 pthread_cond_t &_ReadyWait ,
62 pthread_cond_t &_RunningWait ,
63 pthread_cond_t &_DoneWait ,
64 pthread_cond_t &_SuspendedWait ,
65 pthread_cond_t &_SuspendWait ,
67 pthread_cond_t &_ResumeWait ,
69 pthread_cond_t &_KillWait ,
71 pthread_cond_t &_ThreadStartedWait ,
72 bool &_ThreadStartedSync ,
73 pthread_cond_t &_StopWait ,
74 GraphExecutor::FiniteStateMachine ** _Automaton ,
75 GraphExecutor::FiniteStateMachine * theAutomaton ,
76 CORBA::ORB_ptr * _Orb ,
77 CORBA::ORB_ptr ORB ) {
79 _ControlState = SUPERV::VoidState ;
80 _currentState = SUPERV::UnKnownState ;
81 *_aReStartNode = NULL ;
82 _PyFuncRunned = false ;
83 *_MyPyRunMethod = NULL ;
84 pthread_mutex_init( &_MutexDataWait , NULL ) ;
86 pthread_mutex_init( &_MutexWait , NULL ) ;
87 if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
88 perror("pthread_cond_init( &_ReadyWait , NULL )") ;
91 if ( pthread_cond_init( &_RunningWait , NULL ) ) {
92 perror("pthread_cond_init( &_RunningWait , NULL )") ;
95 if ( pthread_cond_init( &_DoneWait , NULL ) ) {
96 perror("pthread_cond_init( &_DoneWait , NULL )") ;
99 if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
100 perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
103 if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
104 perror("pthread_cond_init( &_SuspendWait , NULL )") ;
107 _SuspendSync = false ;
108 if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
109 perror("pthread_cond_init( &_ResumeWait , NULL )") ;
112 _ResumeSync = false ;
113 if ( pthread_cond_init( &_KillWait , NULL ) ) {
114 perror("pthread_cond_init( &_KillWait , NULL )") ;
118 if ( pthread_cond_init( &_ThreadStartedWait , NULL ) ) {
119 perror("pthread_cond_init( &_ThreadStartedWait , NULL )") ;
122 _ThreadStartedSync = false ;
123 if ( pthread_cond_init( &_StopWait , NULL ) ) {
124 perror("pthread_cond_init( &_StopWait , NULL )") ;
127 *_Automaton = theAutomaton ;
128 *_Orb = CORBA::ORB::_nil();
131 GraphExecutor::FiniteStateMachine * theAutomaton = new GraphExecutor::FiniteStateMachine() ;
133 //GraphExecutor::InNode::InNode() :
134 // GraphBase::FactoryNode() {
135 GraphExecutor::InNode::InNode() {
136 InitInNode( _RewindStack ,
161 CORBA::ORB::_nil() ) ;
164 GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB,
165 SALOME_NamingService* ptrNamingService ,
166 const SALOME_ModuleCatalog::Service& aService ,
167 const char * ComponentName ,
168 const char * NodeInterfaceName ,
169 const char * NodeName ,
170 const SUPERV::KindOfNode akind ,
171 GraphBase::ListOfFuncName aFuncName ,
172 GraphBase::ListOfPythonFunctions aPythonFunction ,
173 const SUPERV::SDate NodeFirstCreation ,
174 const SUPERV::SDate NodeLastModification ,
175 const char * NodeEditorRelease ,
176 const char * NodeAuthor ,
177 const char * NodeComputer ,
178 const char * NodeComment ,
179 const bool GeneratedName ,
182 int * Graph_prof_debug,
183 ofstream * Graph_fdebug) {
184 // ostream * Graph_fdebug = NULL ) :
185 // GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
186 // ComponentName , NodeInterfaceName ,
187 // NodeName , akind ,
188 // NodeFirstCreation , NodeLastModification ,
189 // NodeEditorRelease , NodeAuthor ,
190 // NodeComputer , NodeComment , GeneratedName ,
192 // Graph_prof_debug , Graph_fdebug ) {
193 InitInNode( _RewindStack ,
219 SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
221 _ComputingNode = NULL ;
222 _FactoryNode = NULL ;
226 _EndOfLoopNode = NULL ;
228 _EndOfSwitchNode = NULL ;
230 case SUPERV::ComputingNode : {
231 cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
232 _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
236 NodeLastModification ,
237 NodeEditorRelease , NodeAuthor ,
238 NodeComment , GeneratedName ,
240 Graph_prof_debug , Graph_fdebug ) ;
243 case SUPERV::FactoryNode : {
244 cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
245 _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
246 ComponentName , NodeInterfaceName ,
249 NodeLastModification ,
250 NodeEditorRelease , NodeAuthor ,
251 NodeComputer , NodeComment ,
252 GeneratedName , NodeX , NodeY ,
253 Graph_prof_debug , Graph_fdebug ) ;
254 _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
257 case SUPERV::InLineNode : {
258 cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
259 _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
260 aFuncName[0].c_str() , *aPythonFunction[0] ,
262 NodeFirstCreation , NodeLastModification ,
263 NodeEditorRelease , NodeAuthor ,
264 NodeComment , GeneratedName ,
266 Graph_prof_debug , Graph_fdebug ) ;
267 _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
270 case SUPERV::GOTONode : {
271 cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
272 _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
273 aFuncName[0].c_str() , *aPythonFunction[0] ,
275 NodeFirstCreation , NodeLastModification ,
276 NodeEditorRelease , NodeAuthor ,
277 NodeComment , GeneratedName ,
279 Graph_prof_debug , Graph_fdebug ) ;
280 _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
281 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
284 case SUPERV::LoopNode : {
285 cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
286 _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
287 aFuncName[0].c_str() , *aPythonFunction[0] ,
288 aFuncName[1].c_str() , *aPythonFunction[1] ,
289 aFuncName[2].c_str() , *aPythonFunction[2] ,
291 NodeFirstCreation , NodeLastModification ,
292 NodeEditorRelease , NodeAuthor ,
293 NodeComment , GeneratedName ,
295 Graph_prof_debug , Graph_fdebug ) ;
296 _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
297 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
298 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
301 case SUPERV::EndLoopNode : {
302 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
303 _EndOfLoopNode = new GraphBase::EndOfLoopNode(
304 ORB , ptrNamingService ,
305 aFuncName[0].c_str() , *aPythonFunction[0] ,
307 NodeFirstCreation , NodeLastModification ,
308 NodeEditorRelease , NodeAuthor ,
309 NodeComment , GeneratedName ,
311 Graph_prof_debug , Graph_fdebug ) ;
312 _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
313 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
314 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
317 case SUPERV::SwitchNode : {
318 cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
319 _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
320 aFuncName[0].c_str() , *aPythonFunction[0] ,
322 NodeFirstCreation , NodeLastModification ,
323 NodeEditorRelease , NodeAuthor ,
324 NodeComment , GeneratedName ,
326 Graph_prof_debug , Graph_fdebug ) ;
327 _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
328 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
329 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
332 case SUPERV::EndSwitchNode : {
333 cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
334 _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
335 ORB , ptrNamingService ,
336 aFuncName[0].c_str() , *aPythonFunction[0] ,
338 NodeFirstCreation , NodeLastModification ,
339 NodeEditorRelease , NodeAuthor ,
340 NodeComment , GeneratedName ,
342 Graph_prof_debug , Graph_fdebug ) ;
343 _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
344 _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
345 _InLineNode = (GraphBase::InLineNode *) _ComputingNode ;
348 case SUPERV::DataFlowNode : {
349 cdebug << "GraphEditor::InNode::InNode SUPERV::DataFlowNode ERROR : " << NodeName ;
351 case SUPERV::UnknownNode : {
352 cdebug << "GraphEditor::InNode::InNode SUPERV::UnknownNode ERROR : " << NodeName ;
355 cdebug << "GraphExecutor::InNode::InNode " << (void *) this
356 << " _ComputingNode " << (void *) _ComputingNode ;
357 _ComputingNode->InNode( this ) ;
360 GraphExecutor::InNode::~InNode() {
363 void GraphExecutor::InNode::LockDataWait() {
364 if ( pthread_mutex_lock( &_MutexDataWait ) ) {
365 perror("Ready pthread_mutex_lock ") ;
370 void GraphExecutor::InNode::UnLockDataWait() {
372 if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
373 perror("Ready pthread_mutex_unlock ") ;
378 Engines::Component_var GraphExecutor::InNode::Component() const {
379 if ( IsFactoryNode() ) {
380 return _FactoryNode->Component() ;
383 CORBA::Any const * anAnyComponent = GetChangeNodeInPort( 0 )->GetOutPort()->Value() ; // this
384 CORBA::Object_ptr obj ;
386 *anAnyComponent >>= obj ;
387 return Engines::Component::_narrow( obj ) ;
390 cdebug << "GraphExecutor::InNode::Component Component catch" << endl ;
393 return Engines::Component::_nil() ;
396 Engines::Container_var GraphExecutor::InNode::Container() const {
397 if ( IsFactoryNode() ) {
398 return _FactoryNode->Container() ;
400 return Engines::Container::_nil() ;
404 bool GraphExecutor::InNode::Ping() {
405 // cdebug_in << "GraphExecutor::InNode::Ping" << endl;
407 if ( IsFactoryNode() ) {
408 RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
410 if ( State() != SUPERV::SuspendedExecutingState ) {
411 _FactoryNode->Component()->ping() ;
418 // cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
422 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
423 ThreadNo ( aThread ) ;
425 _OutNode->NewThread() ;
427 void GraphExecutor::InNode::ExitThread() {
429 _OutNode->ExitThread() ;
432 bool GraphExecutor::InNode::Suspend() {
433 cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
437 ControlState( SUPERV::VoidState ) ;
438 if ( _OutNode->IsDone() ) {
439 ControlState( SUPERV::VoidState ) ;
443 else if ( IsWaiting() || IsReady() ) {
444 ControlState( SUPERV::ToSuspendState ) ;
447 else if ( IsRunning() ) {
448 ControlState( SUPERV::ToSuspendState ) ;
449 if ( IsFactoryNode() || IsComputingNode() ) {
450 if ( !CORBA::is_nil( Component() ) ) {
451 RetVal = Component()->Suspend_impl() ;
454 cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name()
455 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
456 SendEvent( GraphExecutor::SuspendEvent ) ;
457 cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container"
458 << Name() << " --> thread" << ThreadNo() << endl;
460 else if ( IsDone() ) {
461 ControlState( SUPERV::VoidState ) ;
462 RetVal = false ; // Too late ...
465 cdebug << "component Suspended and !IsDone and !IsRunning !"
471 cdebug << "Suspend cannot Suspend component !" << endl ;
476 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
481 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
485 cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " "
486 << Automaton()->StateName( State() ) << endl ;
490 bool GraphExecutor::InNode::ContainerKill() {
491 cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
492 << ThreadNo() << endl;
494 if ( IsFactoryNode() ) {
496 RetVal = Container()->Kill_impl() ;
498 cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
502 bool GraphExecutor::InNode::Kill() {
503 cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " "
504 << Automaton()->StateName( State() ) << endl;
507 ControlState( SUPERV::ToKillState ) ; // if loop
508 if ( _OutNode->IsDone() ) {
509 ControlState( SUPERV::VoidState ) ;
514 ControlState( SUPERV::ToKillState ) ;
516 if ( _OutNode->IsDone() ) {
517 ControlState( SUPERV::VoidState ) ;
523 if ( IsFactoryNode() || IsComputingNode() ) {
524 if ( !CORBA::is_nil( Component() ) ) {
525 RetVal = Component()->Kill_impl() ;
526 cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ;
529 cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name()
530 << " --> thread" << ThreadNo() << " SuspendEvent " << endl;
531 SendEvent( GraphExecutor::KillEvent ) ;
532 cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container"
533 << Name() << " --> thread" << ThreadNo() << endl;
535 else if ( IsDone() ) {
536 ControlState( SUPERV::VoidState ) ;
537 RetVal = false ; // Too late ...
540 cdebug << "component Killed and !IsDone and !IsRunning !"
545 cdebug << "Kill with nilComponent cannot Kill component !" << endl ;
550 else if ( IsSuspended() ) {
551 cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name()
552 << " --> thread" << ThreadNo() << " Resume()" << endl;
556 else if ( IsWaiting() ) {
560 cdebug << "Kill and !IsDone and !IsRunning and !IsWaiting ?"
566 cdebug_out << "GraphExecutor::InNode::Kill" << endl ;
570 bool GraphExecutor::InNode::KillDone() {
571 cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
574 if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
578 ControlState( SUPERV::ToKillDoneState ) ;
580 if ( _OutNode->IsDone() ) {
581 ControlState( SUPERV::VoidState ) ;
589 else if ( IsWaiting() ) {
593 cdebug << "KillDone and !IsDone and !IsRunning and !IsWaiting ?"
599 cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
603 bool GraphExecutor::InNode::Stop() {
604 cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
607 if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
611 ControlState( SUPERV::ToStopState ) ;
613 if ( _OutNode->IsDone() ) {
614 ControlState( SUPERV::VoidState ) ;
620 if ( IsFactoryNode() || IsComputingNode() ) {
621 if ( !CORBA::is_nil( Component() ) ) {
622 RetVal = Component()->Stop_impl() ;
625 SendEvent( GraphExecutor::StopEvent ) ;
627 else if ( IsDone() ) {
628 ControlState( SUPERV::VoidState ) ;
629 RetVal = false ; // Too late ...
632 cdebug << "component Suspended and !IsDone and !IsRunning !"
638 cdebug << "Suspend cannot Suspend component !" << endl ;
643 cdebug << "Suspend with nilComponent while RunningState !" << endl ;
647 else if ( IsWaiting() ) {
651 cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
657 cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
661 bool GraphExecutor::InNode::SuspendDone() {
662 cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
663 << ThreadNo() << endl;
665 if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
669 ControlState( SUPERV::ToSuspendDoneState ) ;
671 if ( _OutNode->IsDone() ) {
672 ControlState( SUPERV::VoidState ) ;
680 cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
684 bool GraphExecutor::InNode::Resume() {
685 cdebug_in << pthread_self() << "/" << ThreadNo()
686 << " GraphExecutor::InNode::Resume " << Name() << " "
687 << Automaton()->StateName( State() ) << endl;
688 bool RetVal = false ;
689 if ( IsSuspended() ) {
690 if ( State() == SUPERV::SuspendedReadyState ) {
691 ResumeAction( GraphExecutor::ToResumeEvent ) ;
694 else if ( State() == SUPERV::SuspendedExecutingState ) {
695 if ( IsFactoryNode() || IsComputingNode() ) {
696 RetVal = Component()->Resume_impl() ;
699 else if ( State() == SUPERV::SuspendedSuccessedState ) {
700 ResumeAction( GraphExecutor::ResumeEvent ) ;
703 else if ( State() == SUPERV::SuspendedErroredState ) {
704 ResumeAction( GraphExecutor::ResumeEvent ) ;
708 cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
709 << Automaton()->StateName( State() ) << endl ;
714 cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
715 << Automaton()->StateName( State() ) << endl ;
718 if ( ControlState() == SUPERV::ToSuspendStartState ) {
719 ControlState( SUPERV::VoidState ) ;
723 if ( ControlState() == SUPERV::ToSuspendRunState ||
724 ( ControlState() == SUPERV::ToSuspendState &&
725 State() == SUPERV::SuspendedReadyState) ) {
726 if ( IsSuspended() ) {
727 if ( State() == SUPERV::SuspendedReadyState ) {
731 else if ( State() == SUPERV::SuspendedExecutingState ) {
733 RetVal = Component()->Resume_impl() ;
736 cdebug << "GraphExecutor::InNode::Resume State "
737 << Automaton()->StateName( State() ) << endl ;
740 if ( ControlState() != SUPERV::ToSuspendState ) {
741 ControlState( SUPERV::VoidState ) ;
744 else if ( IsRunning() ) {
747 else if ( IsWaiting() ) {
748 ControlState( SUPERV::VoidState ) ;
751 else if ( IsDone() ) {
755 else if ( ControlState() == SUPERV::ToSuspendDoneState ||
756 ( ControlState() == SUPERV::ToSuspendState &&
757 State() == SUPERV::SuspendedSuccessedState) ) {
758 if ( IsSuspended() ) {
759 if ( State() == SUPERV::SuspendedSuccessedState ) {
763 else if ( State() == SUPERV::SuspendedErroredState ) {
768 cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
771 if ( ControlState() != SUPERV::ToSuspendState ) {
772 ControlState( SUPERV::VoidState ) ;
775 else if ( IsRunning() ) {
776 ControlState( SUPERV::VoidState ) ;
779 else if ( IsWaiting() ) {
780 ControlState( SUPERV::VoidState ) ;
783 else if ( IsDone() ) {
784 ControlState( SUPERV::VoidState ) ;
789 cdebug_out << "GraphExecutor::InNode::Resume " << RetVal << endl ;
793 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
794 const bool AndSuspend ) {
795 bool RetVal = false ;
796 GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->GetGraphNode( AtNodeName )->GetInNode() ;
797 cdebug_in << pthread_self() << "/" << ThreadNo()
798 << " --> GraphExecutor::InNode::ReStartAt( "
799 << AtNodeName << " , " << AndSuspend << ") " << endl
800 << "thread " << aRestartNode->ThreadNo() << " "
801 << Automaton()->StateName( aRestartNode->State() )
802 << " from " << Name() << " " << Automaton()->StateName( State() )
804 if ( IsWaiting() && aRestartNode->IsSuspended() ) {
805 RetVal = aRestartNode->Resume() ;
807 else if ( IsSuspended() ) {
808 if ( strcmp( AtNodeName , Name() ) ) {
809 aRestartNode->State( SUPERV::SuspendedSuccessedState ) ;
812 ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
815 ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
819 cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << endl ;
823 bool GraphExecutor::InNode::IsWaiting() {
825 // cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
826 SUPERV::AutomatonState aState = State() ;
827 if ( aState == SUPERV::DataUndefState ||
828 aState == SUPERV::DataWaitingState ||
829 aState == SUPERV::SuspendedReadyState )
830 // aState == SUPERV::SuspendedExecutingState ||
831 // aState == SUPERV::SuspendedSuccessedState ||
832 // aState == SUPERV::SuspendedErroredState ||
833 // aState == SUPERV::SuspendedState
835 // cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
839 bool GraphExecutor::InNode::IsReady() {
841 // cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
842 SUPERV::AutomatonState aState = State() ;
843 if ( aState == SUPERV::DataUndefState ||
844 aState == SUPERV::DataWaitingState ||
845 aState == SUPERV::DataReadyState ||
846 aState == SUPERV::ResumedReadyState )
848 // cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
852 bool GraphExecutor::InNode::IsRunning() {
854 // cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
855 SUPERV::AutomatonState aState = State() ;
856 if ( aState == SUPERV::ExecutingState ||
857 aState == SUPERV::ResumedExecutingState )
859 // cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
863 bool GraphExecutor::InNode::IsDone() {
865 // cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
866 SUPERV::AutomatonState aState = State() ;
867 if ( aState == SUPERV::KilledReadyState ||
868 aState == SUPERV::StoppedReadyState ||
869 aState == SUPERV::KilledExecutingState ||
870 aState == SUPERV::StoppedExecutingState ||
871 aState == SUPERV::SuspendedSuccessedState ||
872 aState == SUPERV::SuspendedErroredState ||
873 // aState == SUPERV::SuccessedExecutingState ||
874 // aState == SUPERV::ErroredExecutingState ||
875 aState == SUPERV::SuccessedState ||
876 aState == SUPERV::ErroredState ||
877 aState == SUPERV::ResumedSuccessedState ||
878 aState == SUPERV::ResumedErroredState ||
879 aState == SUPERV::KilledSuccessedState ||
880 aState == SUPERV::StoppedSuccessedState )
882 // cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
886 bool GraphExecutor::InNode::IsSuspended() {
888 // cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
889 SUPERV::AutomatonState aState = State() ;
890 if ( aState == SUPERV::SuspendedReadyState ||
891 aState == SUPERV::SuspendedExecutingState ||
892 aState == SUPERV::SuspendedSuccessedState ||
893 aState == SUPERV::SuspendedErroredState )
895 // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
898 bool GraphExecutor::InNode::IsKilled() {
900 // cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
901 SUPERV::AutomatonState aState = State() ;
902 if ( aState == SUPERV::KilledReadyState ||
903 aState == SUPERV::KilledExecutingState ||
904 aState == SUPERV::KilledSuccessedState ||
905 aState == SUPERV::KilledErroredState ||
906 aState == SUPERV::KilledState )
908 // cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
911 bool GraphExecutor::InNode::IsStopped() {
913 // cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
914 SUPERV::AutomatonState aState = State() ;
915 if ( aState == SUPERV::StoppedReadyState ||
916 aState == SUPERV::StoppedExecutingState ||
917 aState == SUPERV::StoppedSuccessedState ||
918 aState == SUPERV::StoppedErroredState ||
919 aState == SUPERV::StoppedState )
921 // cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
925 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
926 bool RetVal = false ;
927 if ( pthread_mutex_lock( &_MutexWait ) ) {
928 perror("pthread_mutex_lock _Wait") ;
932 case SUPERV::ReadyState : {
934 cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
935 << " " << Automaton()->StateName( _currentState )
936 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
937 while ( !RetVal && !IsDone() ) {
938 cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
939 pthread_cond_wait( &_ReadyWait , &_MutexWait );
941 cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
942 << Automaton()->StateName( _currentState ) << " " << RetVal
945 cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
946 << " " << Automaton()->StateName( _currentState )
947 << " pthread_cond_wait _ReadyWait " << Name() << endl ;
950 case SUPERV::RunningState : {
951 RetVal = IsRunning() ;
952 cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
953 << " " << Automaton()->StateName( _currentState )
954 << " pthread_cond_wait _RunningWait " << Name() << endl ;
955 while ( !RetVal && !IsDone() ) {
956 cdebug << pthread_self() << " pthread_cond_wait RunningWait" << endl ;
957 pthread_cond_wait( &_RunningWait , &_MutexWait );
958 RetVal = IsRunning() ;
959 cdebug << pthread_self() << " pthread_cond_waited RunningWait "
960 << Automaton()->StateName( _currentState ) << " " << RetVal
963 cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
964 << " " << Automaton()->StateName( _currentState )
965 << " pthread_cond_wait _RunningWait " << Name() << endl ;
968 case SUPERV::DoneState : {
970 cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
971 << " " << Automaton()->StateName( _currentState )
972 << " pthread_cond_wait _DoneWait " << Name() << endl ;
974 cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
975 pthread_cond_wait( &_DoneWait , &_MutexWait );
977 cdebug << pthread_self() << " pthread_cond_waited DoneWait "
978 << Automaton()->StateName( _currentState ) << " " << RetVal
981 cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
982 << " " << Automaton()->StateName( _currentState )
983 << " pthread_cond_wait _DoneWait " << Name() << endl ;
986 case SUPERV::SuspendState : {
987 RetVal = IsSuspended() ;
988 cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
989 << " " << Automaton()->StateName( _currentState )
990 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
991 while ( !RetVal && !IsDone() ) {
992 cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
993 pthread_cond_wait( &_SuspendedWait , &_MutexWait );
994 RetVal = IsSuspended() ;
995 cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
996 << Automaton()->StateName( _currentState ) << " " << RetVal
999 cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
1000 << " " << Automaton()->StateName( _currentState )
1001 << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
1005 cdebug << " GraphExecutor::OutNode::StateWait Error Undefined State : "
1009 if ( pthread_mutex_unlock( &_MutexWait ) ) {
1010 perror("pthread_mutex_lock _Wait") ;
1016 bool GraphExecutor::InNode::ReadyWait() {
1017 // cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
1019 aret = StateWait( SUPERV::ReadyState ) ;
1020 // cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
1024 bool GraphExecutor::InNode::RunningWait() {
1025 // cdebug_in << "GraphExecutor::InNode::RunningWait " << Name() << endl;
1027 aret = StateWait( SUPERV::RunningState ) ;
1031 bool GraphExecutor::InNode::DoneWait() {
1032 // cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
1034 aret = StateWait( SUPERV::DoneState ) ;
1038 bool GraphExecutor::InNode::SuspendedWait() {
1039 // cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
1041 aret = StateWait( SUPERV::SuspendState ) ;
1045 void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
1047 cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
1049 _OutNode = theOutNode ;
1052 _ControlState = SUPERV::VoidState ;
1053 CreateNewThread( false ) ;
1054 CreateNewThreadIf( false ) ;
1055 _SuspendSync = false ;
1056 _ResumeSync = false ;
1057 // ThreadNo( pthread_self() ) ;
1060 for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1061 if ( i != 0 || !IsGOTONode() ) {
1062 GetChangeNodeOutPort(i)->State( SUPERV::WaitingState ) ;
1063 GetChangeNodeOutPort(i)->Done( false ) ;
1067 int Pc = GetNodeInPortsSize() ;
1068 for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1069 const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1070 GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1071 if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1072 anOutPort->PortStatus( DataConnected );
1073 anOutPort->State( SUPERV::ReadyState ) ;
1074 anOutPort->Done( true ) ;
1075 CORBA::Any * anAny = new CORBA::Any() ;
1076 *anAny <<= (long ) 1 ;
1077 anOutPort->Value( anAny ) ;
1079 else if ( anInPort->IsGate() && anOutPort ) {
1080 if ( IsComputingNode() || IsFactoryNode() ) {
1081 anOutPort->State( SUPERV::WaitingState ) ;
1082 anOutPort->Done( false ) ;
1084 else if ( IsOneOfInLineNodes() ) {
1085 anOutPort->PortStatus( DataConnected );
1086 anOutPort->State( SUPERV::ReadyState ) ;
1087 anOutPort->Done( true ) ;
1090 // if ( ( anInPort->IsGate() || anInPort->IsBus() ) && anOutPort == NULL ) {
1091 if ( anInPort->IsGate() && anOutPort == NULL ) {
1095 if ( anOutPort->IsDataConnected() ) {
1098 if ( anOutPort->IsPortConnected() ) {
1099 anOutPort->State( SUPERV::WaitingState ) ;
1100 anOutPort->Done( false ) ;
1102 else if ( anOutPort->IsDataConnected() ) {
1103 anOutPort->State( SUPERV::ReadyState ) ;
1104 anOutPort->Done( true ) ;
1108 GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1111 cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1112 << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1114 if ( anOutPort->State() == SUPERV::WaitingState ) {
1115 cdebug << "WaitingState" ;
1117 else if ( anOutPort->State() == SUPERV::ReadyState ) {
1118 cdebug << "ReadyState" ;
1123 cdebug << " PortConnected("
1124 << anOutPort->IsPortConnected() << ") DataConnected("
1125 << anOutPort->IsDataConnected() << ")" << endl ;
1129 _currentState = Pc > 0 ? SUPERV::DataWaitingState
1130 : SUPERV::DataReadyState ;
1131 if ( Pc == GetNodeInPortsSize() ) {
1132 _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1135 else if ( Pc != 0 ) {
1136 _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1140 _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1143 cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1146 cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1149 bool GraphExecutor::InNode::InitPythonFunctions(bool WithErr ) {
1150 cdebug_in << "GraphExecutor::InNode::InitPythonFunctions " << Name() << endl;
1152 if ( !PyFuncRunned() && IsOneOfInLineNodes() ) {
1153 if ( IsLoopNode() ) {
1154 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1155 if ( PyRunMethod ) {
1158 PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1159 InLineNode()->PythonFunction() ) ;
1160 InLineNode()->PyRunMethod( PyRunMethod ) ;
1162 PyObject * PyMoreMethod = LoopNode()->PyMoreMethod() ;
1163 if ( PyMoreMethod ) {
1166 PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1167 LoopNode()->MorePythonFunction() ) ;
1168 LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1170 PyObject * PyNextMethod = LoopNode()->PyNextMethod() ;
1171 if ( PyNextMethod ) {
1174 PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1175 LoopNode()->NextPythonFunction() ) ;
1176 LoopNode()->PyNextMethod( PyNextMethod ) ;
1178 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod(Init) " << PyRunMethod
1179 << " PyMoreMethod " << PyMoreMethod << " PyNextMethod " << PyNextMethod << endl;
1180 Err = !PyRunMethod || !PyMoreMethod || !PyNextMethod ;
1182 else if ( IsInLineNode() || IsSwitchNode() ) {
1183 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1184 if ( PyRunMethod ) {
1187 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1188 InLineNode()->PythonFunction() ) ;
1189 InLineNode()->PyRunMethod( PyRunMethod ) ;
1191 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1192 Err = !PyRunMethod ;
1194 else if ( ( IsEndLoopNode() || IsEndSwitchNode() || IsGOTONode() ) &&
1195 (*InLineNode()->PythonFunction()).length() ) {
1196 PyObject * PyRunMethod = InLineNode()->PyRunMethod() ;
1197 if ( PyRunMethod ) {
1200 PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1201 InLineNode()->PythonFunction() ) ;
1202 InLineNode()->PyRunMethod( PyRunMethod ) ;
1204 cdebug << "GraphExecutor::InNode::InitPythonFunctions " << Name() << " PyRunMethod " << PyRunMethod << endl;
1205 Err = !PyRunMethod ;
1208 Err = WithErr && Err ;
1209 cdebug_out << "GraphExecutor::InNode::InitPythonFunctions " << Name() ;
1211 cdebug << " Error " << Err ;
1217 const long GraphExecutor::InNode::CpuUsed( bool tot ) {
1218 CORBA::Long cpu = 0 ;
1219 // cdebug_in << "GraphExecutor::InNode::CpuUsed( " << tot << " )" << Name() << endl ;
1220 if ( IsOneOfInLineNodes() ) {
1221 // cdebug << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1222 // cout << "CpuUsed " << Name() << " --> PyCpuUsed()" << endl ;
1223 cpu = PyCpuUsed( tot ) ;
1226 if ( !CORBA::is_nil( Component() ) ) {
1227 // cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1228 // cout << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl()" << endl ;
1230 cpu = Component()->CpuUsed_impl() ;
1233 cdebug << "CpuUsed " << Name() << " --> Component()->CpuUsed_impl() ERROR catched " << endl ;
1238 // cdebug_out << "GraphExecutor::InNode::CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1239 // cout << "CpuUsed " << Name() << " CpuUsed : " << cpu << endl ;
1243 #include <sys/time.h>
1244 #include <sys/resource.h>
1247 long GraphExecutor::InNode::PyCpu() {
1248 struct rusage usage ;
1250 if ( getrusage( RUSAGE_SELF , &usage ) == -1 ) {
1251 perror("GraphExecutor::InNode::PyCpu") ;
1254 // return usage.ru_utime.__time_t tv_sec ;
1255 // cdebug << pthread_self() << "PyCpu " << Name() << " " << usage.ru_utime.tv_sec << " "
1256 // << usage.ru_utime.tv_usec << " " << usage.ru_stime.tv_sec << " " << usage.ru_stime.tv_usec
1258 cpu = usage.ru_utime.tv_sec ;
1262 long GraphExecutor::InNode::PyCpuUsed( bool tot ) {
1264 if ( _PyTotCpuUsed == -1 ) {
1265 if ( _Pythread == pthread_self() ) {
1266 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name()
1267 // << " _PyTotCpuUsed " << _PyTotCpuUsed << " PyCpu() " << PyCpu() << " - " << " _PyCpuUsed "
1268 // << _PyCpuUsed << endl ;
1269 cpu = PyCpu() - _PyCpuUsed ;
1271 _PyTotCpuUsed = cpu ;
1279 cpu = _PyTotCpuUsed ;
1281 // cdebug << pthread_self() << "GraphExecutor::InNode::PyCpuUsed(" << tot << ") " << Name() << "_PyTotCpuUsed"
1282 // << _PyTotCpuUsed << " CpuUsed : " << cpu << endl ;
1286 void GraphExecutor::InNode::SetPyCpuUsed() {
1287 _PyTotCpuUsed = -1 ;
1289 _Pythread = pthread_self() ;
1290 _PyCpuUsed = PyCpu() ;
1291 // cdebug << pthread_self() << "GraphExecutor::InNode::SetPyCpuUsed " << Name() << " _PyCpuUsed : "
1292 // << _PyCpuUsed << endl ;