From: rahuel Date: Wed, 8 Dec 2004 13:29:58 +0000 (+0000) Subject: Management of loading of a Component in a Container for Kill, Suspend because it... X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a298c8a5c1cde182f6ec183b04cac8b74bbe791b;p=modules%2Fsuperv.git Management of loading of a Component in a Container for Kill, Suspend because it is not possible to call the corresponding method in the Container at that time. Kill, Suspend and Resume are now possible for InLineNodes. But they do not run for MacroNodes : developpement is necessary. --- diff --git a/src/GraphExecutor/DataFlowExecutor_InNode.cxx b/src/GraphExecutor/DataFlowExecutor_InNode.cxx index 485e76d..32e7cd5 100644 --- a/src/GraphExecutor/DataFlowExecutor_InNode.cxx +++ b/src/GraphExecutor/DataFlowExecutor_InNode.cxx @@ -32,6 +32,7 @@ using namespace std; #include #include #include +#include #include "OpUtil.hxx" @@ -47,7 +48,8 @@ using namespace std; #include "DataFlowBase_SwitchNode.hxx" #include "DataFlowBase_EndOfSwitchNode.hxx" -#include "DataFlowExecutor_OutNode.hxx" +#include "DataFlowExecutor_DataFlow.hxx" +#include "DataFlowEditor_DataFlow.hxx" // GraphEditor package must be built BEFORE static void InitInNode( int &_RewindStack , SUPERV::ControlState &_ControlState , @@ -218,6 +220,7 @@ GraphExecutor::InNode::InNode( CORBA::ORB_ptr ORB, ORB ) ; SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ; + _Loading = false ; _ComputingNode = NULL ; _FactoryNode = NULL ; _InLineNode = NULL ; @@ -431,7 +434,7 @@ bool GraphExecutor::InNode::Ping() { _FactoryNode->Component()->ping() ; } catch( ... ) { - cdebug << "InNode::Ping() catched" << endl ; + cdebug << "InNode::Ping() ERROR catched" << endl ; State( GraphExecutor::ErroredState ) ; _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false ; @@ -458,7 +461,7 @@ void GraphExecutor::InNode::ExitThread() { bool GraphExecutor::InNode::Suspend() { cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo() - << endl; + << " " << Automaton()->StateName( State() ) << endl; bool RetVal = false ; if ( IsDone() ) { //If loop we need to suspend also ControlState( SUPERV::VoidState ) ; @@ -476,47 +479,121 @@ bool GraphExecutor::InNode::Suspend() { else if ( IsRunning() ) { ControlState( SUPERV::ToSuspendState ) ; if ( IsFactoryNode() || IsComputingNode() ) { - if ( !CORBA::is_nil( Component() ) ) { - try { - RetVal = Component()->Suspend_impl() ; - } - catch( ... ) { - cdebug << "InNode::Suspend() catched" << endl ; - State( GraphExecutor::ErroredState ) ; - _OutNode->State( GraphExecutor::ErroredState ) ; - RetVal = false ; - } - if ( RetVal ) { - if ( IsRunning() ) { - cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name() - << " --> thread" << ThreadNo() << " SuspendEvent " << endl; - SendEvent( GraphExecutor::SuspendEvent ) ; - cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container" - << Name() << " --> thread" << ThreadNo() << endl; - } - else if ( IsDone() ) { - ControlState( SUPERV::VoidState ) ; - RetVal = false ; // Too late ... +// We have to suspend in the container of that node + int TrySuspend = 10 ; + while ( TrySuspend ) { + if ( !CORBA::is_nil( Component() ) ) { +// We can call that component + try { + RetVal = Component()->Suspend_impl() ; + } + catch( ... ) { + cdebug << "InNode::Suspend() ERROR catched" << endl ; + State( GraphExecutor::ErroredState ) ; + _OutNode->State( GraphExecutor::ErroredState ) ; + RetVal = false ; + TrySuspend = 1 ; + } + cdebug << "Component()->Suspend_impl() returns status " << RetVal << endl ; + if ( RetVal ) { + if ( IsRunning() ) { + cdebug << pthread_self() << "GraphExecutor::InNode::Suspend_impl " << Name() + << " --> thread" << ThreadNo() << " SuspendEvent " << endl; + SendEvent( GraphExecutor::SuspendEvent ) ; + cdebug << pthread_self() << "GraphExecutor::InNode::Suspended_impl in Container" + << Name() << " --> thread" << ThreadNo() << endl; + TrySuspend = 1 ; + } + else if ( IsDone() ) { + ControlState( SUPERV::VoidState ) ; + RetVal = false ; // Too late ... + TrySuspend = 1 ; + } + else { + cdebug << "InNode::Suspend component Suspended and !IsDone and !IsRunning !" + << endl ; + MESSAGE("InNode::Suspend component Suspended and !IsDone and !IsRunning !") ; + TrySuspend = 1 ; + } } else { - cdebug << "component Suspended and !IsDone and !IsRunning !" +// Suspend in the Container failed : it is always false if it is a Python Container + cdebug << "InNode::Suspend cannot Suspend component ! Python Component ?" << endl ; + if ( TrySuspend == 1 ) { + if ( IsSuspended() ) { + RetVal = true ; + } + else { + RetVal = false ; + } + } + } + } + else { + cdebug << "InNode::Suspend with nilComponent while RunningState !. Loading Component ?" + << endl ; +// Wait for the end of loading of the component + while ( IsLoading() ) { + sleep( 1 ) ; + } + if ( TrySuspend == 1 ) { + if ( IsSuspended() ) { + RetVal = true ; + } + else { + RetVal = false ; + } } } + TrySuspend -= 1 ; + if ( TrySuspend ) { + sleep( 1 ) ; + } } - else { - cdebug << "Suspend cannot Suspend component !" << endl ; - RetVal = false ; + } + else if ( IsMacroNode() ) { +// It should be like that but it is not completely implemented + GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ; + RetVal = aGraph->GraphEditor()->Executor()->Suspend() ; + if ( RetVal ) { + State( GraphExecutor::SuspendedState ) ; } } else { - cdebug << "Suspend with nilComponent while RunningState !" << endl ; - RetVal = false ; +// Now we can suspend an InLineNode with the handler of the SuperVision Container + if ( pthread_kill( _OutNode->MainThreadId() , SIGUSR2 ) == -1 ) { + perror("Suspend pthread_kill error") ; + State( GraphExecutor::ErroredState ) ; + _OutNode->State( GraphExecutor::ErroredState ) ; + RetVal = false ; + } + else { + RetVal = true ; + } + if ( RetVal ) { + if ( IsRunning() ) { + cdebug << pthread_self() << "GraphExecutor::InNode::Suspend " << Name() + << " --> thread" << ThreadNo() << " SuspendEvent " << endl; + SendEvent( GraphExecutor::SuspendEvent ) ; + cdebug << pthread_self() << "GraphExecutor::InNode::Suspended in SuperVision Container" + << Name() << " --> thread" << ThreadNo() << endl; + } + else if ( IsDone() ) { + ControlState( SUPERV::VoidState ) ; + RetVal = false ; // Too late ... + } + else { + cdebug << "component Suspended and !IsDone and !IsRunning !" + << endl ; + } + } } } else { - cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?" - << endl ; + cdebug << "Suspend and IsDone " << IsDone() << " and IsRunning " << IsRunning() + << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady() + << " ?" << endl ; RetVal = false ; } cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << " " @@ -539,7 +616,8 @@ bool GraphExecutor::InNode::ContainerKill() { bool GraphExecutor::InNode::Kill() { cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads() - << " SuspendedThreads " << _OutNode->SuspendedThreads() << endl; + << " SuspendedThreads " << _OutNode->SuspendedThreads() + << " EventQSize " << _OutNode->EventQSize() << endl; bool RetVal ; if ( IsDone() ) { ControlState( SUPERV::ToKillState ) ; // if loop @@ -559,62 +637,137 @@ bool GraphExecutor::InNode::Kill() { else { if ( IsRunning() ) { if ( IsFactoryNode() || IsComputingNode() ) { - if ( !CORBA::is_nil( Component() ) ) { - try { - RetVal = Component()->Kill_impl() ; - } - catch( ... ) { - cdebug << "InNode::Suspend() catched" << endl ; - State( GraphExecutor::ErroredState ) ; - _OutNode->State( GraphExecutor::ErroredState ) ; - RetVal = false ; - } - cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ; - RetVal = true ; - if ( IsRunning() ) { - cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name() - << " --> thread" << ThreadNo() << " SuspendEvent " << endl; - SendEvent( GraphExecutor::KillEvent ) ; - cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container" - << Name() << " --> thread" << ThreadNo() << endl; - } - else if ( IsDone() ) { - ControlState( SUPERV::VoidState ) ; - RetVal = false ; // Too late ... +// We have to suspend in the container of that node + int TryKill = 10 ; + while ( TryKill ) { + if ( !CORBA::is_nil( Component() ) ) { +// We can call that component + try { + RetVal = Component()->Kill_impl() ; + } + catch( ... ) { + cdebug << "InNode::Kill_impl ERROR catched" << endl ; + State( GraphExecutor::ErroredState ) ; + _OutNode->State( GraphExecutor::ErroredState ) ; + RetVal = false ; + TryKill = 1 ; + } + cdebug << "Component()->Kill_impl() returns status " << RetVal << endl ; + if ( RetVal ) { + if ( IsRunning() ) { + cdebug << pthread_self() << "GraphExecutor::InNode::Kill_impl " << Name() + << " --> thread" << ThreadNo() << " KillEvent " << endl; + SendEvent( GraphExecutor::KillEvent ) ; + cdebug << pthread_self() << "GraphExecutor::InNode::Killed_impl in Container" + << Name() << " --> thread" << ThreadNo() << endl; + TryKill = 1 ; + } + else if ( IsDone() ) { + ControlState( SUPERV::VoidState ) ; + RetVal = false ; // Too late ... + TryKill = 1 ; + } + else { + cdebug << "Kill component Killed and !IsDone and !IsRunning !" + << endl ; + TryKill = 1 ; + } + } + else { +// Kill in the Container failed : it is always false if it is a Python Container + cdebug << "InNode::Suspend cannot Kill component ! Python Component ?" + << endl ; + if ( TryKill == 1 ) { + if ( IsKilled() ) { + RetVal = true ; + } + else { + RetVal = false ; + } + } + } } else { - cdebug << "component Killed and !IsDone and !IsRunning !" + cdebug << "InNode::Kill with nilComponent while RunningState !. Loading Component ?" << endl ; +// Wait for the end of loading of the component + while ( IsLoading() ) { + sleep( 1 ) ; + } + if ( TryKill == 1 ) { + if ( IsKilled() ) { + RetVal = true ; + } + else { + RetVal = false ; + } + } } + TryKill -= 1 ; + if ( TryKill ) { + sleep( 1 ) ; + } } - else { - cdebug << "Kill with nilComponent cannot Kill component !" << endl ; + } + else if ( IsMacroNode() ) { +// It should be like that but it is not completely implemented + GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ; + RetVal = aGraph->GraphEditor()->Executor()->Kill() ; + if ( RetVal ) { + State( GraphExecutor::KilledState ) ; + } + } + else { +//PAL6886 +// Now we can kill an InLineNode with the handler of the SuperVision Container + cdebug << pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId " + << _OutNode->MainThreadId() << " :" << endl ; + MESSAGE( pthread_self() << "Kill of InLineNode " << Name() << " MainThreadId " + << _OutNode->MainThreadId() << " :" ) ; + if ( pthread_kill( _OutNode->MainThreadId() , SIGINT ) == -1 ) { +// python signals run only in main thread ... + perror("Kill pthread_kill error") ; + State( GraphExecutor::ErroredState ) ; + _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false ; } + else { + cdebug << pthread_self() << "pthread_kill of InLineNode " << Name() + << " done. MainThreadId " << _OutNode->MainThreadId() << endl ; + MESSAGE( pthread_self() << "pthread_kill of InLineNode " << Name() + << " done. MainThreadId " << _OutNode->MainThreadId() ) ; + RetVal = true ; + } } } else if ( IsSuspended() ) { cdebug << pthread_self() << "GraphExecutor::InNode::Kill " << Name() << " --> thread" << ThreadNo() << " Resume()" << endl; - Resume() ; - RetVal = true ; + if ( Resume() ) { + RetVal = Kill() ; + } + else { + RetVal = false ; + } } else if ( IsWaiting() ) { - RetVal = true ; + RetVal = false ; } else if ( IsReady() ) { RetVal = true ; } else { - cdebug << "Kill and !IsDone and !IsRunning and !IsWaiting and !IsReady ?" - << endl ; + cdebug << "Kill and IsDone " << IsDone() << " and IsRunning " << IsRunning() + << " and IsWaiting " << IsWaiting() << " and IsReady " << IsReady() + << " ?" << endl ; RetVal = false ; } } } - cdebug_out << "GraphExecutor::InNode::Kill" << Name() << " " << ThreadNo() << " " + cdebug_out << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " << Automaton()->StateName( State() ) << " Threads " << _OutNode->Threads() - << " SuspendedThreads " << _OutNode->SuspendedThreads() << endl ; + << " SuspendedThreads " << _OutNode->SuspendedThreads() + << " EventQSize " << _OutNode->EventQSize() << endl ; return RetVal ; } @@ -674,7 +827,7 @@ bool GraphExecutor::InNode::Stop() { RetVal = Component()->Stop_impl() ; } catch( ... ) { - cdebug << "InNode::Stop() catched" << endl ; + cdebug << "InNode::Stop() ERROR catched" << endl ; State( GraphExecutor::ErroredState ) ; _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false ; @@ -694,7 +847,7 @@ bool GraphExecutor::InNode::Stop() { } } else { - cdebug << "Suspend cannot Suspend component !" << endl ; + cdebug << "Suspend cannot Stop component ! Python Component ?" << endl ; RetVal = false ; } } @@ -752,15 +905,49 @@ bool GraphExecutor::InNode::Resume() { } else if ( State() == GraphExecutor::SuspendedExecutingState ) { if ( IsFactoryNode() || IsComputingNode() ) { + if ( pthread_mutex_lock( &_MutexWait ) ) { + perror("ResumeAction pthread_mutex_lock ") ; + exit( 0 ) ; + } try { RetVal = Component()->Resume_impl() ; + if ( RetVal ) { + State( GraphExecutor::ExecutingState ) ; + } } catch( ... ) { - cdebug << "InNode::Resume() catched" << endl ; + cdebug << "InNode::Resume() ERROR catched" << endl ; State( GraphExecutor::ErroredState ) ; _OutNode->State( GraphExecutor::ErroredState ) ; RetVal = false ; } + if ( pthread_mutex_unlock( &_MutexWait ) ) { + perror("ResumeAction pthread_mutex_unlock ") ; + exit( 0 ) ; + } + } + else if ( IsMacroNode() ) { + cdebug << "Suspend of MacroNode not yet implemented ? Trying" << endl ; + GraphBase::Graph * aGraph = (GraphBase::Graph * ) GraphMacroNode()->CoupledNode() ; + RetVal = aGraph->GraphEditor()->Executor()->Resume() ; + if ( RetVal ) { + State( GraphExecutor::ExecutingState ) ; + } + } + else { +// Resume of InLinePythonNode in the Node of the SuperVisionContainer ... + cdebug << ThreadNo() << "/" << pthread_self() + << "Resume of InLineNode pthread_kill" << Name() << endl ; + if ( pthread_kill( _OutNode->MainThreadId() , SIGCONT ) == -1 ) { + perror("Resume pthread_kill error") ; + State( GraphExecutor::ErroredState ) ; + _OutNode->State( GraphExecutor::ErroredState ) ; + RetVal = false ; + } + else { + State( GraphExecutor::ExecutingState ) ; + RetVal = true ; + } } } else if ( State() == GraphExecutor::SuspendedSuccessedState ) { @@ -853,7 +1040,8 @@ bool GraphExecutor::InNode::Resume() { } } #endif - cdebug_out << "GraphExecutor::InNode::Resume " << RetVal << endl ; + cdebug_out << "GraphExecutor::InNode::Resume " << Name() << " " << RetVal << " " + << Automaton()->StateName( State() ) << endl ; return RetVal ; } @@ -957,7 +1145,8 @@ bool GraphExecutor::InNode::IsSuspended() { if ( aState == GraphExecutor::SuspendedReadyState || aState == GraphExecutor::SuspendedExecutingState || aState == GraphExecutor::SuspendedSuccessedState || - aState == GraphExecutor::SuspendedErroredState ) + aState == GraphExecutor::SuspendedErroredState || + aState == GraphExecutor::SuspendedState ) aret = true ; // cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ; return aret ; @@ -1020,12 +1209,14 @@ bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) { << " " << Automaton()->StateName( _currentState ) << " pthread_cond_wait _RunningWait " << Name() << endl ; while ( !RetVal && !IsDone() ) { - cdebug << pthread_self() << " pthread_cond_wait RunningWait" << endl ; + cdebug << pthread_self() << " pthread_cond_wait RunningWait " << Name() << endl ; pthread_cond_wait( &_RunningWait , &_MutexWait ); - RetVal = IsRunning() ; +//We may have pthread_cond_waited but !IsRunning and !IsDone : + RetVal = IsRunning() || State() == GraphExecutor::SuccessedExecutingState || + State() == GraphExecutor::ErroredExecutingState ; cdebug << pthread_self() << " pthread_cond_waited RunningWait " << Automaton()->StateName( _currentState ) << " " << RetVal - << endl ; + << " " << Name() << endl ; } cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal << " " << Automaton()->StateName( _currentState ) @@ -1089,9 +1280,12 @@ bool GraphExecutor::InNode::ReadyWait() { } bool GraphExecutor::InNode::RunningWait() { -// cdebug_in << "GraphExecutor::InNode::RunningWait " << Name() << endl; + cdebug_in << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name() + << " " << Automaton()->StateName( State() ) << endl; bool aret ; aret = StateWait( SUPERV::RunningState ) ; + cdebug_out << pthread_self() << "GraphExecutor::InNode::RunningWait " << Name() + << " " << Automaton()->StateName( State() ) << endl; return aret ; } @@ -1109,18 +1303,17 @@ bool GraphExecutor::InNode::SuspendedWait() { return aret ; } -void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode ) +void GraphExecutor::InNode::InitialState() { cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl; - _OutNode = theOutNode ; - int i; _ControlState = SUPERV::VoidState ; CreateNewThread( false ) ; CreateNewThreadIf( false ) ; _SuspendSync = false ; _ResumeSync = false ; + IsLoading( true ) ; // ThreadNo( pthread_self() ) ; ThreadNo( 0 ) ;