Salome HOME
The final values of InPorts of EndSwitchNodes in a loop may be wrong
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_InNodeThreads.cxx
1 //  SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : DataFlowBase_InNodeThreads.cxx
25 //  Author : Jean Rahuel, CEA
26 //  Module : SUPERV
27 //  $Header:
28
29 using namespace std;
30
31 #include <stdlib.h>
32 #include <iostream>
33 #include <unistd.h>
34 #include <stdio.h>
35
36 #if defined __GNUC__
37   #if __GNUC__ == 2
38     #define __GNUC_2__
39   #endif
40 #endif
41
42 #if defined __GNUC_2__
43 // _CS_gbo_040604 include explicite pour l'utilisation de
44 // std::transform dans UpperCase
45 #include <cctype> // for toupper
46 #include <algorithm> // for transform
47 #endif
48
49 #include "Python.h"
50
51 #include "OpUtil.hxx"
52
53 #include <SALOMEconfig.h>
54 #include CORBA_CLIENT_HEADER(SALOME_Component)
55 #include "SALOME_LifeCycleCORBA.hxx"
56
57 #include "DataFlowExecutor_DataFlow.hxx"
58 #include "DataFlowEditor_DataFlow.hxx"   // GraphEditor package must be built BEFORE
59
60
61 static void UpperCase(std::string& rstr)
62 {
63 #if defined __GNUC_2__
64   // _CS_gbo_040604 towupper n'existe pas. Utilisation de toupper. Par
65   // ailleurs, include explicite de cctype et algorithm pour toupper
66   // et transform respectivement. 
67   std::transform(rstr.begin(), rstr.end(), rstr.begin(),toupper);
68 #else
69   std::transform(rstr.begin(), rstr.end(), rstr.begin(),towupper);
70 #endif
71 }
72
73
74 int GraphExecutor::InNode::SendEvent( const GraphExecutor::NodeEvent anEvent ) {  
75
76   _CurrentEvent = (GraphExecutor::NodeEvent ) anEvent ;
77   cdebug << pthread_self() << "/" << ThreadNo() << " -->SendEvent Node "  << Name() 
78          << " ControlState : "
79          << Automaton()->ControlStateName( ControlState() )
80          << " Event : " << Automaton()->EventName( anEvent )
81          << " State : " << Automaton()->StateName( State() ) << " _RewindStack " << _RewindStack  << endl;
82
83   _OldState = State() ;
84   _NextState = Automaton()->NextState( _OldState , anEvent ) ;
85   if ( _NextState == _OldState ) {
86     cdebug << pthread_self() << "/" << ThreadNo()
87            << " GraphExecutor::InNodeThreads::SendEvent SameStates "
88            << _OldState << endl ;
89     _NextAction = GraphExecutor::VoidAction ;
90   }
91   else {
92     _NextAction = Automaton()->NextAction( _NextState , anEvent ) ;
93   }
94
95 //  State( _NextState ) ;
96 //  if ( _OldState == GraphExecutor::SuccessedExecutingState ||
97 //       _OldState == GraphExecutor::ErroredExecutingState ) {
98 //    DoneAction() ;
99 //  }
100
101   cdebug << pthread_self() << "/" << ThreadNo() << " SendedEvent Node "
102          << Name() << endl << " ControlState : "
103          << Automaton()->ControlStateName( ControlState() ) << endl
104          << " OldState : " << Automaton()->StateName( _OldState ) << endl
105          << " Event : " << Automaton()->EventName( anEvent ) << endl
106          << " NextState : " << Automaton()->StateName( _NextState ) << endl
107          << " Action : " << Automaton()->ActionName( _NextAction ) << endl
108          << " CreateNewThread " << CreateNewThread() << endl
109          << " _RewindStack " << _RewindStack  << endl ;
110
111 #if 0
112   //cout << pthread_self() << "/" << ThreadNo() << " SendedEvent Node " << Name()
113        << endl << " ControlState : "
114        << Automaton()->ControlStateName( ControlState() ) << endl
115        << " OldState : " << Automaton()->StateName( _OldState ) << endl
116        << " Event : " << Automaton()->EventName( anEvent ) << endl
117        << " NextState : " << Automaton()->StateName( _NextState ) << endl
118        << " Action : " << Automaton()->ActionName( _NextAction ) << endl
119        << " CreateNewThread " << CreateNewThread() << endl ;
120 #endif
121
122   int sts = executeAction() ;
123   
124   cdebug << pthread_self() << "/" << ThreadNo() << " <--- SendEvent Node " << Name() 
125          << " Event : " << Automaton()->EventName( anEvent )
126          << " State : " << Automaton()->StateName( State() )
127          << endl;
128
129   return sts ;
130
131 }
132
133 // ReadyAction - RunningAction - DoneAction - SuspendedAction :
134 // for StateWait( ReadyW - RunningW - DoneW - SuspendedW )
135 void GraphExecutor::InNode::ReadyAction() {
136   if ( pthread_mutex_lock( &_MutexWait ) ) {
137     perror("Ready pthread_mutex_lock ") ;
138     exit( 0 ) ;
139   }
140   cdebug << pthread_self() << "/" << ThreadNo()
141          << "ReadyAction pthread_cond_broadcast _ReadyWait "
142          << Name() << endl ;
143   if ( pthread_cond_broadcast( &_ReadyWait ) ) {
144     perror("Ready pthread_cond_broadcast ") ;
145   }
146   if ( pthread_mutex_unlock( &_MutexWait ) ) {
147     perror("Ready pthread_mutex_unlock ") ;
148     exit( 0 ) ;
149   }
150 }
151
152 void GraphExecutor::InNode::RunningAction() {
153   if ( pthread_mutex_lock( &_MutexWait ) ) {
154     perror("Running pthread_mutex_lock ") ;
155     exit( 0 ) ;
156   }
157   cdebug << pthread_self() << "/" << ThreadNo()
158          << "RunningAction pthread_cond_broadcast _RunningWait "
159          << Name() << endl ;
160 // That activate the pthread_cond_wait for RunninWait
161   if ( pthread_cond_broadcast( &_RunningWait ) ) {
162     perror("Running pthread_cond_broadcast ") ;
163   }
164   if ( pthread_mutex_unlock( &_MutexWait ) ) {
165     perror("Running pthread_mutex_unlock ") ;
166     exit( 0 ) ;
167   }
168 }
169
170 void GraphExecutor::InNode::DoneAction() {
171   if ( pthread_mutex_lock( &_MutexWait ) ) {
172     perror("Done pthread_mutex_lock ") ;
173     exit( 0 ) ;
174   }
175   cdebug << pthread_self() << "/" << ThreadNo()
176          << "DoneAction pthread_cond_broadcast _DoneWait "
177          << Name() << endl ;
178   if ( pthread_cond_broadcast( &_DoneWait ) ) {
179     perror("Done pthread_cond_broadcast ") ;
180   }
181   if ( pthread_mutex_unlock( &_MutexWait ) ) {
182     perror("Done pthread_mutex_unlock ") ;
183     exit( 0 ) ;
184   }
185 }
186
187 void GraphExecutor::InNode::SuspendedAction() {
188   if ( pthread_mutex_lock( &_MutexWait ) ) {
189     perror("Suspended pthread_mutex_lock ") ;
190     exit( 0 ) ;
191   }
192   cdebug << pthread_self() << "/" << ThreadNo()
193          << "SuspendedAction pthread_cond_broadcast _SuspendedWait "
194          << Name() << endl ;
195   if ( pthread_cond_broadcast( &_SuspendedWait ) ) {
196     perror("Suspended pthread_cond_broadcast ") ;
197   }
198   if ( pthread_mutex_unlock( &_MutexWait ) ) {
199     perror("Suspended pthread_mutex_unlock ") ;
200     exit( 0 ) ;
201   }
202 }
203
204 // SuspendAction <--> { ResumeAction - ReStartAction }
205 GraphExecutor::InNode * GraphExecutor::InNode::SuspendAction() {
206   SuspendedAction() ;
207   if ( pthread_mutex_lock( &_MutexWait ) ) {
208     perror("Suspend pthread_mutex_lock ") ;
209     exit( 0 ) ;
210   }
211   if ( !_SuspendSync ) {
212     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
213            << " SuspendAction pthread_cond_wait _SuspendWait "
214            << Automaton()->StateName( State() ) << endl ;
215     _SuspendSync = true ;
216     _OutNode->SuspendThread() ;
217     if ( pthread_cond_wait( &_SuspendWait , &_MutexWait ) ) {
218       perror("SuspendAction pthread_cond_wait ") ;
219     }
220     _OutNode->ResumeThread() ;
221     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
222            << " SuspendAction pthread_cond_waited"  
223            << Automaton()->StateName( State() ) << endl ;
224   }
225   else {
226     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
227            << " NO SuspendAction pthread_cond_wait"  
228            << Automaton()->StateName( State() ) << endl ;
229   }
230 //  SendEvent( _aResumeEvent ) ; ===> Mutex with myself !
231   _SuspendSync = false ;  
232   if ( ControlState() == SUPERV::ToSuspendStartState ||
233        ControlState() == SUPERV::ToSuspendState ) {
234     ControlState( SUPERV::VoidState ) ;
235   }
236   if ( pthread_mutex_unlock( &_MutexWait ) ) {
237     perror("SuspendAction pthread_mutex_unlock ") ;
238     exit( 0 ) ;
239   }
240
241   SendEvent( _aResumeEvent ) ;
242 //  if ( ControlState() == SUPERV::ToSuspendStartState ) {
243 //    ControlState( SUPERV::VoidState ) ;
244 //  }
245
246   if ( pthread_mutex_lock( &_MutexWait ) ) {
247     perror("SuspendAction pthread_mutex_lock ") ;
248     exit( 0 ) ;
249   }
250   if ( _ResumeSync ) {
251     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
252            << " SuspendAction pthread_cond_signal _ResumeWait" << endl ;
253     if ( pthread_cond_signal( &_ResumeWait ) ) {
254       perror("SuspendAction pthread_cond_signal _ResumeWait ") ;
255     }
256     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
257            << " SuspendAction pthread_cond_signaled _ResumeWait " << endl ;
258   }
259   else {
260     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
261            << " NO SuspendAction pthread_cond_signal _ResumeWait" << endl ;
262     _ResumeSync = true ;  
263   }
264   if ( pthread_mutex_unlock( &_MutexWait ) ) {
265     perror("SuspendAction pthread_mutex_unlock ") ;
266     exit( 0 ) ;
267   }
268   if ( _aReStartNode ) {
269     cdebug << Name() << " " << Automaton()->StateName( State() )
270            << "aReStartNode : " << _aReStartNode->Name() << " "
271            << Automaton()->StateName( _aReStartNode->State() ) << endl ;
272     _aReStartNode->SendEvent( _aResumeEvent ) ;
273   }
274   else {
275     cdebug << "NO aReStartNode" 
276            << Automaton()->StateName( State() ) << endl ;
277   }
278   return _aReStartNode ;
279 }
280
281 bool GraphExecutor::InNode::ResumeAction( GraphExecutor::NodeEvent aResumeEvent ) {
282   bool RetVal ;
283   if ( pthread_mutex_lock( &_MutexWait ) ) {
284     perror("ResumeAction pthread_mutex_lock ") ;
285     exit( 0 ) ;
286   }
287   _aResumeEvent = aResumeEvent ;
288   if ( _SuspendSync ) {
289     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
290            << " ResumeAction pthread_cond_signal" << endl ;
291     if ( pthread_cond_signal( &_SuspendWait ) ) {
292       perror("ResumeAction pthread_cond_signal ") ;
293     }
294     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
295            << " ResumeAction pthread_cond_signaled _SuspendWait " << endl ;
296     RetVal = true ;
297   }
298   else {
299     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
300            << " NO ResumeAction pthread_cond_signal" << endl ;
301     if ( pthread_self() == ThreadNo() ) {
302       RetVal = false ; /*/ Ne pas s'attendre soi-meme !...*/
303     }
304     else {
305       _SuspendSync = true ;
306       RetVal = true ; // Il faut tout de meme attendre ci-apres ...
307     }
308   }
309   if ( pthread_mutex_unlock( &_MutexWait ) ) {
310     perror("ResumeAction pthread_mutex_unlock ") ;
311     exit( 0 ) ;
312   }
313
314   if ( RetVal ) {
315     if ( pthread_mutex_lock( &_MutexWait ) ) {
316       perror("ResumeAction pthread_mutex_lock ") ;
317       exit( 0 ) ;
318     }
319     if ( !_ResumeSync ) {
320       cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond "
321              << Name() << " ResumeAction pthread_cond_wait _ResumeWait " 
322              << Automaton()->StateName( State() ) << endl ;
323       _ResumeSync = true ;
324       if ( pthread_cond_wait( &_ResumeWait , &_MutexWait ) ) {
325         perror("ResumeAction pthread_cond_wait ") ;
326       }
327       cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond "
328              << Name() << " ResumeAction pthread_cond_waited _ResumeWait"  
329              << Automaton()->StateName( State() ) << endl ;
330       RetVal = true ;
331     }
332     else {
333       cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond "
334              << Name() << " NO ResumeAction pthread_cond_wait _ResumeWait" 
335              << Automaton()->StateName( State() ) << endl ;
336       RetVal = false ;
337     }
338     _ResumeSync = false ;  
339     if ( pthread_mutex_unlock( &_MutexWait ) ) {
340       perror("ResumeAction pthread_mutex_unlock ") ;
341       exit( 0 ) ;
342     }
343   }
344   cdebug << pthread_self() << "/" << ThreadNo()
345          << "GraphExecutor::InNodeThreads::ResumeAction RetVal " << RetVal << endl ;
346   return RetVal ;
347 }
348
349 bool GraphExecutor::InNode::ReStartAction( GraphExecutor::InNode * aReStartNode ,
350                                            GraphExecutor::NodeEvent anEvent ) {
351   GraphExecutor::InNode * oldReStartNode = _aReStartNode ;
352   _aReStartNode = aReStartNode ;
353   _aReStartEvent = anEvent ;
354   cdebug << pthread_self() << " GraphExecutor::InNodeThreads::ReStartAction from "
355          << Name() << " " << Automaton()->StateName( State() ) << " to "
356          << aReStartNode->ThreadNo() << " " << aReStartNode->Name() << " "
357          << Automaton()->StateName( aReStartNode->State() ) ;
358   if ( oldReStartNode ) {
359     cdebug << " oldReStartNode " << oldReStartNode->Name() << endl ;
360   }
361   else {
362     cdebug << endl ;
363   }
364   return ResumeAction( GraphExecutor::ToReStartEvent ) ;
365 }
366
367 void GraphExecutor::InNode::KilledAction() {
368   if ( pthread_mutex_lock( &_MutexWait ) ) {
369     perror("Killed pthread_mutex_lock ") ;
370     exit( 0 ) ;
371   }
372   if ( !_KillSync ) {
373     cdebug << "pthread_cond " << Name() << " Killed pthread_cond_wait"
374            << endl ;
375     _KillSync = true ;
376     if ( pthread_cond_wait( &_KillWait , &_MutexWait ) ) {
377       perror("Killed pthread_cond_wait ") ;
378     }
379     cdebug << "pthread_cond " << Name() << " Killed pthread_cond_waited"
380            << endl ;
381   }
382   else {
383     cdebug << "pthread_cond " << Name() << " NO Killed pthread_cond_wait"
384            << endl ;
385   }
386   _KillSync = false ;  
387   if ( pthread_mutex_unlock( &_MutexWait ) ) {
388     perror("Killed pthread_mutex_unlock ") ;
389     exit( 0 ) ;
390   }
391 }
392
393 void GraphExecutor::InNode::KillAction() {
394   if ( pthread_mutex_lock( &_MutexWait ) ) {
395     perror("Kill pthread_mutex_lock ") ;
396     exit( 0 ) ;
397   }
398   if ( _KillSync ) {
399     cdebug << "pthread_cond " << Name() << " Kill pthread_cond_signal"
400            << endl ;
401 //    if ( pthread_cond_broadcast( &_KillWait ) ) {
402     if ( pthread_cond_signal( &_KillWait ) ) {
403       perror("Kill pthread_cond_broadcast ") ;
404     }
405     cdebug << "pthread_cond " << Name() << " Kill pthread_cond_signaled"
406            << endl ;
407   }
408   else {
409     cdebug << "pthread_cond " << Name() << " NO Kill pthread_cond_signal"
410            << endl ;
411     _KillSync = true ;  
412   }
413   if ( pthread_mutex_unlock( &_MutexWait ) ) {
414     perror("Kill pthread_mutex_unlock ") ;
415     exit( 0 ) ;
416   }
417 }
418
419 void GraphExecutor::InNode::StoppedAction() {
420   if ( pthread_mutex_lock( &_MutexWait ) ) {
421     perror("Stopped pthread_mutex_lock ") ;
422     exit( 0 ) ;
423   }
424   if ( pthread_cond_wait( &_StopWait , &_MutexWait ) ) {
425     perror("Stopped pthread_cond_wait ") ;
426   }
427   if ( pthread_mutex_unlock( &_MutexWait ) ) {
428     perror("Stopped pthread_mutex_unlock ") ;
429     exit( 0 ) ;
430   }
431 }
432
433 void GraphExecutor::InNode::StopAction() {
434   if ( pthread_mutex_lock( &_MutexWait ) ) {
435     perror("Stop pthread_mutex_lock ") ;
436     exit( 0 ) ;
437   }
438   if ( pthread_cond_broadcast( &_StopWait ) ) {
439     perror("Stop pthread_cond_broadcast ") ;
440   }
441   if ( pthread_mutex_unlock( &_MutexWait ) ) {
442     perror("Stop pthread_mutex_unlock ") ;
443     exit( 0 ) ;
444   }
445 }
446
447 void GraphExecutor::InNode::ThreadStartedAction() {
448   if ( pthread_mutex_lock( &_MutexWait ) ) {
449     perror("ThreadStarted pthread_mutex_lock ") ;
450     exit( 0 ) ;
451   }
452   if ( !_ThreadStartedSync ) {
453     cdebug << pthread_self() << "/" << ThreadNo()
454            << "pthread_cond " << Name() << " ThreadStarted pthread_cond_wait"
455            << endl ;
456     _ThreadStartedSync = true ;
457     if ( pthread_cond_wait( &_ThreadStartedWait , &_MutexWait ) ) {
458       perror("ThreadStarted pthread_cond_wait ") ;
459     }
460     cdebug << pthread_self() << "/" << ThreadNo()
461            << "pthread_cond " << Name() << " ThreadStarted pthread_cond_waited"
462            << endl ;
463   }
464   else {
465     cdebug << pthread_self() << "/" << ThreadNo()
466            << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_wait"
467            << endl ;
468 //Debug :
469     _ThreadStartedSync = false ;  
470     if ( pthread_cond_signal( &_ThreadStartedWait ) ) {
471       perror("ThreadStart pthread_cond_signal ") ;
472     }
473 //Debug
474     cdebug << pthread_self() << "/" << ThreadNo()
475            << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_signaled"
476            << endl ;
477   }
478   if ( pthread_mutex_unlock( &_MutexWait ) ) {
479     perror("ThreadStarted pthread_mutex_unlock ") ;
480     exit( 0 ) ;
481   }
482 }
483
484 void GraphExecutor::InNode::ThreadStartAction() {
485   if ( pthread_mutex_lock( &_MutexWait ) ) {
486     perror("ThreadStart pthread_mutex_lock ") ;
487     exit( 0 ) ;
488   }
489   if ( _ThreadStartedSync ) {
490     cdebug << pthread_self() << "/" << ThreadNo()
491            << "pthread_cond " << Name() << " ThreadStart pthread_cond_signal"
492            << endl ;
493     _ThreadStartedSync = false ;  
494     if ( pthread_cond_signal( &_ThreadStartedWait ) ) {
495       perror("ThreadStart pthread_cond_broadcast ") ;
496     }
497     cdebug << pthread_self() << "/" << ThreadNo()
498            << "pthread_cond " << Name() << " ThreadStart pthread_cond_signaled"
499            << endl ;
500   }
501   else {
502     cdebug << pthread_self() << "/" << ThreadNo()
503            << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_signal"
504            << endl ;
505     _ThreadStartedSync = true ;
506 //Debug :
507     if ( pthread_cond_wait( &_ThreadStartedWait , &_MutexWait ) ) {
508       perror("ThreadStarted pthread_cond_wait ") ;
509     }
510 //Debug
511     cdebug << pthread_self() << "/" << ThreadNo()
512            << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_waited"
513            << endl ;
514   }
515   if ( pthread_mutex_unlock( &_MutexWait ) ) {
516     perror("ThreadStart pthread_mutex_unlock ") ;
517     exit( 0 ) ;
518   }
519 }
520
521 int GraphExecutor::InNode::executeAction() {
522   int oldRewindStack = ( _RewindStack > MAXSTACKTHREADSIZE ) ;
523   if ( !CreateNewThread() && oldRewindStack ) {
524     cdebug << pthread_self() << "/" << ThreadNo()
525            << " executeAction start Thread _RewindStack " << _RewindStack << " > "
526            << MAXSTACKTHREADSIZE << " CreateNewThread "
527            << CreateNewThread() << " " << Automaton()->ActionName( _NextAction ) << "(" << Name() << ")"
528            << endl;
529     CreateNewThread( true ) ;
530     ThreadNo( 0 ) ;
531   }
532   if ( CreateNewThread() ) {
533     CreateNewThread( false ) ;
534     if ( ThreadNo() == 0 ) {
535       _RewindStack = 1 ;
536       cdebug << pthread_self() << "/" << ThreadNo()
537              << " executeAction start Thread _RewindStack " << _RewindStack << " "
538              << Automaton()->ActionName( _NextAction ) << "(" << Name() << ")"
539              << endl;
540       pthread_t T;
541       int pthread_sts = 1 ;
542 //      _OutNode->PushEvent( NULL , GraphExecutor::NewThreadEvent ,
543 //                           GraphExecutor::ExecutingState ) ; 
544       while ( (pthread_sts = pthread_create(&T, NULL, run_function, this )) ) {
545         char * msg = "Cannot pthread_create " ;
546         perror( msg ) ;
547         cdebug << ThreadNo() << " " << msg << " --> sleep(5)" << endl ;
548         cdebug << ThreadNo() << " PTHREAD_THREADS_MAX : "
549                << PTHREAD_THREADS_MAX << " pthread_create status : " ;
550         if ( pthread_sts == EAGAIN ) {
551           cdebug << "EAGAIN(" << pthread_sts << ")" << endl ;
552           cdebug << "It seems to me that with gdb we are limited to 256 threads because of defunct" << endl ;
553         }
554         else {
555           cdebug << pthread_sts << endl ;
556         }
557         string smsg = msg ;
558         delete [] msg ;
559         pthread_exit( msg ) ;
560       }
561       cdebug << pthread_self() << "/" << ThreadNo()
562              << "executeAction has created thread " << T << endl ;
563       ThreadStartedAction() ;
564       cdebug << pthread_self() << "/" << ThreadNo()
565              << "executeAction the thread " << T << " has called NewThread and will call ExecuteAction for node "
566              << Name() << endl ;
567     }
568     else {
569       cdebug << pthread_self() << "/" << ThreadNo()
570              << " executeAction restart Thread _RewindStack " << _RewindStack << " "
571              << Automaton()->StateName( State() ) << " "
572              << Automaton()->ActionName( _NextAction ) << "(" << Name()
573              << ") ReStartAction ==>" << endl;
574       State( GraphExecutor::SuspendedSuccessedState ) ;
575       if ( !ReStartAction( this , GraphExecutor::ReStartEvent ) ) {
576         cdebug << pthread_self() << "/" << ThreadNo()
577                << " executeAction STATE & CALLED "
578                << Automaton()->ActionName( _NextAction ) << "(" << Name()
579                << ") ERROR-DEBUG " << endl;
580       }
581       else {
582         cdebug << pthread_self() << "/" << ThreadNo() << " executeAction NO CALL "
583                << Automaton()->ActionName( _NextAction ) << "(" << Name()
584                << ")" << endl;
585       }
586     }
587   }
588   else {
589     if ( _CurrentEvent == ExecuteEvent ) {
590       _RewindStack += 1 ;
591     }
592     cdebug << pthread_self() << "/" << ThreadNo() << " executeAction call "
593            << Automaton()->ActionName( _NextAction ) << "(" << Name() << ") _RewindStack " << _RewindStack
594            << endl;
595     return ExecuteAction() ;
596   }
597   return 1 ;
598 }
599
600 void GraphExecutor::InNode::coutbegin() {
601   cdebug << pthread_self() << "/" << ThreadNo() << " run_function begin"
602          << " " << Name() << " " << Automaton()->StateName( State() ) << endl ;
603 }
604 void GraphExecutor::InNode::coutexit() {
605   cdebug << pthread_self() << "/" << ThreadNo() << " run_function pthread_exit _RewindStack " << _RewindStack
606          << " " << Name() << " " << Automaton()->StateName( State() ) << endl ;
607 }
608 void * run_function(void *p) {
609   GraphExecutor::InNode *aNode = (GraphExecutor::InNode *) p;
610   aNode->coutbegin() ;
611   aNode->NewThread( pthread_self() ) ;
612   if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) ) {
613     perror("pthread_setcanceltype ") ;
614     exit(0) ;
615   }
616   if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) ) {
617     perror("pthread_setcancelstate ") ;
618     exit(0) ;
619   }
620   aNode->ThreadStartAction() ;
621 //  cout << "run_function " << aNode->Name() << "->ExecuteAction() Coupled : " << aNode->CoupledNode()
622 //       << endl ;
623   aNode->ExecuteAction() ;
624   char * msg = new char[40] ;
625   sprintf( msg , "%d" , (int ) aNode->ThreadNo() ) ;
626   strcat( msg , " thread exit" ) ;
627   aNode->coutexit() ;
628   aNode->ExitThread() ;
629   string smsg = msg ;
630   delete [] msg ;
631   pthread_exit( (void * ) smsg.c_str() ) ;
632   return msg ;
633 }
634
635 int GraphExecutor::InNode::ExecuteAction() {
636   int sts ;
637
638   const char * nextactionname = Automaton()->ActionName( _NextAction ) ;
639   const char * statename = Automaton()->StateName( State() ) ;
640   const char * nextstatename = Automaton()->StateName( _NextState ) ;
641   cdebug_in << pthread_self() << "/" << ThreadNo() << " --> ExecuteAction "
642             << nextactionname << " "  << statename << " NextState "
643             << nextstatename << endl ;
644
645   State( _NextState ) ;
646   switch ( _NextAction ) {
647   case GraphExecutor::ErrorAction : {
648     sts = ErrorAction() ;
649     break ;
650   }
651   case GraphExecutor::VoidAction : {
652     sts = VoidAction() ;
653     break ;
654   }
655   case GraphExecutor::DataWaiting_SomeDataReadyAction : {
656     sts = DataWaiting_SomeDataReadyAction() ;
657     break ;
658   }
659   case GraphExecutor::DataUndef_NotAllDataReadyAction : {
660     sts = DataUndef_NotAllDataReadyAction() ;
661     break ;
662   }
663   case GraphExecutor::DataUndef_AllDataReadyAction : {
664     sts = DataUndef_AllDataReadyAction() ;
665     break ;
666   }
667   case GraphExecutor::DataReady_SuspendAction : {
668     sts = DataReady_SuspendAction() ;
669     break ;
670   }
671   case GraphExecutor::SuspendedReady_ResumeAction : {
672     sts = SuspendedReady_ResumeAction() ;
673     break ;
674   }
675   case GraphExecutor::DataReady_KillAction : {
676     sts = DataReady_KillAction() ;
677     break ;
678   }
679   case GraphExecutor::DataReady_StopAction : {
680     sts = DataReady_StopAction() ;
681     break ;
682   }
683   case GraphExecutor::DataReady_ExecuteAction : {
684     sts = DataReady_ExecuteAction() ;
685     break ;
686   }
687   case GraphExecutor::Executing_SuspendAction : {
688     sts = Executing_SuspendAction() ;
689     break ;
690   }
691   case GraphExecutor::SuspendedExecuting_ResumeAction : {
692     sts = SuspendedExecuting_ResumeAction() ;
693     break ;
694   }
695   case GraphExecutor::Executing_KillAction : {
696     sts = Executing_KillAction() ;
697     break ;
698   }
699   case GraphExecutor::Executing_StopAction : {
700     sts = Executing_StopAction() ;
701     break ;
702   }
703   case GraphExecutor::Executing_SuccessAction : {
704     sts = Executing_SuccessAction() ;
705     break ;
706   }
707   case GraphExecutor::Executing_ErrorAction : {
708     sts = Executing_ErrorAction() ;
709     break ;
710   }
711   case GraphExecutor::Successed_SuccessAction : {
712     sts = Successed_SuccessAction() ;
713     break ;
714   }
715   case GraphExecutor::Errored_ErrorAction : {
716     sts = Errored_ErrorAction() ;
717     break ;
718   }
719   case GraphExecutor::Successed_SuspendAction : {
720     sts = Successed_SuspendAction() ;
721     break ;
722   }
723   case GraphExecutor::Errored_SuspendAction : {
724     sts = Errored_SuspendAction() ;
725     break ;
726   }
727   case GraphExecutor::SuspendedSuccessed_ResumeAction : {
728     sts = SuspendedSuccessed_ResumeAction() ;
729     break ;
730   }
731   case GraphExecutor::SuspendedErrored_ResumeAction : {
732     sts = SuspendedErrored_ResumeAction() ;
733     break ;
734   }
735   case GraphExecutor::Successed_KillAction : {
736     sts = Successed_KillAction() ;
737     break ;
738   }
739   case GraphExecutor::Errored_KillAction : {
740     sts = Errored_KillAction() ;
741     break ;
742   }
743   case GraphExecutor::Successed_StopAction : {
744     sts = Successed_StopAction() ;
745     break ;
746   }
747   case GraphExecutor::Errored_StopAction : {
748     sts = Errored_StopAction() ;
749     break ;
750   }
751   case GraphExecutor::SuspendedSuccessed_ReStartAction : {
752     sts = SuspendedSuccessed_ReStartAction() ;
753     break ;
754   }
755   case GraphExecutor::SuspendedErrored_ReStartAction : {
756     sts = SuspendedErrored_ReStartAction() ;
757     break ;
758   }
759   case GraphExecutor::SuspendedSuccessed_ReStartAndSuspendAction : {
760     sts = SuspendedSuccessed_ReStartAndSuspendAction() ;
761     break ;
762   }
763   case GraphExecutor::SuspendedErrored_ReStartAndSuspendAction : {
764     sts = SuspendedErrored_ReStartAndSuspendAction() ;
765     break ;
766   }
767   default : {
768     cdebug << pthread_self() << "/" << ThreadNo()
769            << " GraphExecutor::InNodeThreads::SendEvent Error Undefined Action : "
770            << _NextAction << endl ;
771     return 0 ;
772   }
773   }
774   cdebug_out << pthread_self() << "/" << ThreadNo() << "<-- ExecuteAction "
775              << nextactionname << endl ;
776   return sts ;
777 }
778
779 int GraphExecutor::InNode::ErrorAction() {
780   cdebug << pthread_self() << "/" << ThreadNo() << " Automaton ErrorAction Node "
781          << Name() << endl;
782   return 0;
783 }
784
785 int GraphExecutor::InNode::VoidAction() {
786   cdebug << pthread_self() << "/" << ThreadNo() << " VoidAction "  << Name() << endl;
787   return 1;
788 }
789
790
791 int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
792   cdebug << pthread_self() << "/" << ThreadNo()
793          << " --> DataWaiting_SomeDataReadyAction from " << DataFromNode()
794          << " to " << Name() << endl;
795   unsigned int k;
796   int InReady = 0 ;
797   int res = 1;
798   bool LoopBeginning = false ;
799   bool LoopFinished = false ;
800   bool SwitchFinished = false ;
801
802   if ( IsLoopNode() ) {
803     GraphBase::OutPort * anOutLoopPort = GetChangeNodeInLoop()->GetOutPort() ;
804     if ( anOutLoopPort && anOutLoopPort->BoolValue() ) {
805       LoopBeginning = true ; // Beginning of Loop
806     }
807   }
808   if ( IsEndLoopNode() ) {
809     GraphBase::OutPort * anOutLoopPort = GetChangeNodeInLoop()->GetOutPort() ;
810     if ( anOutLoopPort && !anOutLoopPort->BoolValue() ) {
811       LoopFinished = true ; // End of Loop
812     }
813   }
814   if ( IsEndSwitchNode() ) {
815     GraphBase::OutPort * anOutGateSwitchPort = GetChangeNodeInGate()->GetOutPort() ;
816     if ( anOutGateSwitchPort && !anOutGateSwitchPort->BoolValue() ) {
817       SwitchFinished = true ; // End of Switch
818     }
819   }
820   cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " LoopFinished " << LoopFinished
821          << " LoopBeginning " << LoopBeginning << " SwitchFinished " << SwitchFinished << endl ;
822   for ( k = 0 ; k < (unsigned int ) GetNodeInPortsSize() ; k++ ) {
823     GraphBase::InPort * anInPort = GetChangeNodeInPort(k) ;
824     GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
825     cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort " << anInPort->PortName() << " " << anInPort->State() << " " << anInPort->PortStatus() << endl ;
826     if ( anInPort->IsGate() && anOutPort == NULL ) {
827       InReady += 1 ;
828       anInPort->State( SUPERV::ReadyState ) ;
829       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
830              << anInPort->PortName() << " ControlPort inactive." << endl ;
831     }
832 // That InPort get its value from an other node
833     else if ( strcmp( DataFromNode() , anOutPort->NodeName() ) ) {
834       if ( anInPort->State() == SUPERV::ReadyState ) {
835         InReady += 1 ;
836         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
837                << anInPort->PortName() << " Was Done from Node "
838                << anOutPort->NodeName() << "( " << anOutPort->PortName()
839                << ") ReadyState " ;
840 #ifdef _DEBUG_
841         if ( GraphBase::Base::_prof_debug ) {
842           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
843         }
844 #endif
845         cdebug << endl ;
846       }
847       else if ( IsLoopNode() && anInPort->IsDataConnected() ) {
848         anInPort->State( SUPERV::ReadyState ) ;
849         InReady += 1 ;
850         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
851                << anInPort->PortName() << " Was Done from Node "
852                << anOutPort->NodeName() << "( " << anOutPort->PortName()
853                << ") LoopBeginning " << LoopBeginning ;
854 #ifdef _DEBUG_
855         if ( GraphBase::Base::_prof_debug ) {
856           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
857         }
858 #endif
859         cdebug << endl ;
860       }
861       else if ( LoopFinished ) {
862         anInPort->State( SUPERV::ReadyState ) ;
863         InReady += 1 ;
864         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
865                << anInPort->PortName() << " Was Done from Node "
866                << anOutPort->NodeName() << "( " << anOutPort->PortName()
867                << ") LoopFinished" ;
868 #ifdef _DEBUG_
869         if ( GraphBase::Base::_prof_debug ) {
870           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
871         }
872 #endif
873         cdebug << endl ;
874       }
875       else if ( anInPort->IsGate() && SwitchFinished ) {
876         anInPort->State( SUPERV::ReadyState ) ;
877         InReady += 1 ;
878         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
879                << anInPort->PortName() << " Was Done from Node "
880                << anOutPort->NodeName() << "( " << anOutPort->PortName()
881                << ") SwitchFinished" ;
882 #ifdef _DEBUG_
883         if ( GraphBase::Base::_prof_debug ) {
884           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
885         }
886 #endif
887         cdebug << endl ;
888       }
889       else {
890         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
891                << anInPort->PortName() << " Was NOT Done from Node "
892                << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
893                << " " << Automaton()->StateName( State() ) << " DataConnected "
894                << anInPort->IsDataConnected() << " LoopBeginning "
895                << LoopBeginning << endl ;
896       }
897     }
898 // That InPort get its value from the sending node
899     else if ( anInPort->IsGate() ) {
900       const CORBA::Any * theValue = anOutPort->Value() ;
901       long GateOpened ;
902       (*theValue) >>= GateOpened ;
903       if ( GateOpened != 0 ) {
904         InReady += 1 ;
905         anInPort->State( SUPERV::ReadyState ) ;
906         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
907                << anInPort->PortName() << " Gate is Opened from Node "
908                << anOutPort->NodeName() << "( " << anOutPort->PortName()
909                << ") " ;
910 #ifdef _DEBUG_
911         if ( GraphBase::Base::_prof_debug ) {
912           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
913         }
914 #endif
915         cdebug << endl ;
916       }
917       else if ( LoopFinished ) {
918         anInPort->State( SUPERV::ReadyState ) ;
919         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
920                << anInPort->PortName() << " GATE IS CLOSED from Node "
921                << anOutPort->NodeName() << "( " << anOutPort->PortName()
922                << ") LoopFinished" ;
923 #ifdef _DEBUG_
924         if ( GraphBase::Base::_prof_debug ) {
925           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
926         }
927 #endif
928         cdebug << endl ;
929       }
930       else {
931         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
932                << anInPort->PortName() << " GATE IS CLOSED from Node "
933                << anOutPort->NodeName() << "( " << anOutPort->PortName()
934                << ") " ;
935 #ifdef _DEBUG_
936         if ( GraphBase::Base::_prof_debug ) {
937           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
938         }
939 #endif
940         cdebug << endl ;
941       }
942     }
943     else if ( anOutPort->Done() ) {
944       InReady += 1 ;
945       anInPort->State( SUPERV::ReadyState ) ;
946       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
947              << anInPort->PortName() << " " << anInPort->PortStatus() << " is Done from Node "
948              << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
949              << anOutPort->PortStatus() << " " ;
950 #ifdef _DEBUG_
951       if ( GraphBase::Base::_prof_debug ) {
952         anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
953       }
954 #endif
955       cdebug << endl ;
956 // MacroNode : give immediately the value to the corresponding graph
957       if ( IsMacroNode() ) {
958         cout << "SomeDataReadyAction " << GraphMacroNode() << " " << GraphMacroNode()->Name()
959              << " coupled to " << GraphMacroNode()->CoupledNode() << endl ;
960         GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
961         cdebug << "SomeDataReadyAction MacroNode " << aMacroGraph->Graph()->Name() << " --> InputOfAny "
962                << InReady << "/" << GetNodeInPortsSize() << " InPorts are Ready" << endl ;
963 //        GraphMacroNode()->MacroObject()->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
964         aMacroGraph->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
965       }
966     }
967     else {
968       cdebug << pthread_self() << "/" << ThreadNo() << " Node " << Name() << "( "
969              << anInPort->PortName() << ") " << anInPort->PortStatus()
970              << " is NOT Done from Node "
971              << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
972              << anOutPort->PortStatus() << " " ;
973     }
974   }
975
976   if ( InReady == GetNodeInPortsSize() ) { // All Flags != 0 :
977     res = SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
978   }
979   else { // At least one Flag == 0 :
980     res = SendEvent( GraphExecutor::NotAllDataReadyEvent );
981   }
982
983   cdebug << pthread_self() << "/" << ThreadNo()
984          << " <-- DataWaiting_SomeDataReadyAction "  << Name() << endl;
985   return res ;
986
987 }
988
989 int GraphExecutor::InNode::DataUndef_NotAllDataReadyAction() {
990   CreateNewThreadIf( false ) ;
991 //  cdebug << pthread_self() << " for " << ThreadNo()
992 //         << " DataUndef_NotAllDataReadyAction " << Name() << endl;
993   return 1;
994 }
995
996 int GraphExecutor::InNode::DataUndef_AllDataReadyAction() {
997 //  cdebug << pthread_self() << "/" << ThreadNo()
998 //         << " --> DataUndef_AllDataReadyAction " << Name()
999 //         << " CreateNewThreadIf " << CreateNewThreadIf() << " IsLockedDataWait "
1000 //         << IsLockedDataWait() ;
1001   if ( IsLockedDataWait() ) {
1002     cdebug << "DataUndef_AllDataReadyAction() WOULD DEAD-LOCK" << endl ;
1003     return 0 ; // ==> DataUndef_AllDataReadyAction() after UnLockDataWait()
1004   }
1005 //  cdebug << endl ;
1006   CreateNewThread( CreateNewThreadIf() ) ;
1007   if ( !CreateNewThread() ) {
1008 //    cdebug << "Thread " << ThreadNo() << "-->" << pthread_self() << endl ;
1009     ThreadNo( pthread_self() ) ;
1010   }
1011   _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1012                        GraphExecutor::DataReadyState ) ; 
1013   ReadyAction() ;
1014   SUPERV::ControlState aControl = ControlState() ;
1015   switch ( aControl ) {
1016   case SUPERV::VoidState : {
1017     SendEvent( GraphExecutor::ExecuteEvent ) ;
1018     break ;
1019   }
1020   case SUPERV::ToSuspendState : {
1021     SendEvent( GraphExecutor::SuspendEvent ) ;
1022     break ;
1023   }
1024   case SUPERV::ToSuspendStartState : {
1025     SendEvent( GraphExecutor::SuspendEvent ) ;
1026     break ;
1027   }
1028   case SUPERV::ToSuspendDoneState : {
1029     SendEvent( GraphExecutor::ExecuteEvent ) ;
1030     break ;
1031   }
1032   case SUPERV::ToKillState : {
1033     SendEvent( GraphExecutor::KillEvent ) ;
1034     break ;
1035   }
1036   case SUPERV::ToKillDoneState : {
1037     SendEvent( GraphExecutor::ExecuteEvent ) ;
1038     break ;
1039   }
1040   case SUPERV::ToStopState : {
1041     SendEvent( GraphExecutor::StopEvent ) ;
1042     break ;
1043   }
1044   default : {
1045     cdebug << ThreadNo()
1046            << " GraphExecutor::InNodeThreads::DataUndef_AllDataReadyAction Error Undefined Control : "
1047            << aControl << endl ;
1048     return 0;
1049   }
1050   }
1051 //  cdebug << pthread_self() << "/" << ThreadNo()
1052 //         << " <-- DataUndef_AllDataReadyAction " << Name() << endl;
1053   return 1;
1054 }
1055
1056 int GraphExecutor::InNode::DataReady_SuspendAction() {
1057   cdebug << pthread_self() << "/" << ThreadNo()
1058          << "DataReady_SuspendAction --> Suspend " << Name()
1059          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
1060          << _OutNode->SuspendedThreads() << endl;
1061   _OutNode->PushEvent( this , GraphExecutor::SuspendedReadyEvent ,
1062                        GraphExecutor::SuspendedReadyState ) ;
1063   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
1064   cdebug << pthread_self() << "/" << ThreadNo()
1065          << "DataReady_SuspendAction Resumed " << Name() << endl;
1066   if ( aReStartNode ) {
1067     _aReStartNode = NULL ;
1068     aReStartNode->SendEvent( _aReStartEvent ) ;
1069   }
1070   else {
1071     SendEvent( GraphExecutor::ExecuteEvent ) ;
1072   }
1073   return 1 ;
1074 }
1075
1076 int GraphExecutor::InNode::SuspendedReady_ResumeAction() {
1077   cdebug << pthread_self() << "/" << ThreadNo() << "SuspendedReady_ResumeAction "
1078          << Name() << endl;
1079 //  ResumeAction() ;
1080   _OutNode->PushEvent( this , GraphExecutor::ResumedReadyEvent ,
1081                        GraphExecutor::ResumedReadyState ) ; 
1082   return 1 ;
1083 }
1084
1085 int GraphExecutor::InNode::DataReady_KillAction() {
1086   _OutNode->PushEvent( this , GraphExecutor::KilledReadyEvent ,
1087                        GraphExecutor::KilledReadyState ) ;
1088   KillAction() ;
1089   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_KillAction " << Name()
1090          << " will pthread_exit()" << endl;
1091   return 1 ;
1092 }
1093
1094 int GraphExecutor::InNode::DataReady_StopAction() {
1095   _OutNode->PushEvent( this , GraphExecutor::StoppedReadyEvent ,
1096                        GraphExecutor::StoppedReadyState ) ; 
1097   StopAction() ;
1098   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_StopAction " << Name()
1099          << " will pthread_exit()" << endl;
1100   return 1 ;
1101 }
1102
1103 #include <CORBA.h>
1104
1105 int GraphExecutor::InNode::DataReady_ExecuteAction() {
1106   int i;
1107
1108 //  cdebug << pthread_self() << "/" << ThreadNo() << " --> DataReady_ExecuteAction "
1109 //         << Name() << endl;
1110   _OutNode->PushEvent( this , GraphExecutor::ExecuteEvent ,
1111                        GraphExecutor::ExecutingState ) ; 
1112
1113   RunningAction() ;
1114
1115   bool Err = false ;
1116
1117   SUPERV::GraphState PortState = SUPERV::ReadyState ;
1118   GraphExecutor::AutomatonState NewState = GraphExecutor::DataUndefState ;
1119   GraphExecutor::NodeEvent NewEvent = GraphExecutor::UndefinedEvent ;
1120
1121   int nInParams ;
1122   ServicesAnyData * InParametersList ;
1123   int nOutParams ;
1124   ServicesAnyData * OutParametersList ;
1125
1126   nInParams = GetNodeInPortsSize()  ;
1127   InParametersList = new ServicesAnyData[nInParams];
1128   InParametersSet( Err , nInParams , InParametersList ) ;
1129
1130   nOutParams = GetNodeOutPortsSize() ;
1131   OutParametersList = new ServicesAnyData[nOutParams];
1132   InOutParametersSet( nOutParams , OutParametersList ) ;
1133
1134   if ( !IsMacroNode() ) {
1135
1136     Engines::Container_var myContainer ;
1137     Engines::Component_var myObjComponent ;
1138     if ( !IsFactoryNode() ) {
1139 //      cdebug << ThreadNo() << "No Component : NO StartComponent & No Ping" << endl ;
1140       if ( IsComputingNode() ) {
1141         ObjInterface( true ) ;
1142         CORBA::Object_ptr obj ;
1143         InParametersList[0].Value >>= obj ;
1144         CORBA::Object_var objvar = CORBA::Object_var( obj ) ;
1145         myObjComponent = Engines::Component::_narrow( objvar ) ;
1146       }
1147       else {
1148       }
1149     }
1150     else if ( CORBA::is_nil( Component() ) ) {
1151 //      ostringstream astr ;
1152 //      astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name()
1153 //           << " : load of component " << ComponentName() << " in container "
1154 //           << Computer() ;
1155 //      _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
1156       Err = !_OutNode->Graph()->StartComponent( ThreadNo() , Computer() ,
1157                                                 my_strdup( ComponentName() ) ,
1158                                                 myContainer , myObjComponent ) ;
1159       ObjInterface( false ) ;
1160       SetContainer( myContainer ) ;
1161       SetComponent( myObjComponent ) ;
1162     }
1163     else {
1164       myContainer = Container() ;
1165       myObjComponent = Component() ;
1166 //      cdebug << ThreadNo() << "Component known : NO StartComponent & Ping"
1167 //             << endl ;
1168       try {
1169         myObjComponent->ping() ;
1170       }
1171       catch( ... ) {
1172         cdebug << "ping() catched" << endl ;
1173         Err = true ;
1174       }
1175     }
1176
1177     if ( Err || ControlState() == SUPERV::ToKillState ||
1178                 ControlState() == SUPERV::ToKillDoneState ||
1179                 ControlState() == SUPERV::ToStopState ) {
1180       cdebug << ThreadNo() << "StartComponent Error or ToKillState" << endl ;
1181       MESSAGE(pthread_self() << "Executor::InNode::DataReady_ExecuteAction of " << Name()
1182               << " ControlState " << Automaton()->ControlStateName( ControlState() )
1183               << " BEFORE execution ThreadNo " << ThreadNo() ) ;
1184       Err = true ;
1185     }
1186     else {
1187       if ( ControlState() == SUPERV::ToSuspendState ) {
1188         cdebug << ThreadNo() << "ToSuspendState before running." << endl ;
1189         MESSAGE(ThreadNo() << "ToSuspendState before running.") ;
1190       }
1191       if ( !Err ) {
1192 //        ostringstream astr ;
1193 //        astr << "Graph " << _OutNode->Graph()->Name() << " Run of Node " << Name() ;
1194 //        _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
1195         cdebug << ThreadNo() << " Run( '" << ServiceName() << "'" ;
1196         for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
1197           cdebug << " , " << InParametersList[ i ].Name << "[kind"
1198                  << InParametersList[ i ].Value.type()->kind() << "]" ;
1199         }
1200         for ( i = 0 ; i < (int ) ServiceOutParameter().length() ; i++ ) {
1201           cdebug << " , " << OutParametersList[ i ].Name << "[kind"
1202                  << OutParametersList[ i ].Value.type()->kind() << "]" ;
1203         }
1204         if ( IsOneOfInLineNodes() ) {
1205           cdebug << " , PyFuncName '" << InLineNode()->PyFuncName() << "' PyRunMethod "
1206                  << InLineNode()->PyRunMethod() << " length "
1207                  << (*InLineNode()->PythonFunction()).length() ;
1208         }
1209         cdebug << ")" << endl ;
1210
1211         if ( IsOneOfInLineNodes() ) {
1212           bool StsPyDynInvoke = true;
1213           _OutNode->PyThreadLock() ;
1214           SetPyCpuUsed() ;
1215           try {
1216 //            if ( IsInLineNode() && (*InLineNode()->PythonFunction()).length() &&
1217             bool ItIsaLoop = false ;
1218             bool CopyInOut = false ;
1219             if ( IsInLineNode() && /*InLineNode()->PyRunMethod() &&*/
1220                  strlen( InLineNode()->PyFuncName() ) ) {
1221               cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1222                      << InLineNode()->PyFuncName()
1223                      << "' IsInLineNode PyDynInvoke"  << endl ;
1224               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1225                                             InLineNode()->PyFuncName() ,
1226                                             &InParametersList[0] , ServiceInParameter().length() ,
1227                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1228               if ( !StsPyDynInvoke ) {
1229                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1230               }     }
1231             else if ( IsLoopNode() ) {
1232               ItIsaLoop = true ;
1233               bool CopyOutIn = false ;
1234 // Switch between Init() and Next()
1235 // if InLoop port is true and does not come from EndLoop ==> execute Init
1236 // if InLoop port is false or come from EndLoop ==> execute Next
1237 //              GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
1238 //              if ( GetNodeInLoop()->GetOutPort()->BoolValue() &&
1239               if ( _InitLoop ) {
1240                 if ( strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port = true ==> Init()
1241                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1242                          << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
1243                          << "' InitLoop " << LoopNode()->PyRunMethod() << endl ;
1244                   StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1245                                                 InLineNode()->PyFuncName() ,
1246                                                 &InParametersList[1] , ServiceInParameter().length() ,
1247                                                 &OutParametersList[1] , ServiceOutParameter().length() ) ;
1248                 if ( !StsPyDynInvoke ) {
1249                   RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1250                 }
1251                   CopyOutIn = true ;
1252                 }
1253                 else {
1254                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1255                          << " IsLoopNode NO PyDynInvoke Void PyFuncName InitLoop" << endl ;
1256                 }
1257                 cdebug << ThreadNo() << " !ObjInterface " << Name()
1258                        << " IsLoopNode _InitLoop Reset after Init() Python Function" << endl ;
1259                 _InitLoop = false ;
1260               }
1261               else if ( LoopNode()->PyNextMethod() &&
1262                         strlen( LoopNode()->PyNextName() ) ){ // InLoop Port = false ==> Next()
1263                 cdebug << ThreadNo() << " !ObjInterface " << Name()
1264                        << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
1265                        << "' " << LoopNode()->PyNextMethod() << endl ;
1266                 StsPyDynInvoke = PyDynInvoke( LoopNode()->PyNextMethod() ,
1267                                               LoopNode()->PyNextName() ,
1268                                               &InParametersList[1] , ServiceInParameter().length() ,
1269                                               &OutParametersList[1] , ServiceOutParameter().length() ) ;
1270                 if ( !StsPyDynInvoke ) {
1271                   RemovePyDynInvoke( LoopNode()->PyNextName() ) ;
1272                 }
1273                 CopyOutIn = true ;
1274               }
1275               else {
1276                 cdebug << ThreadNo() << " !ObjInterface " << Name()
1277                        << " IsLoopNode NO PyDynInvoke Void PyFuncName NextLoop" << endl ;
1278               }
1279               if ( StsPyDynInvoke ) {
1280                 if ( CopyOutIn ) {
1281                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1282                          << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
1283                          << "' Copy of " << ServiceInParameter().length()
1284                          << " OutParameters" << endl ;
1285                   int i ;
1286 // Start at 1 : Do not copy InLoop ( InLoop == true <==> Init ; InLoop == false <==> Next )
1287                   for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
1288                     InParametersList[i].Value = OutParametersList[i].Value ;
1289                     InParametersList[i].Name = OutParametersList[i].Name ;
1290 //#if 0
1291                     switch ( InParametersList[i].Value.type()->kind() ) {
1292                     case CORBA::tk_string :
1293                       char * t;
1294                       InParametersList[i].Value >>= t ;
1295                       cdebug << "ArgOut->In" << i << " : "
1296                              << InParametersList[i].Name.c_str()
1297                              << " Value(string) " << t << endl ;
1298                       break ;
1299                     case CORBA::tk_double :
1300                       double d;
1301                       InParametersList[i].Value >>= d;
1302                       cdebug << "ArgOut->In" << i << " : "
1303                              << InParametersList[i].Name.c_str()
1304                              << " Value(double) " << d << endl ;
1305                       break ;
1306                     case CORBA::tk_long :
1307                       long l;
1308                       InParametersList[i].Value >>= l;
1309                       cdebug << "ArgOut->In" << i << " : "
1310                              << InParametersList[i].Name.c_str()
1311                              << " Value(long) " << l << endl ;
1312                       break ;
1313                     case CORBA::tk_objref :
1314                       CORBA::Object_ptr obj ;
1315                       char * retstr ;
1316                       try {
1317                         InParametersList[i].Value >>= obj ;
1318                         retstr = ObjectToString( obj );
1319                         cdebug << "ArgOut->In" << i << " : "
1320                                << InParametersList[i].Name.c_str()
1321                                << " Value(object reference) " << retstr << endl ;
1322                        }
1323                       catch ( ... ) {
1324                         cdebug << "ArgOut->In" << i << " : "
1325                                << InParametersList[i].Name.c_str()
1326                                << " Value(object reference) Catched ERROR" << endl ;
1327                       }
1328                       break ;
1329                     default :
1330                       cdebug << "ArgOut->In" << i << " : "
1331                              << InParametersList[i].Name.c_str()
1332                              << " Value(other) ERROR" << endl ;
1333                     }
1334 //#endif
1335                   }
1336                 }
1337                 if ( LoopNode()->PyMoreMethod() && strlen( LoopNode()->PyMoreName() ) ) {
1338                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1339                          << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
1340                          << "' " << LoopNode()->PyMoreMethod() << endl ;
1341                   StsPyDynInvoke = PyDynInvoke( LoopNode()->PyMoreMethod() ,
1342                                                 LoopNode()->PyMoreName() ,
1343                                                 &InParametersList[1] , ServiceInParameter().length() ,
1344                                                 &OutParametersList[0] , ServiceOutParameter().length()+1 ) ;
1345                   if ( !StsPyDynInvoke ) {
1346                     RemovePyDynInvoke( LoopNode()->PyMoreName() ) ;
1347                   }
1348                 }
1349                 else {
1350                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1351                          << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
1352                          << "' No MoreMethod" << endl ;
1353                   CopyInOut = true ;
1354                 }
1355               }
1356               else {
1357                 Err = true ;
1358                 cdebug << ThreadNo() << " InLineNode " << Name() << " "
1359                        << InLineNode()->PyFuncName() << "/" << LoopNode()->PyNextName()
1360                        << " Python Dynamic Call Error"
1361                        << endl ;
1362               }
1363             }
1364             else if ( IsSwitchNode() && /*InLineNode()->PyRunMethod() &&*/
1365                       strlen( InLineNode()->PyFuncName() ) ) {
1366 //              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1367 //                     << InLineNode()->PyFuncName()
1368 //                     << "' IsSwitchNode PyDynInvoke"  << endl ;
1369               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1370                                             InLineNode()->PyFuncName() ,
1371                                             &InParametersList[0] , ServiceInParameter().length() ,
1372                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1373               if ( !StsPyDynInvoke ) {
1374                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1375               }
1376             }
1377 //            else if ( IsGOTONode() && (*GOTONode()->PythonFunction()).length() &&
1378             else if ( IsGOTONode() && /*InLineNode()->PyRunMethod() &&*/
1379                       strlen( InLineNode()->PyFuncName() ) ) {
1380 //              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1381 //                     << InLineNode()->PyFuncName()
1382 //                     << "' IsGOTONode PyDynInvoke"  << endl ;
1383               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1384                                             InLineNode()->PyFuncName() ,
1385                                             &InParametersList[0] , ServiceInParameter().length() ,
1386                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1387               if ( !StsPyDynInvoke ) {
1388                 RemovePyDynInvoke( GOTONode()->PyFuncName() ) ;
1389               }
1390             }
1391 //            else if ( IsEndSwitchNode() && (*InLineNode()->PythonFunction()).length() &&
1392             else if ( ( IsEndSwitchNode() ) &&
1393                       InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
1394 //              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1395 //                     << InLineNode()->PyFuncName()
1396 //                     << "' IsSwitchNode PyDynInvoke"  << endl ;
1397               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1398                                             InLineNode()->PyFuncName() ,
1399                                             &InParametersList[0] , ServiceInParameter().length() ,
1400                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1401               if ( !StsPyDynInvoke ) {
1402                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1403               }
1404             }
1405             else if ( ( IsEndLoopNode() ) &&
1406                       InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
1407               cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1408                      << InLineNode()->PyFuncName()
1409                      << "' IsSwitchNode PyDynInvoke"  << endl ;
1410               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1411                                             InLineNode()->PyFuncName() ,
1412                                             &InParametersList[0] , ServiceInParameter().length() + 1 ,
1413                                             &OutParametersList[0] , ServiceOutParameter().length() + 1 ) ;
1414               if ( !StsPyDynInvoke ) {
1415                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1416               }
1417             }
1418
1419 //            else if ( (*InLineNode()->PythonFunction()).length() == 0 ||
1420             if ( (!ItIsaLoop && ( InLineNode()->PyRunMethod() == NULL ||
1421                                   strlen( InLineNode()->PyFuncName() ) == 0 ) ) || CopyInOut ) {
1422 // This is a void Python Function : without code (No PyFuncName)
1423 //              cdebug << ThreadNo() << " !ObjInterface " << Name()
1424 //                     << " Copy of " << ServiceInParameter().length()
1425 //                     << " OutParameters" << endl ;
1426               int i ;
1427               int argout0 = 0 ;
1428               int argin0 = 0 ;
1429               if ( IsLoopNode() || IsEndLoopNode() ) {
1430                 argout0 = 1 ;
1431                 argin0 = 1 ; // after DoLoop
1432                 if ( IsLoopNode() ) { // More() is void
1433 //                  OutParametersList[0].Value = InParametersList[0].Value ; // DoLoop
1434                   cdebug << Name() << " Not Beginning of loop and non void EndLoop : DoLoop = EndLoop(DoLoop)"
1435                          << endl ;
1436                   GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
1437                   OutParametersList[0].Value = *anEndLoopNode->GetNodeOutLoop()->Value() ; // DoLoop = EndLoop(DoLoop)
1438                 }
1439               }
1440               for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
1441                 OutParametersList[argout0 + i].Value = InParametersList[argin0 + i].Value ;
1442 //#if 0
1443                 switch ( InParametersList[argin0 + i].Value.type()->kind() ) {
1444                 case CORBA::tk_string :
1445                   cdebug << "ArgOut->In" << argin0 + i << " : "
1446                          << InParametersList[argin0 + i].Name.c_str()
1447                          << " Value(string) "
1448                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1449                   break ;
1450                 case CORBA::tk_double :
1451                   cdebug << "ArgOut->In" << argin0 + i << " : "
1452                          << InParametersList[argin0 + i].Name.c_str()
1453                          << " Value(double) "
1454                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1455                   break ;
1456                 case CORBA::tk_long :
1457                   cdebug << "ArgOut->In" << argin0 + i << " : "
1458                          << InParametersList[argin0 + i].Name.c_str()
1459                          << " Value(long) "
1460                          << OutParametersList[argout0 + i ].Name.c_str() << endl ;
1461                   break ;
1462                 case CORBA::tk_objref :
1463                   cdebug << "ArgOut->In" << argin0 + i << " : "
1464                          << InParametersList[argin0 + i].Name.c_str()
1465                          << " Value(object reference) "
1466                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1467                   break ;
1468                 default :
1469                   cdebug << "ArgOut->In" << argin0 + i << " : "
1470                          << InParametersList[argin0 + i].Name.c_str()
1471                          << " Value(other) ERROR "
1472                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1473                 }
1474 //#endif
1475               }
1476             }
1477             if ( !StsPyDynInvoke ) {
1478               Err = true ;
1479               cdebug << ThreadNo() << " InLineNode " << Name()
1480                      << " Python Dynamic Call Error"
1481                      << endl ;
1482             }
1483           }
1484           catch( ... ) {
1485             Err = true ;
1486             cdebug << ThreadNo() << " InLineNode " << Name()
1487                    << " Python Dynamic Call Exception catched ERROR"
1488                    << endl ;
1489           }
1490           CpuUsed( true ) ;
1491           _OutNode->PyThreadUnLock() ;
1492         }
1493         else {
1494           try {
1495             try {
1496               cdebug << "DynInvoke -> Names " << _OutNode->Graph()->Name() << " " << Name() << endl ;
1497               DynInvoke( myObjComponent, "Names" ,
1498                          _OutNode->Graph()->Name() , Name() ) ;
1499             }
1500             catch( ... ) {
1501               cdebug << "DynInvoke Names catched ERROR" << endl ;
1502             }
1503 // for DataStreamNodes : call of SetProperties ===> environment variables in the component/container
1504             if ( ComputingNode()->HasDataStream() ) {
1505               try {
1506                 cdebug << "DynInvoke -> SetProperties " << _OutNode->Graph()->Name() << " " << Name() << endl ;
1507                 Engines::FieldsDict_var dict = new Engines::FieldsDict;
1508                 dict->length( 4 );
1509                 dict[ 0 ].key = CORBA::string_dup( "CAL_MACHINE");
1510                 // myContainer->getHostName() ne renvoit pas le nom complet (avec domaine).
1511                 //              dict[ 0 ].value <<= myContainer->getHostName() ;
1512                 char FullyQualifiedDomainName[256]="";
1513                 gethostname(FullyQualifiedDomainName,255);
1514                 dict[ 0 ].value <<=  FullyQualifiedDomainName ;
1515                 dict[ 1 ].key = CORBA::string_dup( "CAL_REPERTOIRE");
1516                 dict[ 1 ].value <<= "/tmp" ;
1517                 dict[ 2 ].key = CORBA::string_dup( "CAL_COUPLAGE");
1518                 stringstream ofst1 ;
1519                 ofst1 << ComputingNode()->SubStreamGraph() ;
1520                 string cpl = string( "/tmp/" ) + string( _OutNode->Graph()->Name() ) + string( "_" ) + 
1521                              ofst1.str() + string( ".cpl" );
1522                 dict[ 2 ].value <<= cpl.c_str() ;
1523                 dict[ 3 ].key = CORBA::string_dup( "SALOME_INSTANCE_NAME");
1524                 string uname = Name();
1525                 UpperCase( uname);
1526                 dict[ 3 ].value <<= uname.c_str() ;
1527
1528                 myObjComponent->setProperties( dict ) ;
1529               }
1530               catch( ... ) {
1531                 cdebug << "DynInvoke setProperties catched ERROR" << endl ;
1532                 Err = true;
1533               }
1534             }
1535             if ( !Err && IsComputingNode() ) {
1536               cdebug << ThreadNo() << " !ObjInterface " << Name()
1537                      << " IsComputingNode DynInvoke"  << endl ;
1538               cdebug << ServiceInParameter().length()-1 << " input parameters and "
1539                      << ServiceOutParameter().length() << " output parameters" << endl ;
1540               IsLoading( false ) ;
1541               DynInvoke( myObjComponent,
1542                          ServiceName() ,
1543                          &InParametersList[1] , ServiceInParameter().length()-1 ,
1544                          &OutParametersList[0] , ServiceOutParameter().length() ) ;
1545             }
1546             else if ( !Err && IsFactoryNode() ) {
1547               cdebug << ThreadNo() << " !ObjInterface " << Name()
1548                      << " IsFactoryNode DynInvoke"  << endl ;
1549               cdebug << ServiceInParameter().length() << " input parameters and "
1550                      << ServiceOutParameter().length() << " output parameters" << endl ;
1551               IsLoading( false ) ;
1552               DynInvoke( myObjComponent,
1553                          ServiceName() ,
1554                          &InParametersList[0] , ServiceInParameter().length() ,
1555                          &OutParametersList[0] , ServiceOutParameter().length() ) ;
1556             }
1557 //            cdebug << ThreadNo() << " Component::CpuUsed " << Name() << " "
1558 //                   << myObjComponent->CpuUsed_impl() << endl ;
1559           }
1560           catch( ... ) {
1561             Err = true ;
1562             cdebug << ThreadNo() << " !ObjInterface " << Name()
1563                    << " Node(Component) Dynamic Call Exception catched ERROR"
1564                    << endl ;
1565 //Reset of _ThreadId in the Container ...
1566             try {
1567               myObjComponent->Kill_impl() ;
1568             }
1569             catch( ... ) {
1570             }
1571           }
1572         }
1573       }
1574     }
1575   }
1576
1577 //  ostringstream astr ;
1578 //  astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name() << " is done : "
1579 //       << Automaton()->StateName( State() ) ;
1580 //  _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
1581
1582   if ( Err ) {
1583     
1584     // if exception or something else - IsLoading( false ) may not NOT has been called
1585     if ( IsLoading() )
1586       IsLoading( false );
1587
1588     if ( ControlState() == SUPERV::ToKillState ||
1589          ControlState() == SUPERV::ToKillDoneState ||
1590          ControlState() == SUPERV::ToStopState ) {
1591       PortState = SUPERV::ErrorState ;
1592       NewState = GraphExecutor::KilledState ;
1593       NewEvent = GraphExecutor::KillEvent ;
1594     }
1595     else {
1596       PortState = SUPERV::ErrorState ;
1597       NewState = GraphExecutor::ErroredState ;
1598       NewEvent = GraphExecutor::ErrorEvent ;
1599     }
1600   }
1601   else {
1602     PortState = SUPERV::ReadyState ;
1603     NewState = GraphExecutor::DataReadyState ;
1604     NewEvent = GraphExecutor::SuccessEvent ;
1605   }
1606
1607   if ( !IsMacroNode() ) {
1608     bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
1609     if ( !ErrOut ) {
1610       NewEvent = GraphExecutor::ErrorEvent ;
1611     }
1612     delete [] InParametersList ;
1613     delete [] OutParametersList ;
1614   }
1615           
1616   if ( !IsMacroNode() ) {              
1617     SendEvent( NewEvent ) ;
1618   }
1619   else {
1620     GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
1621     cdebug << ThreadNo() << " DataReady_ExecuteAction " << aMacroGraph << " "
1622            << aMacroGraph->Graph()->Name() << " ->DoneWait()"
1623            << " State " << aMacroGraph->State() << endl;
1624     aMacroGraph->DoneWait() ;
1625     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " State " << aMacroGraph->State() << endl;
1626     if ( aMacroGraph->State() == SUPERV::DoneState ) {
1627       PortState = SUPERV::ReadyState ;
1628       NewState = GraphExecutor::DataReadyState ;
1629       NewEvent = GraphExecutor::SuccessEvent ;
1630     }
1631     else {
1632       Err = true ;
1633       if ( ControlState() == SUPERV::ToKillState ||
1634            ControlState() == SUPERV::ToKillDoneState ||
1635            ControlState() == SUPERV::ToStopState ) {
1636         PortState = SUPERV::ErrorState ;
1637         NewState = GraphExecutor::KilledState ;
1638         NewEvent = GraphExecutor::KillEvent ;
1639       }
1640       else {
1641         PortState = SUPERV::ErrorState ;
1642         NewState = GraphExecutor::ErroredState ;
1643         NewEvent = GraphExecutor::ErrorEvent ;
1644       }
1645     }
1646     bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
1647     if ( !ErrOut ) {
1648       NewEvent = GraphExecutor::ErrorEvent ;
1649     }
1650     delete [] InParametersList ;
1651     delete [] OutParametersList ;
1652     SendEvent( NewEvent ) ;
1653   }
1654
1655 //  cdebug << ThreadNo() << " <-- DataReady_ExecuteAction " << Name() << endl;
1656   return 1 ;
1657 }
1658
1659 int GraphExecutor::InNode::Executing_SuspendAction() {
1660   _OutNode->PushEvent( this , GraphExecutor::SuspendedExecutingEvent ,
1661                        GraphExecutor::SuspendedExecutingState ) ; 
1662   cdebug << ThreadNo() << " Executing_SuspendAction " << Name() << endl;
1663   return 1 ;
1664 }
1665
1666 int GraphExecutor::InNode::SuspendedExecuting_ResumeAction() {
1667   cdebug << ThreadNo() << " SuspendedExecuting_ResumeAction " << Name() << endl;
1668   GraphExecutor::AutomatonState next_state ;
1669   next_state = Automaton()->NextState( State() , GraphExecutor::ExecutingEvent ) ;
1670   _OutNode->NewThread() ; // Only for Threads count
1671   _OutNode->PushEvent( this , GraphExecutor::ResumedExecutingEvent ,
1672                        next_state ) ; 
1673   State( next_state ) ;
1674   return 1 ;
1675 }
1676
1677 int GraphExecutor::InNode::Executing_KillAction() {
1678   cdebug << ThreadNo() << " Executing_KillAction " << Name() << " Thread " << ThreadNo()<< endl;
1679   int RetVal = 0 ;
1680   if ( pthread_self() == ThreadNo() ) {
1681     cdebug << "Executing_KillAction would pthread_canceled itself" << endl ;
1682     KillAction() ;
1683     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
1684                          GraphExecutor::KilledExecutingState ) ; 
1685     RetVal = 1 ;
1686   }
1687   else if ( pthread_cancel( ThreadNo() ) ) {
1688     perror("Executing_KillAction pthread_cancel error") ;
1689   }
1690   else {
1691     cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
1692            << " pthread_canceled" << endl ;
1693     KillAction() ;
1694     _OutNode->ExitThread( ThreadNo() ) ;
1695     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
1696                          GraphExecutor::KilledExecutingState ) ; 
1697   }
1698   return RetVal ;
1699 }
1700
1701 int GraphExecutor::InNode::Executing_StopAction() {
1702   cdebug << ThreadNo() << " Executing_StopAction " << Name() << " Thread " << ThreadNo() << endl;
1703   int RetVal = 0 ;
1704   if ( pthread_cancel( ThreadNo() ) ) {
1705     perror("Executing_KillAction pthread_cancel error") ;
1706   }
1707   else {
1708     cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
1709            << " pthread_canceled" << endl ;
1710     StopAction() ;
1711     _OutNode->ExitThread( ThreadNo() ) ;
1712     _OutNode->PushEvent( this , GraphExecutor::StoppedExecutingEvent ,
1713                          GraphExecutor::StoppedExecutingState ) ; 
1714   }
1715   return RetVal ;
1716 }
1717
1718 int GraphExecutor::InNode::Executing_SuccessAction() {
1719 //  cdebug << ThreadNo() << " --> Executing_SuccessAction " << Name() << endl;
1720   _OutNode->PushEvent( this , GraphExecutor::SuccessedExecutingEvent ,
1721                        GraphExecutor::SuccessedState ) ; 
1722   MESSAGE(pthread_self() << "Executor::InNode::Executing_SuccessAction of " << Name()
1723           << " ControlState " << Automaton()->ControlStateName( ControlState() )
1724           << " AFTER execution ThreadNo " << ThreadNo() ) ;
1725   SUPERV::ControlState aControl = ControlState() ;
1726   switch ( aControl ) {
1727   case SUPERV::VoidState : {
1728     SendEvent( SuccessEvent ) ;
1729     break ;
1730   }
1731   case SUPERV::ToSuspendState : {
1732     SendEvent( SuccessEvent ) ;
1733     break ;
1734   }
1735   case SUPERV::ToSuspendDoneState : {
1736     SendEvent( GraphExecutor::SuspendEvent ) ;
1737     return 1 ;
1738   }
1739   case SUPERV::ToKillState : {
1740     SendEvent( GraphExecutor::KillEvent ) ;
1741     return 1 ;
1742   }
1743   case SUPERV::ToKillDoneState : {
1744     SendEvent( GraphExecutor::KillEvent ) ;
1745     return 1 ;
1746   }
1747   case SUPERV::ToStopState : {
1748     SendEvent( GraphExecutor::StopEvent ) ;
1749     return 1 ;
1750   }
1751   default : {
1752     cdebug << ThreadNo()
1753            << " GraphExecutor::InNodeThreads::Executing_SuccessAction Error Undefined Control : "
1754            << aControl << endl ;
1755     return 0;
1756   }
1757   }
1758 //  cdebug << ThreadNo() << " <-- Executing_SuccessAction "  << Name() << endl;
1759   return 1 ;
1760 }
1761
1762 int GraphExecutor::InNode::Executing_ErrorAction() {
1763   cdebug << ThreadNo() << " --> Executing_ErrorAction " << Name() << endl;
1764   _OutNode->PushEvent( this , GraphExecutor::ErroredExecutingEvent ,
1765                        GraphExecutor::ErroredState ) ; 
1766
1767   SUPERV::ControlState aControl = ControlState() ;
1768   switch ( aControl ) {
1769   case SUPERV::VoidState : {
1770     SendEvent( ErrorEvent ) ;
1771     break ;
1772   }
1773   case SUPERV::ToSuspendState : {
1774     SendEvent( ErrorEvent ) ;
1775     break ;
1776   }
1777   case SUPERV::ToSuspendDoneState : {
1778     SendEvent( GraphExecutor::SuspendEvent ) ;
1779     return 1 ;
1780   }
1781   case SUPERV::ToKillState : {
1782     SendEvent( GraphExecutor::KillEvent ) ;
1783     return 1 ;
1784   }
1785   case SUPERV::ToKillDoneState : {
1786     SendEvent( GraphExecutor::KillEvent ) ;
1787     return 1 ;
1788   }
1789   case SUPERV::ToStopState : {
1790     SendEvent( GraphExecutor::StopEvent ) ;
1791     return 1 ;
1792   }
1793   default : {
1794     cdebug << ThreadNo()
1795            << " GraphExecutor::InNodeThreads::Executing_ErrorAction Error Undefined Control : "
1796            << aControl << endl ;
1797     return 0;
1798   }
1799   }
1800   cdebug << ThreadNo() << " <-- Executing_ErrorAction "  << Name() << endl;
1801   return 1 ;
1802 }
1803
1804 // Set SUPERV::WaitingState to all InPorts 
1805 void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
1806   int i ;
1807   int j ;
1808   bool docdebug = false ;
1809   State( GraphExecutor::DataWaitingState ) ;
1810   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1811     GraphBase::InPort * anInPort = GetChangeNodeInPort( i ) ;
1812     cdebug << "SetWaitingStates InPort " << Name() << "( " << anInPort->PortName() << " ) "
1813            << anInPort->PortStatus() << " " << anInPort->State() << endl ;
1814 // JR Debug 07.01.2005 : Close the Gates instead of open !!!
1815     if ( anInPort->IsGate() ) { // Loop : Close the doors
1816       GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1817       if ( anOutPort ) {
1818         CORBA::Any * anAny = new CORBA::Any() ;
1819 //        *anAny <<= (long ) 1 ;
1820         *anAny <<= (long ) 0 ;
1821         anOutPort->Value( anAny ) ;
1822         anInPort->State( SUPERV::WaitingState ) ;
1823       }
1824     }
1825     else if ( anInPort->State() != SUPERV::WaitingState &&
1826               !anInPort->IsDataConnected() ) {
1827       if ( !docdebug ) {
1828         cdebug << ThreadNo()
1829                << " --> GraphExecutor::InNodeThreads::SetWaitingStates " << Name() << endl;
1830         docdebug = true ;
1831       }
1832       if ( !anInPort->IsDataStream() ) {
1833         anInPort->State( SUPERV::WaitingState ) ;
1834       }
1835     }
1836     cdebug << "               --> " << Name() << "( " << anInPort->PortName() << " ) "
1837            << anInPort->PortStatus() << " " << anInPort->State() << endl ;
1838   }
1839   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1840     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
1841     for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
1842       if ( !( IsGOTONode() && anOutPort->IsGate() ) &&
1843            !( IsEndLoopNode() && ( anOutPort->IsGate() || anOutPort->IsLoop() ) ) &&
1844            !anOutPort->IsDataStream() &&
1845            !anOutPort->ChangeInPorts( j )->IsDataStream() &&
1846            !anOutPort->ChangeInPorts( j )->IsExternConnected() ) {
1847         cdebug << ThreadNo()
1848                << " InNodeThreads::SetWaitingStates OutPort "
1849                << Name() << "/" << anOutPort->ChangeInPorts( j )->NodeName() << "( "
1850                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " ) --> InPort "
1851                << anOutPort->ChangeInPorts( j )->NodeName() << "( "
1852                << anOutPort->ChangeInPorts( j )->PortName() << " "
1853                << anOutPort->ChangeInPorts( j )->PortStatus() << " )" << endl;
1854         GraphBase::ComputingNode * aToNode ;
1855         aToNode = _OutNode->Graph()->GetChangeGraphNode( anOutPort->ChangeInPorts( j )->NodeName() ) ;
1856 // JR 12.01.2005 : the OutPort linked to the InPort of a EndSwitchNode was changed so final
1857 //                 values of InPorts of EndSwitchNode may be wrong
1858         if ( !aToNode->IsEndSwitchNode() && 
1859              strcmp( anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() , Name() ) ) {
1860 // After EndLoopNode or GOTONode the Input Ports of LoopNode or LabelNode have their values from
1861 // EndLoopNode or GOTONode. But if there is several nested loops we should re-establish.
1862           cdebug << ThreadNo()
1863                  << " InNodeThreads::SetWaitingStates Node " << Name() << " " 
1864                  << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() << "( "
1865                  << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName() << " ) != "
1866                  << Name() << " : Restored to " << anOutPort->NodeName() << "( "
1867                  << anOutPort->PortName() << " )" << endl ;
1868           anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
1869         }
1870         GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) aToNode->GetInNode() ;
1871         if ( aNode != EndNode ) {
1872           aNode->SetWaitingStates( EndNode ) ;
1873         }
1874       }
1875     }
1876   }
1877 }
1878
1879 int GraphExecutor::InNode::Successed_SuccessAction() {
1880   cdebug << ThreadNo() << " --> Successed_SuccessAction "  << Name() << endl;
1881   int res = 1;
1882   int linkednodesnumber = LinkedNodesSize() ;
1883   GraphExecutor::InNode *firstzeroNode = NULL ;
1884   GraphExecutor::InNode *firsttoNode = NULL ;
1885   GraphExecutor::InNode *toNode ;
1886   int i ;
1887   int j ;
1888   list<GraphExecutor::InNode *> SomeDataNodes ;
1889
1890   DoneAction() ;
1891
1892   if ( IsMacroNode() ) {
1893       cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " LinkedNodes->SomeDataReady already done"
1894              << endl ;
1895     return 1;
1896   }
1897
1898   if ( IsGOTONode() ||
1899        ( IsEndLoopNode() && GetNodeInLoop()->GetOutPort()->BoolValue() ) ) {
1900     cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
1901            << " SetWaitingStates " << endl ;
1902     const GraphBase::OutPort * aGateOutPort ;
1903     if ( IsGOTONode() ) {
1904       aGateOutPort = GetNodeOutGate() ;
1905     }
1906     else {
1907       aGateOutPort = GetNodeOutLoop() ;
1908     }
1909     if ( aGateOutPort->InPortsSize() != 1 ) {
1910       cdebug << ThreadNo() << " Successed_SuccessAction aGateOutPort->InPortsSize "
1911              << aGateOutPort->InPortsSize() << " != 1 ERROR " << Name() << endl ;
1912     }
1913     GraphExecutor::InNode * aLabelNode = NULL ;
1914     for ( i = 0 ; i < aGateOutPort->InPortsSize() ; i++ ) {
1915       const GraphBase::InPort * anInPort = aGateOutPort->InPorts( i ) ;
1916       aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
1917       cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " will Loop to HeadNode "
1918              << aLabelNode->Name() << " from port " << anInPort->PortName() << endl ;
1919       aLabelNode->SetWaitingStates( this ) ;
1920 // JR 07.01.2005 Debug : Open the Gate of the coupledNode closed by SetWaitingStates
1921       GraphBase::OutPort * anOutPort = aLabelNode->GetChangeNodeInGate()->GetOutPort() ;
1922       if ( anOutPort ) {
1923         CORBA::Any * anAny = new CORBA::Any() ;
1924         *anAny <<= (long ) 1 ;
1925         anOutPort->Value( anAny ) ;
1926         aLabelNode->GetChangeNodeInGate()->State( SUPERV::ReadyState ) ;
1927       }
1928       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
1929         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
1930         if ( anInPort->GetOutPort() ) {
1931           cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
1932                  << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
1933                  << endl ;
1934         }
1935       }
1936       for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
1937         GraphBase::OutPort * aBusParamOutPort = GetChangeNodeOutPort( j ) ;
1938         if ( !aBusParamOutPort->IsGate() ) {
1939           GraphBase::InPort * aBusParamChangeInPort = NULL ;
1940           if ( aBusParamOutPort->IsLoop() ) {
1941 // For EndLoop do not copy EndLoop(DoLoop) in Loop(InLoop)
1942 //            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
1943           }
1944           else {
1945             aBusParamChangeInPort = aLabelNode->GetChangeInPort( aBusParamOutPort->PortName() ) ;
1946           }
1947           if ( aBusParamChangeInPort ) {
1948             aBusParamChangeInPort->ChangeOutPort( aBusParamOutPort ) ;
1949             cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " ChangeOutPort to HeadNode "
1950                    << aLabelNode->Name() << "(" << aBusParamChangeInPort->PortName() << ") from port "
1951                    << aBusParamOutPort->PortName() << endl ;
1952           }
1953         }
1954       }
1955     }
1956
1957     if ( aLabelNode && !aLabelNode->IsLockedDataWait() ) {
1958       res = aLabelNode->SendSomeDataReady( Name() ) ;
1959       if ( res ) {
1960         if ( firsttoNode == NULL &&
1961              aLabelNode->ThreadNo() == pthread_self() ) {
1962           firsttoNode = aLabelNode ;
1963           cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
1964                  << aLabelNode->Name() << endl ;
1965         }
1966         else if ( firstzeroNode == NULL &&
1967                   aLabelNode->ThreadNo() == 0 ) {
1968           firstzeroNode = aLabelNode ;
1969         }
1970         else {
1971           SomeDataNodes.push_back( aLabelNode ) ;
1972           cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
1973                  << aLabelNode->Name() << " " << SomeDataNodes.size() 
1974                  << endl ;
1975         }
1976       }
1977
1978       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
1979         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
1980         if ( anInPort->GetOutPort() ) {
1981           cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
1982                  << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
1983                  << endl ;
1984         }
1985       }
1986       const GraphBase::InPort * aGateInPort = aLabelNode->GetNodeInGate() ;
1987       if ( aGateInPort ) {
1988         if ( aGateInPort->GetOutPort() ) {
1989           aGateInPort->GetOutPort()->Value( aGateOutPort->Value() ) ;
1990         }
1991         if ( !aLabelNode->IsLockedDataWait() ) {
1992           res = aLabelNode->SendSomeDataReady( Name() ) ;
1993           if ( res ) {
1994             if ( firsttoNode == NULL &&
1995                  aLabelNode->ThreadNo() == pthread_self() ) {
1996               firsttoNode = aLabelNode ;
1997               cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
1998                      << aLabelNode->Name() << endl ;
1999             }
2000             else if ( firstzeroNode == NULL &&
2001                       aLabelNode->ThreadNo() == 0 ) {
2002               firstzeroNode = aLabelNode ;
2003             }
2004             else {
2005               SomeDataNodes.push_back( aLabelNode ) ;
2006               cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
2007                      << aLabelNode->Name() << " " << SomeDataNodes.size()
2008                      << endl ;
2009             }
2010           }
2011         }
2012       }
2013       else {
2014         cdebug << ThreadNo() << " ERROR in Successed_SuccessAction of " << Name()
2015                << " NO port " << aGateOutPort->PortName() << " in "
2016                << aLabelNode->Name() << endl;
2017       }
2018     }
2019   }
2020
2021   else {
2022     cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
2023            << " with " << LinkedNodesSize() << " linked nodes :" ;
2024     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2025       if ( LinkedNodes( i )->IsDataFlowNode() ) {
2026         linkednodesnumber -= 1 ;
2027       }
2028       cdebug << " " << LinkedNodes( i )->Name() ;
2029     }
2030     cdebug << endl;
2031     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2032       bool IgnoreForEndLoop = false ;
2033       GraphBase::ComputingNode * aComputingNode ;
2034       aComputingNode = (GraphBase::ComputingNode * ) LinkedNodes( i ) ;
2035       toNode = (GraphExecutor::InNode *) aComputingNode->GetInNode() ;
2036       cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
2037              << " [" << i << "] " << LinkedNodes( i )->Name() << " toNode " << toNode << " IgnoreForEndLoop "
2038              << IgnoreForEndLoop ;
2039       if ( toNode ) {
2040         cdebug << " " << toNode->Kind() << endl ;
2041       }
2042       if ( toNode && !toNode->IsDataFlowNode() ) {
2043         if ( IsComputingNode() && toNode->IsInLineNode() ) {
2044           GraphBase::InPort * toGateInPort = toNode->GetChangeNodeInGate() ;
2045           toGateInPort->State( SUPERV::ReadyState ) ;
2046           GraphBase::OutPort * GateOutPort = toGateInPort->GetOutPort() ;
2047           if ( GateOutPort ) {
2048             GateOutPort->PortStatus( DataConnected );
2049             GateOutPort->State( SUPERV::ReadyState ) ;
2050             GateOutPort->Done( true ) ;
2051           }
2052         }
2053       }
2054       if ( toNode && IsLoopNode() ) {
2055         GraphBase::OutPort * fromLoopOutPort = GetChangeNodeOutLoop() ;
2056         if ( !fromLoopOutPort->BoolValue() ) { // Ne pas faire la boucle
2057           if ( strcmp( toNode->Name() , CoupledNode()->Name() ) ) {
2058             IgnoreForEndLoop = true ;
2059           }
2060           else { // toNode is the EndLoopNode
2061             GraphBase::InPort * toLoopInPort ;
2062             toLoopInPort = toNode->GetChangeNodeInLoop() ;
2063             if ( toLoopInPort->State() != SUPERV::ReadyState ) {
2064               toLoopInPort->State( SUPERV::ReadyState ) ;
2065             }
2066           }
2067         }
2068       }
2069       else if ( toNode && IsSwitchNode() ) {
2070       }
2071       else if ( toNode && toNode->IsInLineNode() ) {
2072         int j ;
2073         for ( j = 0 ; j < toNode->GetNodeInPortsSize() ; j++ ) {
2074           toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
2075         }
2076       }
2077       if ( toNode && !IgnoreForEndLoop ) {
2078         if ( toNode && toNode->IsLoopNode() ) {
2079           GraphBase::InPort * toLoopInPort = toNode->GetChangeNodeInLoop() ;
2080           toLoopInPort->State( SUPERV::ReadyState ) ;
2081           GraphBase::OutPort * LoopOutPort = toLoopInPort->GetOutPort() ;
2082           LoopOutPort->PortStatus( DataConnected );
2083           LoopOutPort->State( SUPERV::ReadyState ) ;
2084           LoopOutPort->Done( true ) ;
2085           CORBA::Any * anAny = new CORBA::Any() ; // InitLoop
2086           *anAny <<= (long ) 1 ;
2087           LoopOutPort->Value( anAny ) ;
2088           int j ;
2089           for ( j = 0 ; j < toNode->GetNodeInPortsSize() ; j++ ) {
2090             toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
2091           }
2092         }
2093         cdebug << ThreadNo() << " Successed_SuccessAction " << toNode->Name() << "->SendSomeDataReady( "
2094                << Name() << " )" << endl ;
2095         res = toNode->SendSomeDataReady( Name() ) ;
2096         if ( res ) {
2097           if ( firsttoNode == NULL &&
2098                toNode->ThreadNo() == pthread_self() ) {
2099             firsttoNode = toNode ;
2100             cdebug << ThreadNo() << " Successed_SuccessAction firsttoNode "
2101                    << toNode->Name() << endl ;
2102           }
2103           else if ( firstzeroNode == NULL &&
2104                     toNode->ThreadNo() == 0 ) {
2105             firstzeroNode = toNode ;
2106           }
2107           else {
2108             SomeDataNodes.push_back( toNode ) ;
2109             cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
2110                    << toNode->Name() << " " << SomeDataNodes.size() << endl ;
2111           }
2112         }
2113       }
2114     }
2115   }
2116
2117   if ( firsttoNode == NULL && firstzeroNode ) {
2118     firsttoNode = firstzeroNode ;
2119     cdebug << ThreadNo()
2120            << " Successed_SuccessAction firsttoNode = firstzeroNode "
2121            << endl ;
2122   }
2123   else if ( firsttoNode && firstzeroNode ) {
2124     SomeDataNodes.push_back( firstzeroNode ) ;
2125     cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " push firstzeroNode "
2126            << firstzeroNode->Name() << " " << SomeDataNodes.size() << endl ;
2127   }
2128   else {
2129     cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " firsttoNode " << firsttoNode
2130            << " firstzeroNode " << firstzeroNode << endl ;
2131   }
2132
2133   while ( SomeDataNodes.size() ) {
2134     GraphExecutor::InNode *aNode = SomeDataNodes.front() ;
2135     SomeDataNodes.pop_front() ;
2136 //    cdebug << pthread_self() << "/" << ThreadNo()
2137 //           << " Successed_SuccessAction pop "
2138 //           << SomeDataNodes.size() << " " << aNode->Name() << endl ;
2139     if ( aNode->State() == GraphExecutor::DataReadyState ) {
2140       aNode->CreateNewThreadIf( true ) ;
2141       aNode->UnLockDataWait() ;
2142       res = aNode->DataUndef_AllDataReadyAction() ;
2143     }
2144     else {
2145 //      cdebug << pthread_self() << "/" << ThreadNo() << " ERROR "
2146 //             << aNode->Name() << " "
2147 //             << Automaton()->StateName( aNode->State() ) << endl ;
2148     }
2149   }
2150
2151   if ( firsttoNode ) {
2152 //    cdebug << pthread_self() << "/" << ThreadNo()
2153 //           << " Successed_SuccessAction start firsttoNode "
2154 //           << SomeDataNodes.size() << " " << firsttoNode->Name() << endl ;
2155     firsttoNode->CreateNewThreadIf( false ) ;
2156     firsttoNode->RewindStack( RewindStack() ) ;
2157     if ( firsttoNode->State() == GraphExecutor::SuccessedState ) {
2158 //      cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
2159 //             << " : " << firsttoNode->Name() << " "
2160 //             << Automaton()->StateName( firsttoNode->State() )
2161 //             << " --> DataWaitingState for Thread "
2162 //             << firsttoNode->ThreadNo() << endl ;
2163       firsttoNode->State( GraphExecutor::DataWaitingState ) ;
2164     }
2165 //    pthread_t OldT = firsttoNode->ThreadNo() ;
2166     firsttoNode->ThreadNo( pthread_self() ) ;
2167 // On continue avec le meme thread
2168 //    cdebug << pthread_self() << "/" << ThreadNo() << " firsttoNode "
2169 //           << firsttoNode->Name() << "Thread(" << OldT << "-->"
2170 //           << firsttoNode->ThreadNo() << ")" << endl ;
2171     ThreadNo( 0 ) ;
2172 //    cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
2173 //           << " for " << firsttoNode->Name()
2174 //           << " !firsttoNode->CreateNewThreadIf() "
2175 //           << !firsttoNode->CreateNewThreadIf()
2176 //           << " " << Automaton()->StateName( firsttoNode->State() ) ;
2177     if ( firsttoNode->State() == GraphExecutor::DataReadyState ) {
2178       cdebug << endl ;
2179       firsttoNode->UnLockDataWait() ;
2180       res = firsttoNode->DataUndef_AllDataReadyAction() ;
2181     }
2182     else {
2183       cdebug << " ERROR " << endl ;
2184     }
2185   }
2186   else {
2187 //    cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
2188 //           << " NO DataReady ==> ThreadNo( 0 ) firsttoNode == NULL LINKEDnodesnumber " << linkednodesnumber << endl ;
2189     ThreadNo( 0 ) ;
2190   }
2191
2192 //  if ( linkednodesnumber == 0 && firsttoNode == NULL ) {
2193 //    cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " LinkedNodesSize " << LinkedNodesSize()
2194 //           << " firsttoNode == NULL LINKEDnodesnumber " << linkednodesnumber << " CHECK" << endl ;
2195 //    _OutNode->CheckAllDone() ;
2196 //  }
2197
2198 //  cdebug << pthread_self() << "/" << ThreadNo()
2199 //         << " <-- Successed_SuccessAction " << Name() << " linkednodesnumber "
2200 //         << linkednodesnumber << endl;
2201   return 1 ;
2202 }
2203
2204 bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
2205   bool RetVal = false ;
2206   if ( IsDataFlowNode() ) {
2207     cdebug << ThreadNo() << "InNode::SendSomeDataReady ----> " << Name()
2208          << " send Result to graph " << Name() << endl;
2209   }
2210   else {
2211 //    cdebug << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
2212 //           << " send SomeDataReady to " << Name() << " "
2213 //           << Automaton()->StateName( State() ) 
2214 //           << " CreateNewThreadIf() " << CreateNewThreadIf()
2215 //           << " LockedDataWait " << IsLockedDataWait() << endl;
2216 #if 0
2217   //cout << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
2218          << " send SomeDataReady to " << Name() << " "
2219          << Automaton()->StateName( State() ) 
2220          << " CreateNewThreadIf() " << CreateNewThreadIf()
2221          << " LockedDataWait " << IsLockedDataWait() << endl;
2222 #endif
2223     if ( State() == GraphExecutor::SuccessedState ||
2224          State() == GraphExecutor::SuspendedSuccessedState ||
2225          State() == GraphExecutor::SuspendedSuccessedToReStartState ) {
2226 //      cdebug << ThreadNo() << " " << FromNodeName
2227 //             << " : " << Name() << " " << Automaton()->StateName( State() )
2228 //             << " --> DataWaitingState for Thread "
2229 //             << ThreadNo() << " " << endl ;
2230       State( GraphExecutor::DataWaitingState ) ;
2231     }
2232 // We begin that LoopNode if SendSomeDataReady does not come from the corresponding EndLoopNode
2233     if ( IsLoopNode() && strcmp( LoopNode()->CoupledNodeName() , FromNodeName ) ) {
2234       cdebug << ThreadNo() << "InNode::SendSomeDataReady " << Name() << " Set _InitLoop from "
2235              << FromNodeName << endl ;
2236       _InitLoop = true ;
2237     }
2238     LockDataWait() ;
2239     DataFromNode( FromNodeName ) ;
2240     RetVal = !SendEvent( GraphExecutor::SomeDataReadyEvent );
2241     if ( !RetVal ) {
2242       UnLockDataWait() ;
2243     }
2244   }
2245   return RetVal ;
2246 }
2247
2248 int GraphExecutor::InNode::Errored_ErrorAction() {
2249   cdebug << ThreadNo() << " Errored_ErrorAction " << Name()
2250          << " will pthread_exit" << endl;
2251   DoneAction() ;
2252   return 1 ;
2253 }
2254
2255 int GraphExecutor::InNode::Successed_SuspendAction() {
2256   cdebug << ThreadNo() << " Successed_SuspendAction -->Suspend " << Name()
2257          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
2258          << _OutNode->SuspendedThreads() << endl;
2259   _OutNode->PushEvent( this , GraphExecutor::SuspendedSuccessedEvent ,
2260                        GraphExecutor::SuspendedSuccessedState ) ; 
2261   DoneAction() ;
2262   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
2263   cdebug << ThreadNo() << " Successed_SuspendAction Resumed " << Name() ;
2264   if ( aReStartNode ) {
2265     _aReStartNode = NULL ;
2266     cdebug << " for " << aReStartNode->Name() << endl;
2267     aReStartNode->SendEvent( _aReStartEvent ) ;
2268   }
2269   else {
2270     cdebug << endl;
2271     SendEvent( GraphExecutor::ResumeEvent ) ;
2272   }
2273   return 1 ;
2274 }
2275
2276 int GraphExecutor::InNode::Errored_SuspendAction() {
2277   cdebug << ThreadNo() << " Errored_SuspendAction -->Suspend " << Name()
2278          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
2279          << _OutNode->SuspendedThreads() << endl;
2280   _OutNode->PushEvent( this , GraphExecutor::SuspendedErroredEvent ,
2281                        GraphExecutor::SuspendedErroredState ) ; 
2282   DoneAction() ;
2283   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
2284   cdebug << ThreadNo() << " Errored_SuspendAction Resumed " << Name()
2285          << endl;
2286   if ( aReStartNode ) {
2287     _aReStartNode = NULL ;
2288     aReStartNode->SendEvent( _aReStartEvent ) ;
2289   }
2290   else {
2291     SendEvent( GraphExecutor::ResumeEvent ) ;
2292   }
2293   return 1 ;
2294 }
2295
2296 int GraphExecutor::InNode::SuspendedSuccessed_ResumeAction() {
2297   cdebug << ThreadNo() << " SuspendedSuccessed_ResumeAction " << Name() << endl;
2298 //  ResumeAction() ;
2299   _OutNode->PushEvent( this , GraphExecutor::ResumedSuccessedEvent ,
2300                        GraphExecutor::ResumedSuccessedState ) ; 
2301   SendEvent( ResumedSuccessedEvent ) ;
2302   return 1 ;
2303 }
2304
2305 int GraphExecutor::InNode::SuspendedErrored_ResumeAction() {
2306   cdebug << ThreadNo() << " SuspendedErrored_ResumeAction " << Name() << endl;
2307 //  ResumeAction() ;
2308   _OutNode->PushEvent( this , GraphExecutor::ResumedErroredEvent ,
2309                        GraphExecutor::ResumedErroredState ) ; 
2310   SendEvent( ResumedErroredEvent ) ;
2311   return 1 ;
2312 }
2313
2314 int GraphExecutor::InNode::Successed_KillAction() {
2315   KillAction() ;
2316   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
2317                        GraphExecutor::KilledSuccessedState ) ; 
2318   cdebug << ThreadNo() << " Successed_KillAction " << Name() << endl;
2319   return 1 ;
2320 }
2321
2322 int GraphExecutor::InNode::Errored_KillAction() {
2323   KillAction() ;
2324   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
2325                        GraphExecutor::KilledErroredState ) ; 
2326   cdebug << ThreadNo() << " Errored_KillAction " << Name() << endl;
2327   return 1 ;
2328 }
2329
2330 int GraphExecutor::InNode::Successed_StopAction() {
2331   StopAction() ;
2332   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
2333                        GraphExecutor::StoppedSuccessedState ) ; 
2334   cdebug << ThreadNo() << " Successed_StopAction " << Name() << endl;
2335   return 1 ;
2336 }
2337
2338 int GraphExecutor::InNode::Errored_StopAction() {
2339   StopAction() ;
2340   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
2341                        GraphExecutor::StoppedErroredState ) ; 
2342   cdebug << ThreadNo() << " Errored_StopAction " << Name() << endl;
2343   return 1 ;
2344 }
2345
2346 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAction() {
2347   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction " << Name() << endl;
2348   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
2349                        GraphExecutor::ReStartedState ) ;
2350   int i ;
2351   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
2352     GetChangeNodeInPort( i )->State( SUPERV::ReadyState ) ;
2353   }
2354   SendEvent( ExecuteEvent ) ;
2355   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction "  << Name() << endl;
2356   return 1 ;
2357 }
2358
2359 int GraphExecutor::InNode::SuspendedErrored_ReStartAction() {
2360   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction " << Name() << endl;
2361   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
2362                        GraphExecutor::ReStartedState ) ; 
2363   int i ;
2364   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
2365     GetChangeNodeInPort( i )->State( SUPERV::ReadyState ) ;
2366   }
2367   SendEvent( ExecuteEvent ) ;
2368   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction "  << Name() << endl;
2369   return 1 ;
2370 }
2371
2372 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAndSuspendAction() {
2373   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction " << Name()
2374          << endl;
2375   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
2376                        GraphExecutor::ReStartedState ) ; 
2377   State( GraphExecutor::DataWaitingState ) ;
2378   if ( !Suspend() ) {
2379     cdebug << "InNode::Suspend() Node " << Name() << endl ;
2380     return false ;
2381   }
2382   else if ( SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
2383     cdebug << "InNode::SendEvent( SomeDataReadyEvent ) Node "
2384            << Name() << endl ;
2385     return false ;
2386   }
2387   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction "  << Name()
2388          << endl;
2389   return 1 ;
2390 }
2391
2392 int GraphExecutor::InNode::SuspendedErrored_ReStartAndSuspendAction() {
2393   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction " << Name()
2394          << endl;
2395   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
2396                        GraphExecutor::ReStartedState ) ; 
2397   State( GraphExecutor::DataWaitingState ) ;
2398   if ( !Suspend() ) {
2399     cdebug << "InNode::Suspend() Node " << Name() << endl ;
2400     return false ;
2401   }
2402   else if ( SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
2403     cdebug << "InNode::SendEvent( SomeDataReadyEvent ) Node "
2404            << Name() << endl ;
2405     return false ;
2406   }
2407   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction "  << Name()
2408          << endl;
2409   return 1 ;
2410 }
2411
2412 void GraphExecutor::InNode::InParametersSet( bool & Err ,
2413                                              int  nInParams ,
2414                                              ServicesAnyData * InParametersList ) {
2415   int i ;
2416   cdebug << ThreadNo() << " InParametersSet " << Name() << endl ;
2417   for ( i = 0 ; i < nInParams ; i++ ) {
2418     ServicesAnyData D = InParametersList[i];
2419     GraphBase::InPort * anInPort = GetChangeNodeInPort(i) ;
2420     GraphBase::OutPort * theOutPort = anInPort->GetOutPort() ;
2421     if ( anInPort->IsGate() && theOutPort == NULL ) {
2422       cdebug << ThreadNo() << " ArgIn" << i << " " << D.Name << " "
2423              << anInPort->GetServicesParameter().Parametertype
2424              << " is inactive. " << anInPort->Kind() << endl ;
2425     }
2426     else if ( anInPort->State() == SUPERV::ReadyState ) {
2427       if ( anInPort->IsGate() ) {
2428         CORBA::Any * anAny = new CORBA::Any() ;
2429         *anAny <<= (long ) 0 ;
2430         theOutPort->Value( anAny ) ;
2431       }
2432       if ( !anInPort->IsDataStream() &&
2433            !anInPort->IsDataConnected() ) {
2434         anInPort->State( SUPERV::WaitingState ) ;
2435       }
2436       D.Name = CORBA::string_dup( anInPort->GetServicesParameter().Parametername ) ;
2437       cdebug << ThreadNo() << " ArgIn" << i << " " << anInPort->Kind()
2438              << " " << anInPort->State() ;
2439       cdebug << "      " << D.Name << " " << anInPort->GetServicesParameter().Parametertype << " : " ;
2440       D.Value = *theOutPort->Value() ; // CORBA::Any
2441       string _Type = CORBA::string_dup( anInPort->GetServicesParameter().Parametertype ) ;
2442       const char * Type = _Type.c_str() ;
2443       switch ( D.Value.type()->kind() ) { // { string , long , double , objref }
2444       case CORBA::tk_string:
2445         char * t;
2446         D.Value >>= t;
2447         cdebug << t << " (string)" ;
2448         if ( !strcmp( Type , "string" ) ) {
2449         }
2450         else if ( !strcmp( Type , "boolean" ) ) {
2451           bool b ;
2452           long d ;
2453           sscanf( t , "%ld" , &d ) ;
2454           b = (bool ) d ;
2455           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2456 //          theOutPort->Value( D.Value ) ;
2457         }
2458         else if ( !strcmp( Type , "char" ) ) {
2459           unsigned char c ;
2460           long d ;
2461           sscanf( t , "%ld" , &d ) ;
2462           c = (short ) d ;
2463           D.Value <<=  (CORBA::Any::from_char ) c ;
2464           cdebug << "string '" << t << "' --> " << d << " --> char " << c ;
2465 //          theOutPort->Value( D.Value ) ;
2466         }
2467         else if ( !strcmp( Type , "short" ) ) {
2468           short s ;
2469           long d ;
2470           sscanf( t , "%ld" , &d ) ;
2471           s = (short ) d ;
2472           D.Value <<=  s ;
2473           cdebug << "string '" << t << "' --> " << d << " --> short " << s ;
2474 //          theOutPort->Value( D.Value ) ;
2475         }
2476         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2477           long l ;
2478           sscanf( t , "%ld" , &l ) ;
2479           D.Value <<=  l ;
2480           cdebug << "string '" << t << " --> long " << l ;
2481 //          theOutPort->Value( D.Value ) ;
2482         }
2483         else if ( !strcmp( Type , "float" ) ) {
2484           double d ;
2485           sscanf( t , "%lf" , &d ) ;
2486           float f = d ;
2487           D.Value <<= f ;
2488           cdebug << "string '" << t << "' --> " << setw(25) << setprecision(18) << d << " --> float " << " = "
2489                  << setw(25) << setprecision(18) << f ;
2490 //          theOutPort->Value( D.Value ) ;
2491         }
2492         else if ( !strcmp( Type , "double" ) ) {
2493           double d ;
2494           sscanf( t , "%lf" , &d ) ;
2495           D.Value <<= d ;
2496           cdebug << "string '" << t << " --> double " << setw(25) << setprecision(18) << d ;
2497 //          theOutPort->Value( D.Value ) ;
2498         }
2499 //        else if ( !strcmp( Type , "objref" ) ) {
2500         else { // Default
2501           CORBA::Object_ptr ObjRef ;
2502           try {
2503             ObjRef = StringToObject( t ) ;
2504             D.Value <<= ObjRef ;
2505           }
2506           catch( ... ) {
2507             D.Value <<= CORBA::Object::_nil() ;
2508           }
2509 //          theOutPort->Value( D.Value ) ;
2510         }
2511 //        else {
2512 //          cdebug << " (other ERROR)" << endl ;
2513 //        }
2514         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2515         break;
2516       case CORBA::tk_long:
2517         long l;
2518         D.Value >>= l;
2519         cdebug << l << " (long)" << endl ;
2520         if ( !strcmp( Type , "string" ) ) {
2521           char t[40] ;
2522           sprintf( t , "%ld" , l ) ;
2523           D.Value <<= t ;
2524 //          theOutPort->Value( D.Value ) ;
2525         }
2526         else if ( !strcmp( Type , "boolean" ) ) {
2527           bool b ;
2528           b = (bool ) l ;
2529           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2530 //          theOutPort->Value( D.Value ) ;
2531         }
2532         else if ( !strcmp( Type , "char" ) ) {
2533           unsigned char c ;
2534           c = (unsigned char ) l ;
2535           D.Value <<=  (CORBA::Any::from_char ) c ;
2536 //          theOutPort->Value( D.Value ) ;
2537         }
2538         else if ( !strcmp( Type , "short" ) ) {
2539           short s ;
2540           s = (short ) l ;
2541           D.Value <<=  s ;
2542 //          theOutPort->Value( D.Value ) ;
2543         }
2544         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2545         }
2546         else if ( !strcmp( Type , "float" ) ) {
2547           float f ;
2548           f = (float ) l ;
2549           D.Value <<= f ;
2550 //          theOutPort->Value( D.Value ) ;
2551         }
2552         else if ( !strcmp( Type , "double" ) ) {
2553           double d ;
2554           d = (double ) l ;
2555           D.Value <<= d ;
2556 //          theOutPort->Value( D.Value ) ;
2557         }
2558 //        else if ( !strcmp( Type , "objref" ) ) {
2559         else { // Default
2560           D.Value <<= CORBA::Object::_nil() ;
2561 //          theOutPort->Value( D.Value ) ;
2562         }
2563 //        else {
2564 //          cdebug << " (other ERROR)" << endl ;
2565 //        }
2566         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2567         break;
2568       case CORBA::tk_double:
2569         double d;
2570         D.Value >>= d;
2571         cdebug << d << " (double)" << endl ;
2572         if ( !strcmp( Type , "string" ) ) {
2573           char t[40] ;
2574           sprintf( t , "%lf" , d ) ;
2575           D.Value <<= t ;
2576 //          theOutPort->Value( D.Value ) ;
2577         }
2578         else if ( !strcmp( Type , "boolean" ) ) {
2579           bool b ;
2580           b = (bool ) d ;
2581           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2582 //          theOutPort->Value( D.Value ) ;
2583         }
2584         else if ( !strcmp( Type , "char" ) ) {
2585           unsigned char c ;
2586           c = (unsigned char ) d ;
2587           D.Value <<=  (CORBA::Any::from_char ) c ;
2588 //          theOutPort->Value( D.Value ) ;
2589         }
2590         else if ( !strcmp( Type , "short" ) ) {
2591           short s ;
2592           s = (short ) d ;
2593           D.Value <<=  s ;
2594 //          theOutPort->Value( D.Value ) ;
2595         }
2596         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2597           long l ;
2598           l = (long ) d ;
2599           D.Value <<= l ;
2600 //          theOutPort->Value( D.Value ) ;
2601         }
2602         else if ( !strcmp( Type , "float" ) ) {
2603           float f ;
2604           f = (float ) d ;
2605           D.Value <<= f ;
2606 //          theOutPort->Value( D.Value ) ;
2607         }
2608         else if ( !strcmp( Type , "double" ) ) {
2609         }
2610 //        else if ( !strcmp( Type , "objref" ) ) {
2611         else { // Default
2612           D.Value <<= CORBA::Object::_nil() ;
2613 //          theOutPort->Value( D.Value ) ;
2614         }
2615 //        else {
2616 //          cdebug << " (other ERROR)" << endl ;
2617 //        }
2618         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2619         break;
2620       case CORBA::tk_objref:
2621         if ( !strcmp( Type , "string" ) ) {
2622           CORBA::Object_ptr ObjRef ;
2623           char * retstr ;
2624           try {
2625             D.Value >>= ObjRef ;
2626             retstr = ObjectToString( ObjRef ) ;
2627             D.Value <<= retstr ;
2628 //            theOutPort->Value( D.Value ) ;
2629           }
2630           catch( ... ) {
2631             if ( i != 0 ) {
2632               Err = true ;
2633             }
2634             cdebug << "ToString( object ) Catched ERROR" << endl ;
2635           }
2636         }
2637         else if ( !strcmp( Type , "boolean" ) ) {
2638           bool b = 0 ;
2639           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2640 //          theOutPort->Value( D.Value ) ;
2641         }
2642         else if ( !strcmp( Type , "char" ) ) {
2643           unsigned char c = 0 ;
2644           D.Value <<=  (CORBA::Any::from_char ) c ;
2645 //          theOutPort->Value( D.Value ) ;
2646         }
2647         else if ( !strcmp( Type , "short" ) ) {
2648           short s = 0 ;
2649           D.Value <<=  s ;
2650 //          theOutPort->Value( D.Value ) ;
2651         }
2652         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2653           long l = 0 ;
2654           D.Value <<= l ;
2655 //          theOutPort->Value( D.Value ) ;
2656         }
2657         else if ( !strcmp( Type , "float" ) ) {
2658           float f = 0 ;
2659           D.Value <<= f ;
2660 //          theOutPort->Value( D.Value ) ;
2661         }
2662         else if ( !strcmp( Type , "double" ) ) {
2663           double d = 0 ;
2664           D.Value <<= d ;
2665 //          theOutPort->Value( D.Value ) ;
2666         }
2667 //        else if ( !strcmp( Type , "objref" ) ) {
2668         else { // Default
2669           CORBA::Object_ptr obj ;
2670           char * retstr ;
2671           try {
2672             D.Value >>= obj ;
2673             retstr = ObjectToString( obj ) ;
2674             cdebug << retstr << endl ;
2675           }
2676           catch( ... ) {
2677             if ( i != 0 ) {
2678               Err = true ;
2679             }
2680             cdebug << "ToString( object ) Catched ERROR" << endl ;
2681           }
2682         }
2683 //        else {
2684 //          cdebug << " (other ERROR)" << endl ;
2685 //        }
2686         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2687         break;
2688       default:
2689         cdebug << " (other ERROR) " << D.Value.type()->kind() << endl ;
2690       }
2691     }
2692     else {
2693       cdebug << ThreadNo() << " In" << i << " : wrong state ERROR State "
2694              << anInPort->State() << " NameState "
2695              << Automaton()->StateName( anInPort->State() ) << " PortName "
2696              << anInPort->PortName() << " Parametername "
2697              << anInPort->GetServicesParameter().Parametername << endl ;
2698       Err = true ;
2699     }
2700     InParametersList[i] = D ;
2701   }
2702 }
2703
2704 void GraphExecutor::InNode::InOutParametersSet( int nOutParams ,
2705                                                 ServicesAnyData * OutParametersList ) {
2706   int i ;
2707   for ( i = 0 ; i < nOutParams ; i++ ) {
2708     ServicesAnyData D = OutParametersList[i] ;
2709
2710     D.Name = GetChangeNodeOutPort(i)->GetServicesParameter().Parametername;
2711     string _Type = CORBA::string_dup(GetChangeNodeOutPort(i)->GetServicesParameter().Parametertype) ;
2712     const char * Type = _Type.c_str() ;
2713     bool OutDone = GetChangeNodeOutPort(i)->Done() ;
2714     cdebug << ThreadNo() << " ArgOut" << i << " " << D.Name << " Done("
2715            << OutDone << ") " << Type << " : " << endl ;
2716     if ( !strcmp( Type , "string" ) ) {
2717       D.Value <<= (char *) NULL ;
2718     }
2719     else if ( !strcmp( Type , "boolean" ) ) {
2720       bool b = 0 ;
2721       D.Value <<=  (CORBA::Any::from_boolean ) b ;
2722     }
2723     else if ( !strcmp( Type , "char" ) ) {
2724       unsigned char c = 0 ;
2725       D.Value <<=  (CORBA::Any::from_char ) c ;
2726     }
2727     else if ( !strcmp( Type , "short" ) ) {
2728       short s = 0 ;
2729       D.Value <<=  s ;
2730     }
2731     else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2732       D.Value <<= (long ) 0 ;
2733     }
2734     else if ( !strcmp( Type , "float" ) ) {
2735       float f = 0 ;
2736       D.Value <<= f ;
2737     }
2738     else if ( !strcmp( Type , "double" ) ) {
2739       double d = 0 ;
2740       D.Value <<= d ;
2741     }
2742     else {
2743       D.Value <<= CORBA::Object::_nil() ;
2744     }
2745 //#if 0
2746     switch (D.Value.type()->kind()) { // { string , long , double , objref }
2747     case CORBA::tk_string:
2748       char * t;
2749       D.Value >>= t;
2750       cdebug << ThreadNo() << " " << t << "(string)" << endl ;
2751       break;
2752     case CORBA::tk_boolean:
2753       bool b ;
2754       D.Value >>= (CORBA::Any::to_boolean ) b;
2755       cdebug << ThreadNo() << " " << b << "(boolean)" << endl ;
2756       break;
2757     case CORBA::tk_char:
2758       unsigned char c ;
2759       D.Value >>= (CORBA::Any::to_char ) c;
2760       cdebug << ThreadNo() << " " << c << "(char)" << endl ;
2761       break;
2762     case CORBA::tk_short:
2763       short s;
2764       D.Value >>= s;
2765       cdebug << ThreadNo() << " " << s << "(short)" << endl ;
2766       break;
2767     case CORBA::tk_long:
2768       long l;
2769       D.Value >>= l;
2770       cdebug << ThreadNo() << " " << l << "(long)" << endl ;
2771       break;
2772     case CORBA::tk_float:
2773       float f;
2774       D.Value >>= f;
2775       cdebug << ThreadNo() << " " << f << "(float)" << endl ;
2776       break;
2777     case CORBA::tk_double:
2778       double d;
2779       D.Value >>= d;
2780       cdebug << ThreadNo() << " " << d << "(double)" << endl ;
2781       break;
2782     case CORBA::tk_objref:
2783       try {
2784         CORBA::Object_ptr obj ;
2785         char * retstr ;
2786         D.Value >>= obj ;
2787         retstr = ObjectToString( obj ) ;
2788         cdebug << ThreadNo() << retstr << endl ;
2789       }
2790       catch( ... ) {
2791         cdebug << "ToString( object ) Catched ERROR" << endl ;
2792       }
2793       break;
2794     default:
2795       cdebug << ThreadNo() << " " << "(other ERROR)" << endl ;
2796     }
2797 //#endif
2798     OutParametersList[i] = D ;
2799   }
2800 }
2801
2802 bool GraphExecutor::InNode::OutParametersSet( bool Err ,
2803                                               SUPERV::GraphState NewState ,
2804                                               int nOutParams ,
2805                                               ServicesAnyData * OutParametersList ) {
2806   bool RetVal = true ;
2807   int i ;
2808   GraphBase::OutPort * aGateOutPort = NULL ;
2809   bool OrSwitch = false ;
2810   cdebug << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState " << NewState << endl ;
2811 //  cout << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState " << NewState << endl ;
2812   if ( nOutParams && !IsMacroNode() ) {
2813     GraphBase::OutPort * anOutPort ;
2814     for ( i = 0 ; i < nOutParams ; i++ ) {
2815       anOutPort = GetChangeNodeOutPort(i) ;
2816       if ( Err ) {
2817         anOutPort->State( NewState ) ;
2818         anOutPort->Done( true ) ;
2819       }
2820       else {
2821         cdebug << ThreadNo() << " " << "Out" << i << " " << Name() << " "
2822                << anOutPort->PortName() << " " << anOutPort->Kind() ;
2823         ServicesAnyData D = OutParametersList[i] ;
2824         switch (D.Value.type()->kind()) { // { string , long , double , objref }
2825         case CORBA::tk_string: {
2826           char * t;
2827           D.Value >>= t;
2828           cdebug << ThreadNo() << " " << t << "(string)" << endl ;
2829           break;
2830         }
2831         case CORBA::tk_boolean: {
2832           bool b ;
2833           D.Value >>= (CORBA::Any::to_boolean ) b;
2834           long l = (long ) b ;
2835           D.Value <<= l ;
2836           cdebug << ThreadNo() << " " << b << "(boolean)" << endl ;
2837           break;
2838         }
2839         case CORBA::tk_char: {
2840           unsigned char c ;
2841           D.Value >>= (CORBA::Any::to_char ) c;
2842           long l = (long ) c ;
2843           D.Value <<= l ;
2844           cdebug << ThreadNo() << " " << c << "(char)" << endl ;
2845           break;
2846         }
2847         case CORBA::tk_short: {
2848           short s;
2849           D.Value >>= s;
2850           long l = (long ) s ;
2851           D.Value <<= l ;
2852           cdebug << ThreadNo() << " " << s << "(short)" << endl ;
2853           break;
2854         }
2855         case CORBA::tk_long: {
2856           long l;
2857           D.Value >>= l;
2858           cdebug << ThreadNo() << " " << l << "(long)" << endl ;
2859           break;
2860         }
2861         case CORBA::tk_float: {
2862           float f;
2863           D.Value >>= f;
2864           double d = (double ) f ;
2865           D.Value <<= d ;
2866           cdebug << ThreadNo() << " " << f << "(float)" << endl ;
2867           break;
2868         }
2869         case CORBA::tk_double: {
2870           double d;
2871           D.Value >>= d;
2872           cdebug << ThreadNo() << " " << d << "(double)" << endl ;
2873           break;
2874         }
2875         case CORBA::tk_objref: {
2876           try {
2877             CORBA::Object_ptr obj ;
2878             char * retstr ;
2879             D.Value >>= obj ;
2880             retstr = ObjectToString( obj ) ;
2881             cdebug << ThreadNo() << retstr << endl ;
2882           }
2883           catch( ... ) {
2884             cdebug << "ToString( object ) Catched ERROR" << endl ;
2885           }
2886           break;
2887         }
2888         default: {
2889           cdebug << ThreadNo() << " " << "(other ERROR)" << endl ;
2890         }
2891         }
2892         OutParametersList[i] = D ;
2893         if ( !anOutPort->IsDataStream() ) {
2894           if ( anOutPort->IsGate() ) {
2895             aGateOutPort = anOutPort ;
2896             cdebug << " Gate " ;
2897             long l = 1;
2898             OutParametersList[i].Value <<= l;
2899             anOutPort->Value( OutParametersList[i].Value );
2900           }
2901           else if ( anOutPort->IsLoop() ) {
2902             cdebug << " Loop " ;
2903             anOutPort->Value( OutParametersList[i].Value );
2904 // InLoop Port of EndLoopNode is ready :
2905             anOutPort->ChangeInPorts(0)->State( SUPERV::ReadyState ) ;
2906           }
2907           else if ( anOutPort->IsSwitch() ) {
2908             cdebug << " Switch " ;
2909             anOutPort->Value( OutParametersList[i].Value );
2910             if ( anOutPort->InPortsSize() && anOutPort->ChangeInPorts( 0 )->IsGate() ) {
2911               if ( OrSwitch && anOutPort->BoolValue() ) {
2912                 cdebug << "GraphExecutor::InNodeThreads::OutParameters more than one switch is true WARNING"
2913                        << endl ;
2914               }
2915               else {
2916                 OrSwitch = OrSwitch | anOutPort->BoolValue() ;
2917               }
2918             }
2919             cdebug << "OrSwitch " << OrSwitch ;
2920           }
2921           else {
2922             cdebug << " Param " ;
2923             anOutPort->Value( OutParametersList[i].Value );
2924           }
2925           anOutPort->State( NewState ) ;
2926           anOutPort->Done( true ) ;
2927         }
2928         int j ;
2929         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
2930           bool fromGOTO = false ;
2931           const char * ToNodeName = anOutPort->ChangeInPorts( j )->NodeName() ;
2932           if ( !strcmp( ToNodeName , _OutNode->Graph()->Name() ) && _OutNode->Graph()->GraphMacroLevel() != 0 ) {
2933             cdebug << "OutParametersSet ToNodeName " << _OutNode->Graph()->Name() << " CoupledNode "
2934                    << _OutNode->Graph()->CoupledNodeName() << _OutNode->Graph()->CoupledNode()
2935                    << endl ;
2936             cdebug << " GraphExecutor " << _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor() << endl ;
2937             _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor()->OutputOfAny( _OutNode->Graph()->CoupledNodeName() ,
2938                                                                             anOutPort->ChangeInPorts( j )->PortName() ,
2939                                                                             *anOutPort->Value() ) ;
2940           }
2941           else {
2942             GraphBase::ComputingNode * ToNode = _OutNode->Graph()->GetChangeGraphNode( ToNodeName ) ;
2943             if ( ToNode ) {
2944 //              cout << "OutParametersSet ToNodeName " << ToNodeName << endl ;
2945               cdebug << "OutParametersSet ToNodeName " << ToNodeName << " " << ToNode->Name() << endl ;
2946               GraphBase::OutPort * aGOTOPort = ToNode->GetChangeNodeInGate()->GetOutPort() ;
2947               if ( aGOTOPort ) {
2948                 fromGOTO = aGOTOPort->IsGOTO() ;
2949               }
2950               if ( anOutPort->ChangeInPorts( j )->IsEndSwitch() || fromGOTO ) {
2951                 cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
2952                        << anOutPort->ChangeInPorts( j )->PortName() << ","
2953                        << anOutPort->ChangeInPorts( j )->Kind() << ") WILL BE changed from "
2954                        << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
2955                        << "("
2956                        << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
2957                        << ") to " << anOutPort->NodeName() << "("
2958                        << anOutPort->PortName() << ")" << endl ;
2959                 anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
2960               }
2961               else {
2962                 cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
2963                        << anOutPort->ChangeInPorts( j )->PortName() << ","
2964                        << anOutPort->ChangeInPorts( j )->Kind() << ") NOT changed from "
2965                        << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
2966                        << "("
2967                        << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
2968                        << ") to " << anOutPort->NodeName() << "("
2969                        << anOutPort->PortName() << ")" << endl ;
2970               }
2971             }
2972           }
2973         }
2974 //#if 0
2975         switch (anOutPort->Value()->type()->kind()) {
2976         case CORBA::tk_string:
2977           char * t;
2978           (*anOutPort->Value()) >>= t;
2979           cdebug << ThreadNo() << " Out" << i << " : " << t << "(string)" << endl ;
2980           break;
2981         case CORBA::tk_boolean:
2982           bool b ;
2983           (*anOutPort->Value()) >>= (CORBA::Any::to_boolean ) b;
2984           cdebug << ThreadNo() << " Out" << i << " : " << b << "(boolean)" << endl ;
2985           break;
2986         case CORBA::tk_char:
2987           unsigned char c ;
2988           (*anOutPort->Value()) >>= (CORBA::Any::to_char ) c;
2989           cdebug << ThreadNo() << " Out" << i << " : " << c << "(char)" << endl ;
2990           break;
2991         case CORBA::tk_short:
2992           short s;
2993           (*anOutPort->Value()) >>= s;
2994           cdebug << ThreadNo() << " Out" << i << " : " << s << "(short)" << endl ;
2995           break;
2996         case CORBA::tk_long:
2997           long l;
2998           (*anOutPort->Value()) >>= l;
2999           cdebug << ThreadNo() << " Out" << i << " : " << l << "(long)" << endl ;
3000           break;
3001         case CORBA::tk_float:
3002           float f;
3003           (*anOutPort->Value()) >>= f;
3004           cdebug << ThreadNo() << " Out" << i << " : " << f << "(float)" << endl ;
3005           break;
3006         case CORBA::tk_double:
3007           double d;
3008           (*anOutPort->Value()) >>= d;
3009           cdebug << ThreadNo() << " Out" << i << " : " << d << "(double)" << endl ;
3010           break;
3011         case CORBA::tk_objref:
3012           CORBA::Object_ptr obj ;
3013           char * retstr ;
3014           try {
3015             (*anOutPort->Value()) >>= obj ;
3016             retstr = ObjectToString( obj );
3017             cdebug << ThreadNo() << " Out" << i << " : " << "ToString( object ) "
3018                    << retstr << endl ;
3019           }
3020           catch ( ... ) {
3021             cdebug << ThreadNo() << " Out" << i << " : " << "ToString( object ) "
3022                    << "Catched ERROR" << endl ;
3023           }
3024           break;
3025         default:
3026           cdebug << ThreadNo() << " Out" << i << " : " << "(other ERROR)" << endl ;
3027           RetVal = false ;
3028         }
3029 //#endif
3030       }
3031     }
3032     if ( aGateOutPort && IsSwitchNode() ) {
3033       if ( OrSwitch ) {
3034 //        cdebug << ThreadNo() << " " << "Out0 " << Name() << " Close of "
3035 //               << aGateOutPort->PortName() << " " << aGateOutPort->Kind() ;
3036         long l = 0;
3037         OutParametersList[0].Value <<= l ;
3038         aGateOutPort->Value( OutParametersList[0].Value ) ;
3039       }
3040       else {
3041 //        cdebug << ThreadNo() << " " << "Out0 " << Name() << " Open of "
3042 //               << aGateOutPort->PortName() << " " << aGateOutPort->Kind() ;
3043         long l = 1;
3044         OutParametersList[0].Value <<= l ;
3045         aGateOutPort->Value( OutParametersList[0].Value ) ;
3046         int i ;
3047         for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
3048           GraphBase::InPort * anInPort ;
3049           anInPort = CoupledNode()->GetChangeInPort( GetNodeOutPort( i )->PortName() ) ;
3050           if ( anInPort ) {
3051             anInPort->ChangeOutPort( GetChangeNodeOutPort( i ) ) ;
3052           }
3053         }
3054       }
3055     }
3056   }
3057   return RetVal ;
3058 }