]> SALOME platform Git repositories - modules/superv.git/blob - src/GraphExecutor/DataFlowExecutor_InNode.cxx
Salome HOME
NRI : Merge from V1_2.
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNode.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : DataFlowBase_InNode.cxx
4 // Created   : 2002
5 // Author    : Jean Rahuel, CEA
6 // Project   : SALOME
7 // $Header:
8 //=============================================================================
9
10 #include <stdlib.h>
11 #include <iostream>
12 #include <unistd.h>
13 #include <stdio.h>
14
15 #include "OpUtil.hxx"
16
17 #include <SALOMEconfig.h>
18 #include CORBA_CLIENT_HEADER(SALOME_Component)
19 #include "SALOME_NamingService.hxx"
20 #include "SALOME_LifeCycleCORBA.hxx"
21
22 #include "DataFlowBase_FactoryNode.hxx"
23 #include "DataFlowBase_GOTONode.hxx"
24 #include "DataFlowBase_LoopNode.hxx"
25 #include "DataFlowBase_EndOfLoopNode.hxx"
26 #include "DataFlowBase_SwitchNode.hxx"
27 #include "DataFlowBase_EndOfSwitchNode.hxx"
28
29 #include "DataFlowExecutor_OutNode.hxx"
30
31 static void InitInNode( SUPERV::ControlState &_ControlState ,
32                         SUPERV::AutomatonState &_currentState ,
33                         GraphExecutor::InNode ** _aReStartNode ,
34                         bool & _PyFuncRunned ,
35                         PyObject ** _MyPyRunMethod ,
36                         pthread_mutex_t &_MutexDataWait ,
37                         bool &_DataWait ,
38                         pthread_mutex_t &_MutexWait ,
39                         pthread_cond_t &_ReadyWait ,
40                         pthread_cond_t &_RunningWait ,
41                         pthread_cond_t &_DoneWait ,
42                         pthread_cond_t &_SuspendedWait ,
43                         pthread_cond_t &_SuspendWait ,
44                         bool &_SuspendSync ,
45                         pthread_cond_t &_ResumeWait ,
46                         bool &_ResumeSync ,
47                         pthread_cond_t &_KillWait ,
48                         bool &_KillSync ,
49                         pthread_cond_t &_StopWait ,
50                         GraphExecutor::FiniteStateMachine ** _Automaton ,
51                         GraphExecutor::FiniteStateMachine * theAutomaton ,
52                         CORBA::ORB_ptr * _Orb ,
53                         CORBA::ORB_ptr ORB ) {
54   _ControlState = SUPERV::VoidState ;
55   _currentState = SUPERV::UnKnownState ;
56   *_aReStartNode = NULL ;
57   _PyFuncRunned = false ;
58   *_MyPyRunMethod = NULL ;
59   pthread_mutex_init( &_MutexDataWait , NULL ) ;
60   _DataWait = false ;
61   pthread_mutex_init( &_MutexWait , NULL ) ;
62   if ( pthread_cond_init( &_ReadyWait , NULL ) ) {
63     perror("pthread_cond_init( &_ReadyWait , NULL )") ;
64     exit( 0 ) ;
65   }
66   if ( pthread_cond_init( &_RunningWait , NULL ) ) {
67     perror("pthread_cond_init( &_RunningWait , NULL )") ;
68     exit( 0 ) ;
69   }
70   if ( pthread_cond_init( &_DoneWait , NULL ) ) {
71     perror("pthread_cond_init( &_DoneWait , NULL )") ;
72     exit( 0 ) ;
73   }
74   if ( pthread_cond_init( &_SuspendedWait , NULL ) ) {
75     perror("pthread_cond_init( &_SuspendedWait , NULL )") ;
76     exit( 0 ) ;
77   }
78   if ( pthread_cond_init( &_SuspendWait , NULL ) ) {
79     perror("pthread_cond_init( &_SuspendWait , NULL )") ;
80     exit( 0 ) ;
81   }
82   _SuspendSync = false ;
83   if ( pthread_cond_init( &_ResumeWait , NULL ) ) {
84     perror("pthread_cond_init( &_ResumeWait , NULL )") ;
85     exit( 0 ) ;
86   }
87   _ResumeSync = false ;
88   if ( pthread_cond_init( &_KillWait , NULL ) ) {
89     perror("pthread_cond_init( &_KillWait , NULL )") ;
90     exit( 0 ) ;
91   }
92   _KillSync = false ;
93   if ( pthread_cond_init( &_StopWait , NULL ) ) {
94     perror("pthread_cond_init( &_StopWait , NULL )") ;
95     exit( 0 ) ;
96   }
97   *_Automaton = theAutomaton ;
98   *_Orb = CORBA::ORB::_nil();
99 }
100
101 GraphExecutor::FiniteStateMachine * theAutomaton = new
102                                         GraphExecutor::FiniteStateMachine() ;
103
104 //GraphExecutor::InNode::InNode() :
105 //     GraphBase::FactoryNode() {
106 GraphExecutor::InNode::InNode() {
107   InitInNode( _ControlState ,
108               _currentState ,
109               &_aReStartNode ,
110               _PyFuncRunned ,
111               &_MyPyRunMethod ,
112               _MutexDataWait ,
113               _DataWait ,
114               _MutexWait ,
115               _ReadyWait ,
116               _RunningWait ,
117               _DoneWait ,
118               _SuspendedWait ,
119               _SuspendWait ,
120               _SuspendSync ,
121               _ResumeWait ,
122               _ResumeSync ,
123               _KillWait ,
124               _KillSync ,
125               _StopWait ,
126               &_Automaton ,
127               theAutomaton ,
128               &_Orb ,
129               CORBA::ORB::_nil() ) ;
130 }
131
132 GraphExecutor::InNode::InNode(CORBA::ORB_ptr ORB,
133                SALOME_NamingService* ptrNamingService ,
134                const SALOME_ModuleCatalog::Service& aService ,
135                const char * ComponentName ,
136                const char * NodeInterfaceName ,
137                const char * NodeName ,
138                const SUPERV::KindOfNode akind ,
139                GraphBase::ListOfFuncName aFuncName ,
140                GraphBase::ListOfPythonFunctions aPythonFunction ,
141                const SUPERV::SDate NodeFirstCreation ,
142                const SUPERV::SDate NodeLastModification  ,
143                const char * NodeEditorRelease ,
144                const char * NodeAuthor ,
145                const char * NodeComputer ,
146                const char * NodeComment ,
147                const bool   GeneratedName ,
148                const int NodeX ,
149                const int NodeY ,
150                int * Graph_prof_debug,
151                ostream * Graph_fdebug) {
152 //               ostream * Graph_fdebug = NULL ) :
153 //             GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
154 //                                     ComponentName , NodeInterfaceName ,
155 //                                     NodeName , akind ,
156 //                                     NodeFirstCreation , NodeLastModification  ,
157 //                                     NodeEditorRelease , NodeAuthor ,
158 //                                     NodeComputer , NodeComment , GeneratedName ,
159 //                                     0 , 0 ,
160 //                                     Graph_prof_debug , Graph_fdebug ) {
161   InitInNode( _ControlState ,
162               _currentState ,
163               &_aReStartNode ,
164               _PyFuncRunned ,
165               &_MyPyRunMethod ,
166               _MutexDataWait ,
167               _DataWait ,
168               _MutexWait ,
169               _ReadyWait ,
170               _RunningWait ,
171               _DoneWait ,
172               _SuspendedWait ,
173               _SuspendWait ,
174               _SuspendSync ,
175               _ResumeWait ,
176               _ResumeSync ,
177               _KillWait ,
178               _KillSync ,
179               _StopWait ,
180               &_Automaton ,
181               theAutomaton ,
182               &_Orb ,
183               ORB ) ;
184   SetDebug( ORB , Graph_prof_debug , Graph_fdebug ) ;
185
186   _ComputingNode = NULL ;
187   _FactoryNode = NULL ;
188   _InLineNode = NULL ;
189   _GOTONode = NULL ;
190   _LoopNode = NULL ;
191   _EndOfLoopNode = NULL ;
192   _SwitchNode = NULL ;
193   _EndOfSwitchNode = NULL ;
194   switch ( akind ) {
195   case SUPERV::ComputingNode : {
196     cdebug << "GraphExecutor::InNode::InNode SUPERV::ComputingNode : " << NodeName ;
197     _ComputingNode = new GraphBase::ComputingNode( ORB , ptrNamingService ,
198                                                    aService ,
199                                                    NodeName , akind ,
200                                                    NodeFirstCreation ,
201                                                    NodeLastModification  ,
202                                                    NodeEditorRelease , NodeAuthor ,
203                                                    NodeComment , GeneratedName ,
204                                                    NodeX , NodeY ,
205                                                    Graph_prof_debug , Graph_fdebug ) ;
206     break ;
207   }
208   case SUPERV::FactoryNode : {
209     cdebug << "GraphExecutor::InNode::InNode SUPERV::FactoryNode : " << NodeName ;
210     _FactoryNode = new GraphBase::FactoryNode( ORB , ptrNamingService , aService ,
211                                                ComponentName , NodeInterfaceName ,
212                                                NodeName , akind ,
213                                                NodeFirstCreation ,
214                                                NodeLastModification  ,
215                                                NodeEditorRelease , NodeAuthor ,
216                                                NodeComputer , NodeComment ,
217                                                GeneratedName , NodeX , NodeY ,
218                                                Graph_prof_debug , Graph_fdebug ) ;
219     _ComputingNode = (GraphBase::ComputingNode *) _FactoryNode ;
220     break ;
221   }
222   case SUPERV::InLineNode : {
223     cdebug << "GraphExecutor::InNode::InNode SUPERV::InLineNode : " << NodeName ;
224     _InLineNode = new GraphBase::InLineNode( ORB , ptrNamingService ,
225                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
226                                              NodeName , akind ,
227                                              NodeFirstCreation , NodeLastModification  ,
228                                              NodeEditorRelease , NodeAuthor ,
229                                              NodeComment , GeneratedName ,
230                                              NodeX , NodeY ,
231                                              Graph_prof_debug , Graph_fdebug ) ;
232     _ComputingNode = (GraphBase::ComputingNode *) _InLineNode ;
233     break ;
234   }
235   case SUPERV::GOTONode : {
236     cdebug << "GraphEditor::InNode::InNode SUPERV::GOTONode : " << NodeName ;
237     _GOTONode = new GraphBase::GOTONode( ORB , ptrNamingService ,
238                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
239                                          NodeName , akind ,
240                                          NodeFirstCreation , NodeLastModification  ,
241                                          NodeEditorRelease , NodeAuthor ,
242                                          NodeComment , GeneratedName ,
243                                          NodeX , NodeY ,
244                                          Graph_prof_debug , Graph_fdebug ) ;
245     _ComputingNode = (GraphBase::ComputingNode *) _GOTONode ;
246     break ;
247   }
248   case SUPERV::LoopNode : {
249     cdebug << "GraphExecutor::InNode::InNode SUPERV::LoopNode : " << NodeName ;
250     _LoopNode = new GraphBase::LoopNode( ORB , ptrNamingService ,
251                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
252                                          aFuncName[1].c_str() , *aPythonFunction[1] ,
253                                          aFuncName[2].c_str() , *aPythonFunction[2] ,
254                                          NodeName , akind ,
255                                          NodeFirstCreation , NodeLastModification  ,
256                                          NodeEditorRelease , NodeAuthor ,
257                                          NodeComment , GeneratedName ,
258                                          NodeX , NodeY ,
259                                          Graph_prof_debug , Graph_fdebug ) ;
260     _ComputingNode = (GraphBase::ComputingNode *) _LoopNode ;
261     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
262     break ;
263   }
264   case SUPERV::EndLoopNode : {
265     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfLoopNode : " << NodeName ;
266     _EndOfLoopNode = new GraphBase::EndOfLoopNode(
267                                          ORB , ptrNamingService ,
268                                          aFuncName[0].c_str() , *aPythonFunction[0] ,
269                                          NodeName , akind ,
270                                          NodeFirstCreation , NodeLastModification  ,
271                                          NodeEditorRelease , NodeAuthor ,
272                                          NodeComment , GeneratedName ,
273                                          NodeX , NodeY ,
274                                          Graph_prof_debug , Graph_fdebug ) ;
275     _ComputingNode = (GraphBase::ComputingNode *) _EndOfLoopNode ;
276     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
277     break ;
278   }
279   case SUPERV::SwitchNode : {
280     cdebug << "GraphExecutor::InNode::InNode SUPERV::SwitchNode : " << NodeName ;
281     _SwitchNode = new GraphBase::SwitchNode( ORB , ptrNamingService ,
282                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
283                                              NodeName , akind ,
284                                              NodeFirstCreation , NodeLastModification  ,
285                                              NodeEditorRelease , NodeAuthor ,
286                                              NodeComment , GeneratedName ,
287                                              NodeX , NodeY ,
288                                              Graph_prof_debug , Graph_fdebug ) ;
289     _ComputingNode = (GraphBase::ComputingNode *) _SwitchNode ;
290     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
291     break ;
292   }
293   case SUPERV::EndSwitchNode : {
294     cdebug << "GraphEditor::InNode::InNode SUPERV::EndOfSwitchNode : " << NodeName ;
295     _EndOfSwitchNode = new GraphBase::EndOfSwitchNode(
296                                              ORB , ptrNamingService ,
297                                              aFuncName[0].c_str() , *aPythonFunction[0] ,
298                                              NodeName , akind ,
299                                              NodeFirstCreation , NodeLastModification  ,
300                                              NodeEditorRelease , NodeAuthor ,
301                                              NodeComment , GeneratedName ,
302                                              NodeX , NodeY ,
303                                              Graph_prof_debug , Graph_fdebug ) ;
304     _ComputingNode = (GraphBase::ComputingNode *) _EndOfSwitchNode ;
305     _GOTONode = (GraphBase::GOTONode *) _ComputingNode ;
306     break ;
307   }
308   }
309   cdebug << "GraphExecutor::InNode::InNode "  << (void *) this
310          << " _ComputingNode " << (void *) _ComputingNode  ;
311   _ComputingNode->InNode( this ) ;
312 }
313
314 GraphExecutor::InNode::~InNode() {
315 }
316
317 void GraphExecutor::InNode::LockDataWait() {
318   if ( pthread_mutex_lock( &_MutexDataWait ) ) {
319     perror("Ready pthread_mutex_lock ") ;
320     exit( 0 ) ;
321   }
322   _DataWait = true ;
323 }
324 void GraphExecutor::InNode::UnLockDataWait() {
325   _DataWait = false ;
326   if ( pthread_mutex_unlock( &_MutexDataWait ) ) {
327     perror("Ready pthread_mutex_unlock ") ;
328     exit( 0 ) ;
329   }
330 }
331
332 bool GraphExecutor::InNode::Ping() {
333 //  cdebug_in << "GraphExecutor::InNode::Ping" << endl;
334   bool RetVal ;
335   if ( IsFactoryNode() ) {
336     RetVal = !CORBA::is_nil( _FactoryNode->Component() ) ;
337     if ( RetVal ) {
338       if ( State() != SUPERV::SuspendedExecutingState ) {
339         _FactoryNode->Component()->ping() ;
340       }
341       else {
342         RetVal = false ;
343       }
344     }
345   }
346 //  cdebug_out << "GraphExecutor::InNode::Ping" << endl ;
347   return RetVal ;
348 }
349
350 void GraphExecutor::InNode::NewThread( pthread_t aThread ) {
351   ThreadNo ( aThread ) ; 
352   if ( aThread )
353     _OutNode->NewThread() ;
354 }
355 void GraphExecutor::InNode::ExitThread() {
356   ThreadNo( 0 ) ;
357   _OutNode->ExitThread() ;
358
359
360 bool GraphExecutor::InNode::Suspend() {
361   cdebug_in << "GraphExecutor::InNode::Suspend " << Name() << " " << ThreadNo()
362             << endl;
363   bool RetVal ;
364   if ( IsDone() ) {
365     ControlState( SUPERV::VoidState ) ;
366     RetVal = false ;
367   }
368   else if ( IsWaiting() || IsReady() ) {
369     ControlState( SUPERV::ToSuspendState ) ;
370     RetVal = true ;
371   }
372   else  if ( IsRunning() ) {
373     ControlState( SUPERV::ToSuspendState ) ;
374     if ( IsFactoryNode() ) {
375       if ( !CORBA::is_nil( Component() ) ) {
376         RetVal = Component()->Suspend_impl() ;
377         if ( RetVal ) {
378           if ( IsRunning() ) {
379             SendEvent( GraphExecutor::SuspendEvent ) ;
380           }
381           else if ( IsDone() ) {
382             ControlState( SUPERV::VoidState ) ;
383             RetVal = false ; // Too late ...
384           }
385           else {
386             cdebug << "component Suspended and !IsDone and !IsRunning !"
387                    << endl ;
388           }
389         }
390       }
391       else {
392         cdebug << "Suspend cannot Suspend component !" << endl ;
393         RetVal = false ;
394       }
395     }
396     else {
397       cdebug << "Suspend with nilComponent while RunningState !" << endl ;
398       RetVal = false ;
399     }
400   }
401   else {
402     cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
403            << endl ;
404     RetVal = false ;
405   }
406   cdebug_out << "GraphExecutor::InNode::Suspend " << RetVal << endl ;
407   return RetVal ;
408 }
409
410 bool GraphExecutor::InNode::ContainerKill() {
411   cdebug_in << "GraphExecutor::InNode::ContainerKill " << Name() << " "
412             << ThreadNo() << endl;
413   bool RetVal ;
414   if ( IsFactoryNode() ) {
415     Kill() ;
416     Container()->Kill_impl() ;
417   }
418   cdebug_out << "GraphExecutor::InNode::ContainerKill" << endl ;
419   return RetVal ;
420 }
421
422 bool GraphExecutor::InNode::Kill() {
423   cdebug_in << "GraphExecutor::InNode::Kill " << Name() << " " << ThreadNo() << " " 
424             << Automaton()->StateName( State() ) << endl;
425   bool RetVal ;
426   if ( ControlState() == SUPERV::ToKillState || IsDone() ) {
427     RetVal = false ;
428   }
429   else {
430     ControlState( SUPERV::ToKillState ) ;
431     if ( IsDone() ) {
432       ControlState( SUPERV::VoidState ) ;
433       RetVal = false ;
434     }
435     else {
436       if ( IsRunning() ) {
437         if ( IsFactoryNode() ) {
438           if ( !CORBA::is_nil( Component() ) ) {
439             RetVal = Component()->Kill_impl() ;
440             if ( RetVal ) {
441               if ( IsRunning() ) {
442                 SendEvent( GraphExecutor::KillEvent ) ;
443               }
444               else if ( IsDone() ) {
445                 ControlState( SUPERV::VoidState ) ;
446                 RetVal = false ; // Too late ...
447               }
448               else {
449                 cdebug << "component Killed and !IsDone and !IsRunning !"
450                        << endl ;
451               }
452             }
453           }
454           else {
455             cdebug << "Kill cannot Kill component !" << endl ;
456             RetVal = false ;
457           }
458         }
459         else {
460           cdebug << "Kill with nilComponent while RunningState !" << endl ;
461           SendEvent( GraphExecutor::KillEvent ) ;
462           RetVal = IsKilled() ;
463         }
464       }
465       else if ( IsSuspended() ) {
466         SendEvent( GraphExecutor::KillEvent ) ;
467         RetVal = true ;
468       }
469       else if ( IsWaiting() ) {
470         RetVal = true ;
471       }
472       else {
473         cdebug << "Kill and !IsDone and !IsRunning and !IsWaiting ?"
474                << endl ;
475         RetVal = false ;
476       }
477     }
478   }
479   cdebug_out << "GraphExecutor::InNode::Kill" << endl ;
480   return RetVal ;
481 }
482
483 bool GraphExecutor::InNode::KillDone() {
484   cdebug_in << "GraphExecutor::InNode::KillDone " << Name() << " " << ThreadNo()
485             << endl;
486   bool RetVal ;
487   if ( ControlState() == SUPERV::ToKillDoneState || IsDone() ) {
488     RetVal = false ;
489   }
490   else {
491     ControlState( SUPERV::ToKillDoneState ) ;
492     if ( IsDone() ) {
493       ControlState( SUPERV::VoidState ) ;
494       RetVal = false ;
495     }
496     else {
497       if ( IsRunning() ) {
498         if ( IsFactoryNode() ) {
499           if ( !CORBA::is_nil( Component() ) ) {
500             RetVal = Component()->Kill_impl() ;
501             if ( RetVal ) {
502               if ( IsRunning() ) {
503                 SendEvent( GraphExecutor::SuspendEvent ) ;
504               }
505               else if ( IsDone() ) {
506                 ControlState( SUPERV::VoidState ) ;
507                 RetVal = false ; // Too late ...
508               }
509               else {
510                 cdebug << "component Suspended and !IsDone and !IsRunning !"
511                        << endl ;
512               }
513             }
514           }
515           else {
516             cdebug << "Suspend cannot Suspend component !" << endl ;
517             RetVal = false ;
518           }
519         }
520         else {
521           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
522           RetVal = false ;
523         }
524       }
525       else if ( IsWaiting() ) {
526         RetVal = true ;
527       }
528       else {
529         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
530                << endl ;
531         RetVal = false ;
532       }
533     }
534   }
535   cdebug_out << "GraphExecutor::InNode::KillDone" << endl ;
536   return RetVal ;
537 }
538
539 bool GraphExecutor::InNode::Stop() {
540   cdebug_in << "GraphExecutor::InNode::Stop " << Name() << " " << ThreadNo()
541             << endl;
542   bool RetVal ;
543   if ( ControlState() == SUPERV::ToStopState || IsDone() ) {
544     RetVal = false ;
545   }
546   else {
547     ControlState( SUPERV::ToStopState ) ;
548     if ( IsDone() ) {
549       ControlState( SUPERV::VoidState ) ;
550       RetVal = false ;
551     }
552     else {
553       if ( IsRunning() ) {
554         if ( IsFactoryNode() ) {
555           if ( !CORBA::is_nil( Component() ) ) {
556             RetVal = Component()->Stop_impl() ;
557             if ( RetVal ) {
558               if ( IsRunning() ) {
559                 SendEvent( GraphExecutor::SuspendEvent ) ;
560               }
561               else if ( IsDone() ) {
562                 ControlState( SUPERV::VoidState ) ;
563                 RetVal = false ; // Too late ...
564               }
565               else {
566                 cdebug << "component Suspended and !IsDone and !IsRunning !"
567                        << endl ;
568               }
569             }
570           }
571           else {
572             cdebug << "Suspend cannot Suspend component !" << endl ;
573             RetVal = false ;
574           }
575         }
576         else {
577           cdebug << "Suspend with nilComponent while RunningState !" << endl ;
578           RetVal = false ;
579         }
580       }
581       else if ( IsWaiting() ) {
582         RetVal = true ;
583       }
584       else {
585         cdebug << "Suspend and !IsDone and !IsRunning and !IsWaiting ?"
586                << endl ;
587         RetVal = false ;
588       }
589     }
590   }
591   cdebug_out << "GraphExecutor::InNode::Stop" << endl ;
592   return RetVal ;
593 }
594
595 bool GraphExecutor::InNode::SuspendDone() {
596   cdebug_in << "GraphExecutor::InNode::SuspendDone " << Name() << " "
597             << ThreadNo() << endl;
598   bool RetVal ;
599   if ( ControlState() == SUPERV::ToSuspendDoneState || IsDone() ) {
600     RetVal = false ;
601   }
602   else {
603     ControlState( SUPERV::ToSuspendDoneState ) ;
604     if ( IsDone() ) {
605       ControlState( SUPERV::VoidState ) ;
606       RetVal = false ;
607     }
608     else {
609       RetVal = true ;
610     }
611   }
612   cdebug_out << "GraphExecutor::InNode::SuspendDone" << endl ;
613   return RetVal ;
614 }
615
616 bool GraphExecutor::InNode::Resume() {
617   cdebug_in << pthread_self() << "/" << ThreadNo()
618             << " GraphExecutor::InNode::Resume " << Name() << " "
619             << Automaton()->StateName( State() ) << endl;
620   bool RetVal = false ;
621   if ( IsSuspended() ) {
622     if ( State() == SUPERV::SuspendedReadyState ) {
623       ResumeAction( GraphExecutor::ToResumeEvent ) ;
624       RetVal = true ;
625     }
626     else if ( State() == SUPERV::SuspendedExecutingState ) {
627       if ( IsFactoryNode() ) {
628         RetVal = Component()->Resume_impl() ;
629       }
630     }
631     else if ( State() == SUPERV::SuspendedSuccessedState ) {
632       ResumeAction( GraphExecutor::ToResumeEvent ) ;
633       RetVal = true ;
634     }
635     else if ( State() == SUPERV::SuspendedErroredState ) {
636       ResumeAction( GraphExecutor::ToResumeEvent ) ;
637       RetVal = true ;
638     }
639     else {
640       cdebug << "GraphExecutor::InNode::Resume Not SuspendedReady/Executing/Successed/ErroredState "
641              << Automaton()->StateName( State() ) << endl ;
642       RetVal = false ;
643     }
644   }
645   else {
646     cdebug << "GraphExecutor::InNode::Resume Not Suspended State "
647            << Automaton()->StateName( State() ) << endl ;
648     RetVal = false ;
649   }
650   if ( ControlState() == SUPERV::ToSuspendStartState ) {
651     ControlState( SUPERV::VoidState ) ;
652   }
653
654 #if 0
655   if ( ControlState() == SUPERV::ToSuspendRunState ||
656        ( ControlState() == SUPERV::ToSuspendState &&
657          State() == SUPERV::SuspendedReadyState) ) {
658     if ( IsSuspended() ) {
659       if ( State() == SUPERV::SuspendedReadyState ) {
660         ResumeAction() ;
661         RetVal = true ;
662       }
663       else if ( State() == SUPERV::SuspendedExecutingState ) {
664         ResumeAction() ;
665         RetVal = Component()->Resume_impl() ;
666       }
667       else {
668         cdebug << "GraphExecutor::InNode::Resume State "
669                << Automaton()->StateName( State() ) << endl ;
670         RetVal = false ;
671       }
672       if ( ControlState() != SUPERV::ToSuspendState ) {
673         ControlState( SUPERV::VoidState ) ;
674       }
675     }
676     else if ( IsRunning() ) {
677       RetVal = true ;
678     }
679     else if ( IsWaiting() ) {
680       ControlState( SUPERV::VoidState ) ;
681       RetVal = true ;
682     }
683     else if ( IsDone() ) {
684       RetVal = true ;
685     }
686   }
687   else if ( ControlState() == SUPERV::ToSuspendDoneState ||
688             ( ControlState() == SUPERV::ToSuspendState &&
689               State() == SUPERV::SuspendedSuccessedState) ) {
690     if ( IsSuspended() ) {
691       if ( State() == SUPERV::SuspendedSuccessedState ) {
692         ResumeAction() ;
693         RetVal = true ;
694       }
695       else if ( State() == SUPERV::SuspendedErroredState ) {
696         ResumeAction() ;
697         RetVal = true ;
698       }
699       else {
700         cdebug << "GraphExecutor::InNode::Resume State " << State() << endl ;
701         RetVal = false ;
702       }
703       if ( ControlState() != SUPERV::ToSuspendState ) {
704         ControlState( SUPERV::VoidState ) ;
705       }
706     }
707     else if ( IsRunning() ) {
708       ControlState( SUPERV::VoidState ) ;
709       RetVal = true ;
710     }
711     else if ( IsWaiting() ) {
712       ControlState( SUPERV::VoidState ) ;
713       RetVal = true ;
714     }
715     else if ( IsDone() ) {
716       ControlState( SUPERV::VoidState ) ;
717       RetVal = true ;
718     }
719   }
720 #endif
721   cdebug_out << "GraphExecutor::InNode::Resume " << RetVal << endl ;
722   return RetVal ;
723 }
724
725 bool GraphExecutor::InNode::ReStart( const char * AtNodeName ,
726                                      const bool AndSuspend ) {
727   bool RetVal = false ;
728   GraphExecutor::InNode * aRestartNode = (GraphExecutor::InNode *) _OutNode->GetGraphNode( AtNodeName )->GetInNode() ;
729   cdebug_in << pthread_self() << "/" << ThreadNo()
730             << " --> GraphExecutor::InNode::ReStartAt( "
731             << AtNodeName << " , " << AndSuspend << ") " << endl
732             << "thread " << aRestartNode->ThreadNo() << " "
733             << Automaton()->StateName( aRestartNode->State() )
734             << " from " << Name() << " " << Automaton()->StateName( State() )
735             << endl ;
736   if ( IsWaiting() && aRestartNode->IsSuspended() ) {
737     RetVal = aRestartNode->Resume() ;
738   }
739   else if ( IsSuspended() ) {
740     if ( strcmp( AtNodeName , Name() ) ) {
741       aRestartNode->State( SUPERV::SuspendedSuccessedState ) ;
742     }
743     if ( AndSuspend ) {
744       ReStartAction( aRestartNode , GraphExecutor::ReStartAndSuspendEvent ) ;
745     }
746     else {
747       ReStartAction( aRestartNode , GraphExecutor::ReStartEvent ) ;
748     }
749     RetVal = true ;
750   }
751   cdebug_out << "<-- GraphExecutor::InNode::ReStartAt" << endl ;
752   return RetVal ;
753 }
754
755 bool GraphExecutor::InNode::IsWaiting() {
756   bool aret = false ;
757 //  cdebug_in << "GraphExecutor::InNode::IsWaiting " << Name() << endl;
758   SUPERV::AutomatonState aState = State() ;
759   if ( aState == SUPERV::DataUndefState ||
760        aState == SUPERV::DataWaitingState ||
761        aState == SUPERV::SuspendedReadyState )
762 //       aState == SUPERV::SuspendedExecutingState ||
763 //       aState == SUPERV::SuspendedSuccessedState ||
764 //       aState == SUPERV::SuspendedErroredState ||
765 //       aState == SUPERV::SuspendedState
766     aret = true ;
767 //  cdebug_out << "GraphExecutor::InNode::IsWaiting" << endl ;
768   return aret ;
769 }
770
771 bool GraphExecutor::InNode::IsReady() {
772   bool aret = false ;
773 //  cdebug_in << "GraphExecutor::InNode::IsReady " << Name() << endl;
774   SUPERV::AutomatonState aState = State() ;
775   if ( aState == SUPERV::DataUndefState ||
776        aState == SUPERV::DataWaitingState ||
777        aState == SUPERV::DataReadyState ||
778        aState == SUPERV::ResumedReadyState )
779     aret = true ;
780 //  cdebug_out << "GraphExecutor::InNode::IsReady" << endl ;
781   return aret ;
782 }
783
784 bool GraphExecutor::InNode::IsRunning() {
785   bool aret = false ;
786 //  cdebug_in << "GraphExecutor::InNode::IsRunning " << Name() << endl;
787   SUPERV::AutomatonState aState = State() ;
788   if ( aState == SUPERV::ExecutingState ||
789        aState == SUPERV::ResumedExecutingState )
790     aret = true ;
791 //  cdebug_out << "GraphExecutor::InNode::IsRunning" << endl ;
792   return aret ;
793 }
794
795 bool GraphExecutor::InNode::IsDone() {
796   bool aret = false ;
797 //  cdebug_in << "GraphExecutor::InNode::IsDone " << Name() << endl;
798   SUPERV::AutomatonState aState = State() ;
799   if ( aState == SUPERV::KilledReadyState ||
800        aState == SUPERV::StoppedReadyState ||
801        aState == SUPERV::KilledExecutingState ||
802        aState == SUPERV::StoppedExecutingState ||
803        aState == SUPERV::SuspendedSuccessedState ||
804        aState == SUPERV::SuspendedErroredState ||
805 //       aState == SUPERV::SuccessedExecutingState ||
806 //       aState == SUPERV::ErroredExecutingState ||
807        aState == SUPERV::SuccessedState ||
808        aState == SUPERV::ErroredState ||
809        aState == SUPERV::ResumedSuccessedState ||
810        aState == SUPERV::ResumedErroredState ||
811        aState == SUPERV::KilledSuccessedState ||
812        aState == SUPERV::StoppedSuccessedState )
813     aret = true ;
814 //  cdebug_out << "GraphExecutor::InNode::IsDone" << endl ;
815   return aret ;
816 }
817
818 bool GraphExecutor::InNode::IsSuspended() {
819   bool aret = false ;
820 //  cdebug_in << "GraphExecutor::InNode::IsSuspended " << Name() << endl;
821   SUPERV::AutomatonState aState = State() ;
822   if ( aState == SUPERV::SuspendedReadyState ||
823        aState == SUPERV::SuspendedExecutingState ||
824        aState == SUPERV::SuspendedSuccessedState ||
825        aState == SUPERV::SuspendedErroredState )
826     aret = true ;
827 //  cdebug_out << "GraphExecutor::InNode::IsSuspended" << endl ;
828   return aret ;
829 }
830 bool GraphExecutor::InNode::IsKilled() {
831   bool aret = false ;
832 //  cdebug_in << "GraphExecutor::InNode::IsKilled " << Name() << endl;
833   SUPERV::AutomatonState aState = State() ;
834   if ( aState == SUPERV::KilledReadyState ||
835        aState == SUPERV::KilledExecutingState ||
836        aState == SUPERV::KilledSuccessedState ||
837        aState == SUPERV::KilledErroredState ||
838        aState == SUPERV::KilledState )
839     aret = true ;
840 //  cdebug_out << "GraphExecutor::InNode::IsKilled" << endl ;
841   return aret ;
842 }
843 bool GraphExecutor::InNode::IsStopped() {
844   bool aret = false ;
845 //  cdebug_in << "GraphExecutor::InNode::IsStopped " << Name() << endl;
846   SUPERV::AutomatonState aState = State() ;
847   if ( aState == SUPERV::StoppedReadyState ||
848        aState == SUPERV::StoppedExecutingState ||
849        aState == SUPERV::StoppedSuccessedState ||
850        aState == SUPERV::StoppedErroredState ||
851        aState == SUPERV::StoppedState )
852     aret = true ;
853 //  cdebug_out << "GraphExecutor::InNode::IsStopped" << endl ;
854   return aret ;
855 }
856
857 bool GraphExecutor::InNode::StateWait( SUPERV::GraphState aState ) {
858   bool RetVal = false ;
859   if ( pthread_mutex_lock( &_MutexWait ) ) {
860     perror("pthread_mutex_lock _Wait") ;
861     exit( 0 ) ;
862   }
863   switch ( aState ) {
864   case SUPERV::ReadyState : {
865     RetVal = IsReady() ;
866     cdebug_in << pthread_self() << " StateWait( Ready ) " << RetVal
867               << " " << Automaton()->StateName( _currentState )
868               << " pthread_cond_wait _ReadyWait " << Name() << endl ;
869     while ( !RetVal && !IsDone() ) {
870       cdebug << pthread_self() << " pthread_cond_wait ReadyWait" << endl ;
871       pthread_cond_wait( &_ReadyWait , &_MutexWait );
872       RetVal = IsReady() ;
873       cdebug << pthread_self() << " pthread_cond_waited ReadyWait "
874              << Automaton()->StateName( _currentState ) << " " << RetVal
875              << endl ;
876     }
877     cdebug_out << pthread_self() << " StateWait( Ready ) " << RetVal
878                << " " << Automaton()->StateName( _currentState )
879                << " pthread_cond_wait _ReadyWait " << Name() << endl ;
880     break ;
881   }
882   case SUPERV::RunningState : {
883     RetVal = IsRunning() ;
884     cdebug_in << pthread_self() << " StateWait( Running ) " << RetVal
885               << " " << Automaton()->StateName( _currentState )
886               << " pthread_cond_wait _RunningWait " << Name() << endl ;
887     while ( !RetVal && !IsDone() ) {
888       cdebug << pthread_self() << " pthread_cond_wait RunningWait" << endl ;
889       pthread_cond_wait( &_RunningWait , &_MutexWait );
890       RetVal = IsRunning() ;
891       cdebug << pthread_self() << " pthread_cond_waited RunningWait "
892              << Automaton()->StateName( _currentState ) << " " << RetVal
893              << endl ;
894     }
895     cdebug_out << pthread_self() << " StateWait( Running ) " << RetVal
896                << " " << Automaton()->StateName( _currentState )
897                << " pthread_cond_wait _RunningWait " << Name() << endl ;
898     break ;
899   }
900   case SUPERV::DoneState : {
901     RetVal = IsDone() ;
902     cdebug_in << pthread_self() << " StateWait( Done ) " << RetVal
903               << " " << Automaton()->StateName( _currentState )
904               << " pthread_cond_wait _DoneWait " << Name() << endl ;
905     while ( !RetVal ) {
906       cdebug << pthread_self() << " pthread_cond_wait DoneWait" << endl ;
907       pthread_cond_wait( &_DoneWait , &_MutexWait );
908       RetVal = IsDone() ;
909       cdebug << pthread_self() << " pthread_cond_waited DoneWait "
910              << Automaton()->StateName( _currentState ) << " " << RetVal
911              << endl ;
912     }
913     cdebug_out << pthread_self() << " StateWait( Done ) " << RetVal
914                << " " << Automaton()->StateName( _currentState )
915                << " pthread_cond_wait _DoneWait " << Name() << endl ;
916     break ;
917   }
918   case SUPERV::SuspendState : {
919     RetVal = IsSuspended() ;
920     cdebug_in << pthread_self() << " StateWait( Suspend ) " << RetVal
921               << " " << Automaton()->StateName( _currentState )
922               << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
923     while ( !RetVal && !IsDone() ) {
924       cdebug << pthread_self() << " pthread_cond_wait SuspendedWait" << endl ;
925       pthread_cond_wait( &_SuspendedWait , &_MutexWait );
926       RetVal = IsSuspended() ;
927       cdebug << pthread_self() << " pthread_cond_waited SuspendedWait "
928              << Automaton()->StateName( _currentState ) << " " << RetVal
929              << endl ;
930     }
931     cdebug_out << pthread_self() << " StateWait( Suspend ) " << RetVal
932                << " " << Automaton()->StateName( _currentState )
933                << " pthread_cond_wait _SuspendedWait " << Name() << endl ;
934     break ;
935   }
936   default : {
937     cdebug << " GraphExecutor::OutNode::StateWait Error Undefined State : "
938            << aState << endl ;
939   }
940   }
941   if ( pthread_mutex_unlock( &_MutexWait ) ) {
942     perror("pthread_mutex_lock _Wait") ;
943     exit( 0 ) ;
944   }
945   return RetVal ;
946 }
947
948 bool GraphExecutor::InNode::ReadyWait() {
949 //  cdebug_in << "GraphExecutor::InNode::ReadyWait " << Name() << endl;
950   bool aret ;
951   aret = StateWait( SUPERV::ReadyState ) ;
952 //  cdebug_out << "GraphExecutor::InNode::ReadyWait" << endl ;
953   return aret ;
954 }
955
956 bool GraphExecutor::InNode::RunningWait() {
957 //  cdebug_in << "GraphExecutor::InNode::RunningWait " << Name() << endl;
958   bool aret ;
959   aret = StateWait( SUPERV::RunningState ) ;
960   return aret ;
961 }
962
963 bool GraphExecutor::InNode::DoneWait() {
964 //  cdebug_in << "GraphExecutor::InNode::DoneWait " << Name() << endl;
965   bool aret ;
966   aret = StateWait( SUPERV::DoneState ) ;
967   return aret ;
968 }
969
970 bool GraphExecutor::InNode::SuspendedWait() {
971 //  cdebug_in << "GraphExecutor::InNode::SuspendedWait " << Name() << endl;
972   bool aret ;
973   aret = StateWait( SUPERV::SuspendState ) ;
974   return aret ;
975 }
976
977 void GraphExecutor::InNode::InitialState( GraphExecutor::OutNode * theOutNode )
978 {
979   cdebug_in << "GraphExecutor::InNode::InitialState Node " << Name() << endl;
980
981   _OutNode = theOutNode ;
982
983   int i;
984   _ControlState = SUPERV::VoidState ;
985   CreateNewThread( false ) ;
986   CreateNewThreadIf( false ) ;
987   _SuspendSync = false ;
988   _ResumeSync = false ;
989 //  ThreadNo( pthread_self() ) ;
990   ThreadNo( 0 ) ;
991
992   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
993     if ( i != 0 || !IsGOTONode() ) {
994       GetChangeNodeOutPort(i)->State(  SUPERV::WaitingState ) ;
995       GetChangeNodeOutPort(i)->Done( false ) ;
996     }
997   }
998
999   int Pc = GetNodeInPortsSize() ;
1000   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1001     const GraphBase::InPort * anInPort = GetNodeInPort(i) ;
1002     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1003     if ( IsHeadNode() && IsLoopNode() && anInPort->IsLoop() ) {
1004       anOutPort->PortStatus( DataConnected );
1005       anOutPort->State( SUPERV::ReadyState ) ;
1006       anOutPort->Done( true ) ;
1007       CORBA::Any * anAny = new CORBA::Any() ;
1008       *anAny <<= (long ) 1 ;
1009       anOutPort->Value( anAny ) ;
1010     }
1011     else if ( anInPort->IsGate() && anOutPort ) {
1012       if ( IsComputingNode() || IsFactoryNode() ) {
1013         anOutPort->State( SUPERV::WaitingState ) ;
1014         anOutPort->Done( false ) ;
1015       }
1016       else if ( IsOneOfInLineNodes() ) {
1017         anOutPort->PortStatus( DataConnected );
1018         anOutPort->State( SUPERV::ReadyState ) ;
1019         anOutPort->Done( true ) ;
1020       }
1021     }
1022 //    if ( ( anInPort->IsGate() || anInPort->IsBus() ) && anOutPort == NULL ) {
1023     if ( ( anInPort->IsGate() ) && anOutPort == NULL ) {
1024       Pc-- ;
1025     }
1026     else {
1027       if ( anOutPort->IsDataConnected() ) {
1028         Pc-- ;
1029       }
1030       if ( anOutPort->IsPortConnected() ) {
1031         anOutPort->State( SUPERV::WaitingState ) ;
1032         anOutPort->Done( false ) ;
1033       }
1034       else if ( anOutPort->IsDataConnected() ) {
1035         anOutPort->State( SUPERV::ReadyState ) ;
1036         anOutPort->Done( true ) ;
1037       }
1038     }
1039     if ( anOutPort ) {
1040       GetChangeNodeInPort(i)->State( anOutPort->State() ) ;
1041     }
1042     if ( anOutPort ) {
1043       cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1044              << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1045              << " with state " ;
1046       if ( anOutPort->State() == SUPERV::WaitingState ) {
1047         cdebug << "WaitingState" ;
1048       }
1049       else if ( anOutPort->State() == SUPERV::ReadyState ) {
1050         cdebug << "ReadyState" ;
1051       }
1052       else {
1053         cdebug << "???" ;
1054       }
1055       cdebug << " PortConnected("
1056              << anOutPort->IsPortConnected() << ") DataConnected("
1057              << anOutPort->IsDataConnected() << ")" << endl ;
1058     }
1059
1060     if ( !PyFuncRunned() ) {
1061       bool Err = false ;
1062       if ( IsLoopNode()  ) {
1063         PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1064                                                   InLineNode()->PythonFunction() ) ;
1065         InLineNode()->PyRunMethod( PyRunMethod ) ;
1066         PyObject * PyMoreMethod = NULL ;
1067         if ( PyRunMethod ) {
1068           PyMoreMethod = InitPyDynInvoke( LoopNode()->PyMoreName() ,
1069                                           LoopNode()->MorePythonFunction() ) ;
1070           LoopNode()->PyMoreMethod( PyMoreMethod ) ;
1071         }
1072         PyObject * PyNextMethod = NULL ;
1073         if ( PyMoreMethod ) {
1074           PyNextMethod = InitPyDynInvoke( LoopNode()->PyNextName() ,
1075                                           LoopNode()->NextPythonFunction() ) ;
1076           LoopNode()->PyNextMethod( PyNextMethod ) ;
1077         }
1078         Err = !PyRunMethod || !PyMoreMethod || !PyNextMethod ;
1079       }
1080       else if ( IsInLineNode() || IsSwitchNode() ) {
1081         PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1082                                                   InLineNode()->PythonFunction() ) ;
1083         InLineNode()->PyRunMethod( PyRunMethod ) ;
1084         Err = !PyRunMethod ;
1085       }
1086       else if ( ( IsEndSwitchNode() || IsGOTONode() ) &&
1087                 (*InLineNode()->PythonFunction()).length() ) {
1088         PyObject * PyRunMethod = InitPyDynInvoke( InLineNode()->PyFuncName() ,
1089                                                   InLineNode()->PythonFunction() ) ;
1090         InLineNode()->PyRunMethod( PyRunMethod ) ;
1091         Err = !PyRunMethod ;
1092       }
1093     }
1094   }
1095
1096   _currentState = Pc > 0 ? SUPERV::DataWaitingState 
1097                          : SUPERV::DataReadyState ;
1098   if ( Pc == GetNodeInPortsSize() ) {
1099     _OutNode->PushEvent( this , GraphExecutor::NoDataReadyEvent ,
1100                          _currentState ) ; 
1101   }
1102   else if ( Pc != 0 ) {
1103     _OutNode->PushEvent( this , GraphExecutor::SomeDataReadyEvent ,
1104                          _currentState ) ; 
1105   }
1106   else {
1107     _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1108                          _currentState ) ; 
1109   }
1110   cdebug << "CurrentState = " << theAutomaton->StateName( _currentState )
1111          << endl;
1112
1113 #if 0
1114   GraphExecutor::InNode * anInNode = (GraphExecutor::InNode *) _OutNode->GetGraphNode( "label_begin" ) ;
1115   const GraphBase::InPort * anInPort = anInNode->GetNodeInPort(0) ;
1116   GraphBase::OutPort * anOutPort = anInPort->GetLink() ;
1117   if ( anOutPort ) {
1118     cdebug << "InPort" << i << " : " << anInPort->PortName() << " from OutPort "
1119            << anOutPort->PortName() << " from Node " << anOutPort->NodeName()
1120            << " with state " ;
1121     if ( anOutPort->State() == SUPERV::WaitingState ) {
1122       cdebug << "WaitingState" ;
1123     }
1124     else if ( anOutPort->State() == SUPERV::ReadyState ) {
1125       cdebug << "ReadyState" ;
1126     }
1127     else {
1128       cdebug << "???" ;
1129     }
1130     cdebug << " PortConnected("
1131            << anOutPort->IsPortConnected() << ") DataConnected("
1132            << anOutPort->IsDataConnected() << ")" << endl ;
1133   }
1134 #endif
1135
1136   cdebug_out << "GraphExecutor::InNode::InitialState" << endl;
1137 }
1138