]> SALOME platform Git repositories - modules/superv.git/blob - src/GraphExecutor/DataFlowExecutor_InNodeThreads.cxx
Salome HOME
Merging with JR_ASV_2_1_0_deb_with_KERNEL_Head branch, which contains many bug fixes...
[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 if ( anInPort->IsGate() &&
890                 _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() )->IsGOTONode() ) {
891 // GateOutPort of GOTONodes are always opened
892         anInPort->State( SUPERV::ReadyState ) ;
893         InReady += 1 ;
894         CORBA::Any * anAny = new CORBA::Any() ;
895         *anAny <<= (long ) 1 ;
896         _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() )->GetChangeNodeOutGate()->Value( anAny ) ;
897         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
898                << anInPort->PortName() << " Was Done from Node "
899                << anOutPort->NodeName() << "( " << anOutPort->PortName()
900                << ") GOTONode" ;
901 #ifdef _DEBUG_
902         if ( GraphBase::Base::_prof_debug ) {
903           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
904         }
905 #endif
906         cdebug << endl ;
907       }
908       else {
909         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
910                << anInPort->PortName() << " Was NOT Done from Node "
911                << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
912                << " " << Automaton()->StateName( State() ) << " DataConnected "
913                << anInPort->IsDataConnected() << " LoopBeginning "
914                << LoopBeginning << endl ;
915       }
916     }
917 // That InPort get its value from the sending node
918     else if ( anInPort->IsGate() ) {
919       const CORBA::Any * theValue = anOutPort->Value() ;
920       long GateOpened ;
921       (*theValue) >>= GateOpened ;
922       if ( GateOpened != 0 ) {
923         InReady += 1 ;
924         anInPort->State( SUPERV::ReadyState ) ;
925         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
926                << anInPort->PortName() << " Gate is Opened from Node "
927                << anOutPort->NodeName() << "( " << anOutPort->PortName()
928                << ") " ;
929 #ifdef _DEBUG_
930         if ( GraphBase::Base::_prof_debug ) {
931           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
932         }
933 #endif
934         cdebug << endl ;
935       }
936       else if ( LoopFinished ) {
937         anInPort->State( SUPERV::ReadyState ) ;
938         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
939                << anInPort->PortName() << " GATE IS CLOSED from Node "
940                << anOutPort->NodeName() << "( " << anOutPort->PortName()
941                << ") LoopFinished" ;
942 #ifdef _DEBUG_
943         if ( GraphBase::Base::_prof_debug ) {
944           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
945         }
946 #endif
947         cdebug << endl ;
948       }
949       else {
950         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
951                << anInPort->PortName() << " GATE IS CLOSED from Node "
952                << anOutPort->NodeName() << "( " << anOutPort->PortName()
953                << ") " ;
954 #ifdef _DEBUG_
955         if ( GraphBase::Base::_prof_debug ) {
956           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
957         }
958 #endif
959         cdebug << endl ;
960       }
961     }
962     else if ( anOutPort->Done() ) {
963       InReady += 1 ;
964       anInPort->State( SUPERV::ReadyState ) ;
965       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
966              << anInPort->PortName() << " " << anInPort->PortStatus() << " is Done from Node "
967              << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
968              << anOutPort->PortStatus() << " " ;
969 #ifdef _DEBUG_
970       if ( GraphBase::Base::_prof_debug ) {
971         anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
972       }
973 #endif
974       cdebug << endl ;
975 // MacroNode : give immediately the value to the corresponding graph
976       if ( IsMacroNode() ) {
977         cout << "SomeDataReadyAction " << GraphMacroNode() << " " << GraphMacroNode()->Name()
978              << " coupled to " << GraphMacroNode()->CoupledNode() << endl ;
979         GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
980         cdebug << "SomeDataReadyAction MacroNode " << aMacroGraph->Graph()->Name() << " --> InputOfAny "
981                << InReady << "/" << GetNodeInPortsSize() << " InPorts are Ready" << endl ;
982 //        GraphMacroNode()->MacroObject()->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
983         aMacroGraph->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
984       }
985     }
986     else {
987       cdebug << pthread_self() << "/" << ThreadNo() << " Node " << Name() << "( "
988              << anInPort->PortName() << ") " << anInPort->PortStatus()
989              << " is NOT Done from Node "
990              << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
991              << anOutPort->PortStatus() << " " ;
992     }
993   }
994
995   if ( InReady == GetNodeInPortsSize() ) { // All Flags != 0 :
996     res = SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
997   }
998   else { // At least one Flag == 0 :
999     res = SendEvent( GraphExecutor::NotAllDataReadyEvent );
1000   }
1001
1002   cdebug << pthread_self() << "/" << ThreadNo()
1003          << " <-- DataWaiting_SomeDataReadyAction "  << Name() << endl;
1004   return res ;
1005
1006 }
1007
1008 int GraphExecutor::InNode::DataUndef_NotAllDataReadyAction() {
1009   CreateNewThreadIf( false ) ;
1010 //  cdebug << pthread_self() << " for " << ThreadNo()
1011 //         << " DataUndef_NotAllDataReadyAction " << Name() << endl;
1012   return 1;
1013 }
1014
1015 int GraphExecutor::InNode::DataUndef_AllDataReadyAction() {
1016 //  cdebug << pthread_self() << "/" << ThreadNo()
1017 //         << " --> DataUndef_AllDataReadyAction " << Name()
1018 //         << " CreateNewThreadIf " << CreateNewThreadIf() << " IsLockedDataWait "
1019 //         << IsLockedDataWait() ;
1020   if ( IsLockedDataWait() ) {
1021     cdebug << "DataUndef_AllDataReadyAction() WOULD DEAD-LOCK" << endl ;
1022     return 0 ; // ==> DataUndef_AllDataReadyAction() after UnLockDataWait()
1023   }
1024 //  cdebug << endl ;
1025   CreateNewThread( CreateNewThreadIf() ) ;
1026   if ( !CreateNewThread() ) {
1027 //    cdebug << "Thread " << ThreadNo() << "-->" << pthread_self() << endl ;
1028     ThreadNo( pthread_self() ) ;
1029   }
1030   _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1031                        GraphExecutor::DataReadyState ) ; 
1032   ReadyAction() ;
1033   SUPERV::ControlState aControl = ControlState() ;
1034   switch ( aControl ) {
1035   case SUPERV::VoidState : {
1036     SendEvent( GraphExecutor::ExecuteEvent ) ;
1037     break ;
1038   }
1039   case SUPERV::ToSuspendState : {
1040     SendEvent( GraphExecutor::SuspendEvent ) ;
1041     break ;
1042   }
1043   case SUPERV::ToSuspendStartState : {
1044     SendEvent( GraphExecutor::SuspendEvent ) ;
1045     break ;
1046   }
1047   case SUPERV::ToSuspendDoneState : {
1048     SendEvent( GraphExecutor::ExecuteEvent ) ;
1049     break ;
1050   }
1051   case SUPERV::ToKillState : {
1052     SendEvent( GraphExecutor::KillEvent ) ;
1053     break ;
1054   }
1055   case SUPERV::ToKillDoneState : {
1056     SendEvent( GraphExecutor::ExecuteEvent ) ;
1057     break ;
1058   }
1059   case SUPERV::ToStopState : {
1060     SendEvent( GraphExecutor::StopEvent ) ;
1061     break ;
1062   }
1063   default : {
1064     cdebug << ThreadNo()
1065            << " GraphExecutor::InNodeThreads::DataUndef_AllDataReadyAction Error Undefined Control : "
1066            << aControl << endl ;
1067     return 0;
1068   }
1069   }
1070 //  cdebug << pthread_self() << "/" << ThreadNo()
1071 //         << " <-- DataUndef_AllDataReadyAction " << Name() << endl;
1072   return 1;
1073 }
1074
1075 int GraphExecutor::InNode::DataReady_SuspendAction() {
1076   cdebug << pthread_self() << "/" << ThreadNo()
1077          << "DataReady_SuspendAction --> Suspend " << Name()
1078          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
1079          << _OutNode->SuspendedThreads() << endl;
1080   _OutNode->PushEvent( this , GraphExecutor::SuspendedReadyEvent ,
1081                        GraphExecutor::SuspendedReadyState ) ;
1082   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
1083   cdebug << pthread_self() << "/" << ThreadNo()
1084          << "DataReady_SuspendAction Resumed " << Name() << endl;
1085   if ( aReStartNode ) {
1086     _aReStartNode = NULL ;
1087     aReStartNode->SendEvent( _aReStartEvent ) ;
1088   }
1089   else {
1090     SendEvent( GraphExecutor::ExecuteEvent ) ;
1091   }
1092   return 1 ;
1093 }
1094
1095 int GraphExecutor::InNode::SuspendedReady_ResumeAction() {
1096   cdebug << pthread_self() << "/" << ThreadNo() << "SuspendedReady_ResumeAction "
1097          << Name() << endl;
1098 //  ResumeAction() ;
1099   _OutNode->PushEvent( this , GraphExecutor::ResumedReadyEvent ,
1100                        GraphExecutor::ResumedReadyState ) ; 
1101   return 1 ;
1102 }
1103
1104 int GraphExecutor::InNode::DataReady_KillAction() {
1105   _OutNode->PushEvent( this , GraphExecutor::KilledReadyEvent ,
1106                        GraphExecutor::KilledReadyState ) ;
1107   KillAction() ;
1108   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_KillAction " << Name()
1109          << " will pthread_exit()" << endl;
1110   return 1 ;
1111 }
1112
1113 int GraphExecutor::InNode::DataReady_StopAction() {
1114   _OutNode->PushEvent( this , GraphExecutor::StoppedReadyEvent ,
1115                        GraphExecutor::StoppedReadyState ) ; 
1116   StopAction() ;
1117   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_StopAction " << Name()
1118          << " will pthread_exit()" << endl;
1119   return 1 ;
1120 }
1121
1122 #include <CORBA.h>
1123
1124 int GraphExecutor::InNode::DataReady_ExecuteAction() {
1125   int i;
1126
1127 //  cdebug << pthread_self() << "/" << ThreadNo() << " --> DataReady_ExecuteAction "
1128 //         << Name() << endl;
1129   _OutNode->PushEvent( this , GraphExecutor::ExecuteEvent ,
1130                        GraphExecutor::ExecutingState ) ; 
1131
1132   RunningAction() ;
1133
1134   bool Err = false ;
1135
1136   SUPERV::GraphState PortState = SUPERV::ReadyState ;
1137   GraphExecutor::AutomatonState NewState = GraphExecutor::DataUndefState ;
1138   GraphExecutor::NodeEvent NewEvent = GraphExecutor::UndefinedEvent ;
1139
1140   int nInParams ;
1141   ServicesAnyData * InParametersList ;
1142   int nOutParams ;
1143   ServicesAnyData * OutParametersList ;
1144
1145   nInParams = GetNodeInPortsSize()  ;
1146   InParametersList = new ServicesAnyData[nInParams];
1147   InParametersSet( Err , nInParams , InParametersList ) ;
1148
1149   nOutParams = GetNodeOutPortsSize() ;
1150   OutParametersList = new ServicesAnyData[nOutParams];
1151   InOutParametersSet( nOutParams , OutParametersList ) ;
1152
1153   if ( !IsMacroNode() ) {
1154
1155     Engines::Container_var myContainer ;
1156     Engines::Component_var myObjComponent ;
1157     if ( !IsFactoryNode() ) {
1158 //      cdebug << ThreadNo() << "No Component : NO StartComponent & No Ping" << endl ;
1159       if ( IsComputingNode() ) {
1160         ObjInterface( true ) ;
1161         CORBA::Object_ptr obj ;
1162         InParametersList[0].Value >>= obj ;
1163         CORBA::Object_var objvar = CORBA::Object_var( obj ) ;
1164         myObjComponent = Engines::Component::_narrow( objvar ) ;
1165       }
1166       else {
1167       }
1168     }
1169     else if ( CORBA::is_nil( Component() ) ) {
1170 //      ostringstream astr ;
1171 //      astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name()
1172 //           << " : load of component " << ComponentName() << " in container "
1173 //           << Computer() ;
1174 //      _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
1175       Err = !_OutNode->Graph()->StartComponent( ThreadNo() , Computer() ,
1176                                                 my_strdup( ComponentName() ) ,
1177                                                 myContainer , myObjComponent ) ;
1178       ObjInterface( false ) ;
1179       SetContainer( myContainer ) ;
1180       SetComponent( myObjComponent ) ;
1181     }
1182     else {
1183       myContainer = Container() ;
1184       myObjComponent = Component() ;
1185 //      cdebug << ThreadNo() << "Component known : NO StartComponent & Ping"
1186 //             << endl ;
1187       try {
1188         myObjComponent->ping() ;
1189       }
1190       catch( ... ) {
1191         cdebug << "ping() catched" << endl ;
1192         Err = true ;
1193       }
1194     }
1195
1196     if ( Err || ControlState() == SUPERV::ToKillState ||
1197                 ControlState() == SUPERV::ToKillDoneState ||
1198                 ControlState() == SUPERV::ToStopState ) {
1199       cdebug << ThreadNo() << "StartComponent Error or ToKillState" << endl ;
1200       MESSAGE(pthread_self() << "Executor::InNode::DataReady_ExecuteAction of " << Name()
1201               << " ControlState " << Automaton()->ControlStateName( ControlState() )
1202               << " BEFORE execution ThreadNo " << ThreadNo() ) ;
1203       Err = true ;
1204     }
1205     else {
1206       if ( ControlState() == SUPERV::ToSuspendState ) {
1207         cdebug << ThreadNo() << "ToSuspendState before running." << endl ;
1208         MESSAGE(ThreadNo() << "ToSuspendState before running.") ;
1209       }
1210       if ( !Err ) {
1211 //        ostringstream astr ;
1212 //        astr << "Graph " << _OutNode->Graph()->Name() << " Run of Node " << Name() ;
1213 //        _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
1214         cdebug << ThreadNo() << " Run( '" << ServiceName() << "'" ;
1215         for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
1216           cdebug << " , " << InParametersList[ i ].Name << "[kind"
1217                  << InParametersList[ i ].Value.type()->kind() << "]" ;
1218         }
1219         for ( i = 0 ; i < (int ) ServiceOutParameter().length() ; i++ ) {
1220           cdebug << " , " << OutParametersList[ i ].Name << "[kind"
1221                  << OutParametersList[ i ].Value.type()->kind() << "]" ;
1222         }
1223         if ( IsOneOfInLineNodes() ) {
1224           cdebug << " , PyFuncName '" << InLineNode()->PyFuncName() << "' PyRunMethod "
1225                  << InLineNode()->PyRunMethod() << " length "
1226                  << (*InLineNode()->PythonFunction()).length() ;
1227         }
1228         cdebug << ")" << endl ;
1229
1230         if ( IsOneOfInLineNodes() ) {
1231           bool StsPyDynInvoke = true;
1232           _OutNode->PyThreadLock() ;
1233           SetPyCpuUsed() ;
1234           try {
1235 //            if ( IsInLineNode() && (*InLineNode()->PythonFunction()).length() &&
1236             bool ItIsaLoop = false ;
1237             bool CopyInOut = false ;
1238             if ( IsInLineNode() && /*InLineNode()->PyRunMethod() &&*/
1239                  strlen( InLineNode()->PyFuncName() ) ) {
1240               cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1241                      << InLineNode()->PyFuncName()
1242                      << "' IsInLineNode PyDynInvoke"  << endl ;
1243               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1244                                             InLineNode()->PyFuncName() ,
1245                                             &InParametersList[0] , ServiceInParameter().length() ,
1246                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1247               if ( !StsPyDynInvoke ) {
1248                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1249               }     }
1250             else if ( IsLoopNode() ) {
1251               ItIsaLoop = true ;
1252               bool CopyOutIn = false ;
1253 // Switch between Init() and Next()
1254 // if InLoop port is true and does not come from EndLoop ==> execute Init
1255 // if InLoop port is false or come from EndLoop ==> execute Next
1256 //              GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
1257 //              if ( GetNodeInLoop()->GetOutPort()->BoolValue() &&
1258               if ( _InitLoop ) {
1259                 if ( strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port = true ==> Init()
1260                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1261                          << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
1262                          << "' InitLoop " << LoopNode()->PyRunMethod() << endl ;
1263                   StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1264                                                 InLineNode()->PyFuncName() ,
1265                                                 &InParametersList[1] , ServiceInParameter().length() ,
1266                                                 &OutParametersList[1] , ServiceOutParameter().length() ) ;
1267                 if ( !StsPyDynInvoke ) {
1268                   RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1269                 }
1270                   CopyOutIn = true ;
1271                 }
1272                 else {
1273                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1274                          << " IsLoopNode NO PyDynInvoke Void PyFuncName InitLoop" << endl ;
1275                 }
1276                 cdebug << ThreadNo() << " !ObjInterface " << Name()
1277                        << " IsLoopNode _InitLoop Reset after Init() Python Function" << endl ;
1278                 _InitLoop = false ;
1279               }
1280               else if ( LoopNode()->PyNextMethod() &&
1281                         strlen( LoopNode()->PyNextName() ) ){ // InLoop Port = false ==> Next()
1282                 cdebug << ThreadNo() << " !ObjInterface " << Name()
1283                        << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
1284                        << "' " << LoopNode()->PyNextMethod() << endl ;
1285                 StsPyDynInvoke = PyDynInvoke( LoopNode()->PyNextMethod() ,
1286                                               LoopNode()->PyNextName() ,
1287                                               &InParametersList[1] , ServiceInParameter().length() ,
1288                                               &OutParametersList[1] , ServiceOutParameter().length() ) ;
1289                 if ( !StsPyDynInvoke ) {
1290                   RemovePyDynInvoke( LoopNode()->PyNextName() ) ;
1291                 }
1292                 CopyOutIn = true ;
1293               }
1294               else {
1295                 cdebug << ThreadNo() << " !ObjInterface " << Name()
1296                        << " IsLoopNode NO PyDynInvoke Void PyFuncName NextLoop" << endl ;
1297               }
1298               if ( StsPyDynInvoke ) {
1299                 if ( CopyOutIn ) {
1300                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1301                          << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
1302                          << "' Copy of " << ServiceInParameter().length()
1303                          << " OutParameters" << endl ;
1304                   int i ;
1305 // Start at 1 : Do not copy InLoop ( InLoop == true <==> Init ; InLoop == false <==> Next )
1306                   for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
1307                     InParametersList[i].Value = OutParametersList[i].Value ;
1308                     InParametersList[i].Name = OutParametersList[i].Name ;
1309 //#if 0
1310                     switch ( InParametersList[i].Value.type()->kind() ) {
1311                     case CORBA::tk_string :
1312                       char * t;
1313                       InParametersList[i].Value >>= t ;
1314                       cdebug << "ArgOut->In" << i << " : "
1315                              << InParametersList[i].Name.c_str()
1316                              << " Value(string) " << t << endl ;
1317                       break ;
1318                     case CORBA::tk_double :
1319                       double d;
1320                       InParametersList[i].Value >>= d;
1321                       cdebug << "ArgOut->In" << i << " : "
1322                              << InParametersList[i].Name.c_str()
1323                              << " Value(double) " << d << endl ;
1324                       break ;
1325                     case CORBA::tk_long :
1326                       long l;
1327                       InParametersList[i].Value >>= l;
1328                       cdebug << "ArgOut->In" << i << " : "
1329                              << InParametersList[i].Name.c_str()
1330                              << " Value(long) " << l << endl ;
1331                       break ;
1332                     case CORBA::tk_objref :
1333                       CORBA::Object_ptr obj ;
1334                       char * retstr ;
1335                       try {
1336                         InParametersList[i].Value >>= obj ;
1337                         retstr = ObjectToString( obj );
1338                         cdebug << "ArgOut->In" << i << " : "
1339                                << InParametersList[i].Name.c_str()
1340                                << " Value(object reference) " << retstr << endl ;
1341                        }
1342                       catch ( ... ) {
1343                         cdebug << "ArgOut->In" << i << " : "
1344                                << InParametersList[i].Name.c_str()
1345                                << " Value(object reference) Catched ERROR" << endl ;
1346                       }
1347                       break ;
1348                     default :
1349                       cdebug << "ArgOut->In" << i << " : "
1350                              << InParametersList[i].Name.c_str()
1351                              << " Value(other) ERROR" << endl ;
1352                     }
1353 //#endif
1354                   }
1355                 }
1356                 if ( LoopNode()->PyMoreMethod() && strlen( LoopNode()->PyMoreName() ) ) {
1357                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1358                          << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
1359                          << "' " << LoopNode()->PyMoreMethod() << endl ;
1360                   StsPyDynInvoke = PyDynInvoke( LoopNode()->PyMoreMethod() ,
1361                                                 LoopNode()->PyMoreName() ,
1362                                                 &InParametersList[1] , ServiceInParameter().length() ,
1363                                                 &OutParametersList[0] , ServiceOutParameter().length()+1 ) ;
1364                   if ( !StsPyDynInvoke ) {
1365                     RemovePyDynInvoke( LoopNode()->PyMoreName() ) ;
1366                   }
1367                 }
1368                 else {
1369                   cdebug << ThreadNo() << " !ObjInterface " << Name()
1370                          << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
1371                          << "' No MoreMethod" << endl ;
1372                   CopyInOut = true ;
1373                 }
1374               }
1375               else {
1376                 Err = true ;
1377                 cdebug << ThreadNo() << " InLineNode " << Name() << " "
1378                        << InLineNode()->PyFuncName() << "/" << LoopNode()->PyNextName()
1379                        << " Python Dynamic Call Error"
1380                        << endl ;
1381               }
1382             }
1383             else if ( IsSwitchNode() && /*InLineNode()->PyRunMethod() &&*/
1384                       strlen( InLineNode()->PyFuncName() ) ) {
1385 //              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1386 //                     << InLineNode()->PyFuncName()
1387 //                     << "' IsSwitchNode PyDynInvoke"  << endl ;
1388               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1389                                             InLineNode()->PyFuncName() ,
1390                                             &InParametersList[0] , ServiceInParameter().length() ,
1391                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1392               if ( !StsPyDynInvoke ) {
1393                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1394               }
1395             }
1396 //            else if ( IsGOTONode() && (*GOTONode()->PythonFunction()).length() &&
1397             else if ( IsGOTONode() && /*InLineNode()->PyRunMethod() &&*/
1398                       strlen( InLineNode()->PyFuncName() ) ) {
1399 //              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1400 //                     << InLineNode()->PyFuncName()
1401 //                     << "' IsGOTONode PyDynInvoke"  << endl ;
1402               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1403                                             InLineNode()->PyFuncName() ,
1404                                             &InParametersList[0] , ServiceInParameter().length() ,
1405                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1406               if ( !StsPyDynInvoke ) {
1407                 RemovePyDynInvoke( GOTONode()->PyFuncName() ) ;
1408               }
1409             }
1410 //            else if ( IsEndSwitchNode() && (*InLineNode()->PythonFunction()).length() &&
1411             else if ( ( IsEndSwitchNode() ) &&
1412                       InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
1413 //              cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1414 //                     << InLineNode()->PyFuncName()
1415 //                     << "' IsSwitchNode PyDynInvoke"  << endl ;
1416               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1417                                             InLineNode()->PyFuncName() ,
1418                                             &InParametersList[0] , ServiceInParameter().length() ,
1419                                             &OutParametersList[0] , ServiceOutParameter().length() ) ;
1420               if ( !StsPyDynInvoke ) {
1421                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1422               }
1423             }
1424             else if ( ( IsEndLoopNode() ) &&
1425                       InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
1426               cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1427                      << InLineNode()->PyFuncName()
1428                      << "' IsSwitchNode PyDynInvoke"  << endl ;
1429               StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1430                                             InLineNode()->PyFuncName() ,
1431                                             &InParametersList[0] , ServiceInParameter().length() + 1 ,
1432                                             &OutParametersList[0] , ServiceOutParameter().length() + 1 ) ;
1433               if ( !StsPyDynInvoke ) {
1434                 RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1435               }
1436             }
1437
1438 //            else if ( (*InLineNode()->PythonFunction()).length() == 0 ||
1439             if ( (!ItIsaLoop && ( InLineNode()->PyRunMethod() == NULL ||
1440                                   strlen( InLineNode()->PyFuncName() ) == 0 ) ) || CopyInOut ) {
1441 // This is a void Python Function : without code (No PyFuncName)
1442 //              cdebug << ThreadNo() << " !ObjInterface " << Name()
1443 //                     << " Copy of " << ServiceInParameter().length()
1444 //                     << " OutParameters" << endl ;
1445               int i ;
1446               int argout0 = 0 ;
1447               int argin0 = 0 ;
1448               if ( IsLoopNode() || IsEndLoopNode() ) {
1449                 argout0 = 1 ;
1450                 argin0 = 1 ; // after DoLoop
1451                 if ( IsLoopNode() ) { // More() is void
1452 //                  OutParametersList[0].Value = InParametersList[0].Value ; // DoLoop
1453                   cdebug << Name() << " Not Beginning of loop and non void EndLoop : DoLoop = EndLoop(DoLoop)"
1454                          << endl ;
1455                   GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
1456                   OutParametersList[0].Value = *anEndLoopNode->GetNodeOutLoop()->Value() ; // DoLoop = EndLoop(DoLoop)
1457                 }
1458               }
1459               for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
1460                 OutParametersList[argout0 + i].Value = InParametersList[argin0 + i].Value ;
1461 //#if 0
1462                 switch ( InParametersList[argin0 + i].Value.type()->kind() ) {
1463                 case CORBA::tk_string :
1464                   cdebug << "ArgOut->In" << argin0 + i << " : "
1465                          << InParametersList[argin0 + i].Name.c_str()
1466                          << " Value(string) "
1467                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1468                   break ;
1469                 case CORBA::tk_double :
1470                   cdebug << "ArgOut->In" << argin0 + i << " : "
1471                          << InParametersList[argin0 + i].Name.c_str()
1472                          << " Value(double) "
1473                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1474                   break ;
1475                 case CORBA::tk_long :
1476                   cdebug << "ArgOut->In" << argin0 + i << " : "
1477                          << InParametersList[argin0 + i].Name.c_str()
1478                          << " Value(long) "
1479                          << OutParametersList[argout0 + i ].Name.c_str() << endl ;
1480                   break ;
1481                 case CORBA::tk_objref :
1482                   cdebug << "ArgOut->In" << argin0 + i << " : "
1483                          << InParametersList[argin0 + i].Name.c_str()
1484                          << " Value(object reference) "
1485                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1486                   break ;
1487                 default :
1488                   cdebug << "ArgOut->In" << argin0 + i << " : "
1489                          << InParametersList[argin0 + i].Name.c_str()
1490                          << " Value(other) ERROR "
1491                          << OutParametersList[argout0 + i].Name.c_str() << endl ;
1492                 }
1493 //#endif
1494               }
1495             }
1496             if ( !StsPyDynInvoke ) {
1497               Err = true ;
1498               cdebug << ThreadNo() << " InLineNode " << Name()
1499                      << " Python Dynamic Call Error"
1500                      << endl ;
1501             }
1502           }
1503           catch( ... ) {
1504             Err = true ;
1505             cdebug << ThreadNo() << " InLineNode " << Name()
1506                    << " Python Dynamic Call Exception catched ERROR"
1507                    << endl ;
1508           }
1509           CpuUsed( true ) ;
1510           _OutNode->PyThreadUnLock() ;
1511         }
1512         else {
1513           try {
1514             try {
1515               cdebug << "DynInvoke -> Names " << _OutNode->Graph()->Name() << " " << Name() << endl ;
1516               DynInvoke( myObjComponent, "Names" ,
1517                          _OutNode->Graph()->Name() , Name() ) ;
1518             }
1519             catch( ... ) {
1520               cdebug << "DynInvoke Names catched ERROR" << endl ;
1521             }
1522 // for DataStreamNodes : call of SetProperties ===> environment variables in the component/container
1523             if ( ComputingNode()->HasDataStream() ) {
1524               try {
1525                 cdebug << "DynInvoke -> SetProperties " << _OutNode->Graph()->Name() << " " << Name() << endl ;
1526                 Engines::FieldsDict_var dict = new Engines::FieldsDict;
1527                 dict->length( 4 );
1528                 dict[ 0 ].key = CORBA::string_dup( "CAL_MACHINE");
1529                 // myContainer->getHostName() ne renvoit pas le nom complet (avec domaine).
1530                 //              dict[ 0 ].value <<= myContainer->getHostName() ;
1531                 char FullyQualifiedDomainName[256]="";
1532                 gethostname(FullyQualifiedDomainName,255);
1533                 dict[ 0 ].value <<=  FullyQualifiedDomainName ;
1534                 dict[ 1 ].key = CORBA::string_dup( "CAL_REPERTOIRE");
1535                 dict[ 1 ].value <<= "/tmp" ;
1536                 dict[ 2 ].key = CORBA::string_dup( "CAL_COUPLAGE");
1537                 stringstream ofst1 ;
1538                 ofst1 << ComputingNode()->SubStreamGraph() ;
1539                 string cpl = string( "/tmp/" ) + string( _OutNode->Graph()->Name() ) + string( "_" ) + 
1540                              ofst1.str() + string( ".cpl" );
1541                 dict[ 2 ].value <<= cpl.c_str() ;
1542                 dict[ 3 ].key = CORBA::string_dup( "SALOME_INSTANCE_NAME");
1543                 string uname = Name();
1544                 UpperCase( uname);
1545                 dict[ 3 ].value <<= uname.c_str() ;
1546
1547                 myObjComponent->setProperties( dict ) ;
1548               }
1549               catch( ... ) {
1550                 cdebug << "DynInvoke setProperties catched ERROR" << endl ;
1551                 Err = true;
1552               }
1553             }
1554             if ( !Err && IsComputingNode() ) {
1555               cdebug << ThreadNo() << " !ObjInterface " << Name()
1556                      << " IsComputingNode DynInvoke"  << endl ;
1557               cdebug << ServiceInParameter().length()-1 << " input parameters and "
1558                      << ServiceOutParameter().length() << " output parameters" << endl ;
1559               IsLoading( false ) ;
1560               DynInvoke( myObjComponent,
1561                          ServiceName() ,
1562                          &InParametersList[1] , ServiceInParameter().length()-1 ,
1563                          &OutParametersList[0] , ServiceOutParameter().length() ) ;
1564             }
1565             else if ( !Err && IsFactoryNode() ) {
1566               cdebug << ThreadNo() << " !ObjInterface " << Name()
1567                      << " IsFactoryNode DynInvoke"  << endl ;
1568               cdebug << ServiceInParameter().length() << " input parameters and "
1569                      << ServiceOutParameter().length() << " output parameters" << endl ;
1570               IsLoading( false ) ;
1571               DynInvoke( myObjComponent,
1572                          ServiceName() ,
1573                          &InParametersList[0] , ServiceInParameter().length() ,
1574                          &OutParametersList[0] , ServiceOutParameter().length() ) ;
1575             }
1576 //            cdebug << ThreadNo() << " Component::CpuUsed " << Name() << " "
1577 //                   << myObjComponent->CpuUsed_impl() << endl ;
1578           }
1579           catch( ... ) {
1580             Err = true ;
1581             cdebug << ThreadNo() << " !ObjInterface " << Name()
1582                    << " Node(Component) Dynamic Call Exception catched ERROR"
1583                    << endl ;
1584 //Reset of _ThreadId in the Container ...
1585             try {
1586               myObjComponent->Kill_impl() ;
1587             }
1588             catch( ... ) {
1589             }
1590           }
1591         }
1592       }
1593     }
1594   }
1595
1596 //  ostringstream astr ;
1597 //  astr << "Graph " << _OutNode->Graph()->Name() << " Node " << Name() << " is done : "
1598 //       << Automaton()->StateName( State() ) ;
1599 //  _OutNode->Graph()->ObjImpl()->sendMessage( NOTIF_STEP, astr.str().c_str() ) ;
1600
1601   if ( Err ) {
1602     
1603     // if exception or something else - IsLoading( false ) may not NOT has been called
1604     if ( IsLoading() )
1605       IsLoading( false );
1606
1607     if ( ControlState() == SUPERV::ToKillState ||
1608          ControlState() == SUPERV::ToKillDoneState ||
1609          ControlState() == SUPERV::ToStopState ) {
1610       PortState = SUPERV::ErrorState ;
1611       NewState = GraphExecutor::KilledState ;
1612       NewEvent = GraphExecutor::KillEvent ;
1613     }
1614     else {
1615       PortState = SUPERV::ErrorState ;
1616       NewState = GraphExecutor::ErroredState ;
1617       NewEvent = GraphExecutor::ErrorEvent ;
1618     }
1619   }
1620   else {
1621     PortState = SUPERV::ReadyState ;
1622     NewState = GraphExecutor::DataReadyState ;
1623     NewEvent = GraphExecutor::SuccessEvent ;
1624   }
1625
1626   if ( !IsMacroNode() ) {
1627     bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
1628     if ( !ErrOut ) {
1629       NewEvent = GraphExecutor::ErrorEvent ;
1630     }
1631     delete [] InParametersList ;
1632     delete [] OutParametersList ;
1633   }
1634           
1635   if ( !IsMacroNode() ) {              
1636     SendEvent( NewEvent ) ;
1637   }
1638   else {
1639     GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
1640     cdebug << ThreadNo() << " DataReady_ExecuteAction " << aMacroGraph << " "
1641            << aMacroGraph->Graph()->Name() << " ->DoneWait()"
1642            << " State " << aMacroGraph->State() << endl;
1643     aMacroGraph->DoneWait() ;
1644     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " State " << aMacroGraph->State() << endl;
1645     if ( aMacroGraph->State() == SUPERV::DoneState ) {
1646       PortState = SUPERV::ReadyState ;
1647       NewState = GraphExecutor::DataReadyState ;
1648       NewEvent = GraphExecutor::SuccessEvent ;
1649     }
1650     else {
1651       Err = true ;
1652       if ( ControlState() == SUPERV::ToKillState ||
1653            ControlState() == SUPERV::ToKillDoneState ||
1654            ControlState() == SUPERV::ToStopState ) {
1655         PortState = SUPERV::ErrorState ;
1656         NewState = GraphExecutor::KilledState ;
1657         NewEvent = GraphExecutor::KillEvent ;
1658       }
1659       else {
1660         PortState = SUPERV::ErrorState ;
1661         NewState = GraphExecutor::ErroredState ;
1662         NewEvent = GraphExecutor::ErrorEvent ;
1663       }
1664     }
1665     bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
1666     if ( !ErrOut ) {
1667       NewEvent = GraphExecutor::ErrorEvent ;
1668     }
1669     delete [] InParametersList ;
1670     delete [] OutParametersList ;
1671     SendEvent( NewEvent ) ;
1672   }
1673
1674 //  cdebug << ThreadNo() << " <-- DataReady_ExecuteAction " << Name() << endl;
1675   return 1 ;
1676 }
1677
1678 int GraphExecutor::InNode::Executing_SuspendAction() {
1679   _OutNode->PushEvent( this , GraphExecutor::SuspendedExecutingEvent ,
1680                        GraphExecutor::SuspendedExecutingState ) ; 
1681   cdebug << ThreadNo() << " Executing_SuspendAction " << Name() << endl;
1682   return 1 ;
1683 }
1684
1685 int GraphExecutor::InNode::SuspendedExecuting_ResumeAction() {
1686   cdebug << ThreadNo() << " SuspendedExecuting_ResumeAction " << Name() << endl;
1687   GraphExecutor::AutomatonState next_state ;
1688   next_state = Automaton()->NextState( State() , GraphExecutor::ExecutingEvent ) ;
1689   _OutNode->NewThread() ; // Only for Threads count
1690   _OutNode->PushEvent( this , GraphExecutor::ResumedExecutingEvent ,
1691                        next_state ) ; 
1692   State( next_state ) ;
1693   return 1 ;
1694 }
1695
1696 int GraphExecutor::InNode::Executing_KillAction() {
1697   cdebug << ThreadNo() << " Executing_KillAction " << Name() << " Thread " << ThreadNo()<< endl;
1698   int RetVal = 0 ;
1699   if ( pthread_self() == ThreadNo() ) {
1700     cdebug << "Executing_KillAction would pthread_canceled itself" << endl ;
1701     KillAction() ;
1702     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
1703                          GraphExecutor::KilledExecutingState ) ; 
1704     RetVal = 1 ;
1705   }
1706   else if ( pthread_cancel( ThreadNo() ) ) {
1707     perror("Executing_KillAction pthread_cancel error") ;
1708   }
1709   else {
1710     cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
1711            << " pthread_canceled" << endl ;
1712     KillAction() ;
1713     _OutNode->ExitThread( ThreadNo() ) ;
1714     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
1715                          GraphExecutor::KilledExecutingState ) ; 
1716   }
1717   return RetVal ;
1718 }
1719
1720 int GraphExecutor::InNode::Executing_StopAction() {
1721   cdebug << ThreadNo() << " Executing_StopAction " << Name() << " Thread " << ThreadNo() << endl;
1722   int RetVal = 0 ;
1723   if ( pthread_cancel( ThreadNo() ) ) {
1724     perror("Executing_KillAction pthread_cancel error") ;
1725   }
1726   else {
1727     cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
1728            << " pthread_canceled" << endl ;
1729     StopAction() ;
1730     _OutNode->ExitThread( ThreadNo() ) ;
1731     _OutNode->PushEvent( this , GraphExecutor::StoppedExecutingEvent ,
1732                          GraphExecutor::StoppedExecutingState ) ; 
1733   }
1734   return RetVal ;
1735 }
1736
1737 int GraphExecutor::InNode::Executing_SuccessAction() {
1738 //  cdebug << ThreadNo() << " --> Executing_SuccessAction " << Name() << endl;
1739   _OutNode->PushEvent( this , GraphExecutor::SuccessedExecutingEvent ,
1740                        GraphExecutor::SuccessedState ) ; 
1741   MESSAGE(pthread_self() << "Executor::InNode::Executing_SuccessAction of " << Name()
1742           << " ControlState " << Automaton()->ControlStateName( ControlState() )
1743           << " AFTER execution ThreadNo " << ThreadNo() ) ;
1744   SUPERV::ControlState aControl = ControlState() ;
1745   switch ( aControl ) {
1746   case SUPERV::VoidState : {
1747     SendEvent( SuccessEvent ) ;
1748     break ;
1749   }
1750   case SUPERV::ToSuspendState : {
1751     SendEvent( SuccessEvent ) ;
1752     break ;
1753   }
1754   case SUPERV::ToSuspendDoneState : {
1755     SendEvent( GraphExecutor::SuspendEvent ) ;
1756     return 1 ;
1757   }
1758   case SUPERV::ToKillState : {
1759     SendEvent( GraphExecutor::KillEvent ) ;
1760     return 1 ;
1761   }
1762   case SUPERV::ToKillDoneState : {
1763     SendEvent( GraphExecutor::KillEvent ) ;
1764     return 1 ;
1765   }
1766   case SUPERV::ToStopState : {
1767     SendEvent( GraphExecutor::StopEvent ) ;
1768     return 1 ;
1769   }
1770   default : {
1771     cdebug << ThreadNo()
1772            << " GraphExecutor::InNodeThreads::Executing_SuccessAction Error Undefined Control : "
1773            << aControl << endl ;
1774     return 0;
1775   }
1776   }
1777 //  cdebug << ThreadNo() << " <-- Executing_SuccessAction "  << Name() << endl;
1778   return 1 ;
1779 }
1780
1781 int GraphExecutor::InNode::Executing_ErrorAction() {
1782   cdebug << ThreadNo() << " --> Executing_ErrorAction " << Name() << endl;
1783   _OutNode->PushEvent( this , GraphExecutor::ErroredExecutingEvent ,
1784                        GraphExecutor::ErroredState ) ; 
1785
1786   SUPERV::ControlState aControl = ControlState() ;
1787   switch ( aControl ) {
1788   case SUPERV::VoidState : {
1789     SendEvent( ErrorEvent ) ;
1790     break ;
1791   }
1792   case SUPERV::ToSuspendState : {
1793     SendEvent( ErrorEvent ) ;
1794     break ;
1795   }
1796   case SUPERV::ToSuspendDoneState : {
1797     SendEvent( GraphExecutor::SuspendEvent ) ;
1798     return 1 ;
1799   }
1800   case SUPERV::ToKillState : {
1801     SendEvent( GraphExecutor::KillEvent ) ;
1802     return 1 ;
1803   }
1804   case SUPERV::ToKillDoneState : {
1805     SendEvent( GraphExecutor::KillEvent ) ;
1806     return 1 ;
1807   }
1808   case SUPERV::ToStopState : {
1809     SendEvent( GraphExecutor::StopEvent ) ;
1810     return 1 ;
1811   }
1812   default : {
1813     cdebug << ThreadNo()
1814            << " GraphExecutor::InNodeThreads::Executing_ErrorAction Error Undefined Control : "
1815            << aControl << endl ;
1816     return 0;
1817   }
1818   }
1819   cdebug << ThreadNo() << " <-- Executing_ErrorAction "  << Name() << endl;
1820   return 1 ;
1821 }
1822
1823 // Set SUPERV::WaitingState to all InPorts 
1824 void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
1825   int i ;
1826   int j ;
1827   bool docdebug = false ;
1828   State( GraphExecutor::DataWaitingState ) ;
1829   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
1830     GraphBase::InPort * anInPort = GetChangeNodeInPort( i ) ;
1831     cdebug << "SetWaitingStates InPort " << Name() << "( " << anInPort->PortName() << " ) "
1832            << anInPort->PortStatus() << " " << anInPort->State() << endl ;
1833 // JR Debug 07.01.2005 : Close the Gates instead of open !!!
1834     if ( anInPort->IsGate() ) { // Loop : Close the doors
1835       GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
1836       if ( anOutPort ) {
1837         CORBA::Any * anAny = new CORBA::Any() ;
1838 //        *anAny <<= (long ) 1 ;
1839         *anAny <<= (long ) 0 ;
1840         anOutPort->Value( anAny ) ;
1841         anInPort->State( SUPERV::WaitingState ) ;
1842       }
1843     }
1844     else if ( anInPort->State() != SUPERV::WaitingState &&
1845               !anInPort->IsDataConnected() ) {
1846       if ( !docdebug ) {
1847         cdebug << ThreadNo()
1848                << " --> GraphExecutor::InNodeThreads::SetWaitingStates " << Name() << endl;
1849         docdebug = true ;
1850       }
1851       if ( !anInPort->IsDataStream() ) {
1852         anInPort->State( SUPERV::WaitingState ) ;
1853       }
1854     }
1855     cdebug << "               --> " << Name() << "( " << anInPort->PortName() << " ) "
1856            << anInPort->PortStatus() << " " << anInPort->State() << endl ;
1857   }
1858   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
1859     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
1860     for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
1861       if ( !( IsGOTONode() && anOutPort->IsGate() ) &&
1862            !( IsEndLoopNode() && ( anOutPort->IsGate() || anOutPort->IsLoop() ) ) &&
1863            !anOutPort->IsDataStream() &&
1864            !anOutPort->ChangeInPorts( j )->IsDataStream() &&
1865            !anOutPort->ChangeInPorts( j )->IsExternConnected() ) {
1866         cdebug << ThreadNo()
1867                << " InNodeThreads::SetWaitingStates OutPort "
1868                << Name() << "/" << anOutPort->ChangeInPorts( j )->NodeName() << "( "
1869                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " ) --> InPort "
1870                << anOutPort->ChangeInPorts( j )->NodeName() << "( "
1871                << anOutPort->ChangeInPorts( j )->PortName() << " "
1872                << anOutPort->ChangeInPorts( j )->PortStatus() << " )" << endl;
1873         GraphBase::ComputingNode * aToNode ;
1874         aToNode = _OutNode->Graph()->GetChangeGraphNode( anOutPort->ChangeInPorts( j )->NodeName() ) ;
1875 // JR 12.01.2005 : the OutPort linked to the InPort of a EndSwitchNode was changed so final
1876 //                 values of InPorts of EndSwitchNode may be wrong
1877         if ( !aToNode->IsEndSwitchNode() && 
1878              strcmp( anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() , Name() ) ) {
1879 // After EndLoopNode or GOTONode the Input Ports of LoopNode or LabelNode have their values from
1880 // EndLoopNode or GOTONode. But if there is several nested loops we should re-establish.
1881           cdebug << ThreadNo()
1882                  << " InNodeThreads::SetWaitingStates Node " << Name() << " " 
1883                  << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() << "( "
1884                  << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName() << " ) != "
1885                  << Name() << " : Restored to " << anOutPort->NodeName() << "( "
1886                  << anOutPort->PortName() << " )" << endl ;
1887           anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
1888         }
1889         GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) aToNode->GetInNode() ;
1890         if ( aNode != EndNode ) {
1891           aNode->SetWaitingStates( EndNode ) ;
1892         }
1893       }
1894     }
1895   }
1896 }
1897
1898 int GraphExecutor::InNode::Successed_SuccessAction() {
1899   cdebug << ThreadNo() << " --> Successed_SuccessAction "  << Name() << endl;
1900   int res = 1;
1901   int linkednodesnumber = LinkedNodesSize() ;
1902   GraphExecutor::InNode *firstzeroNode = NULL ;
1903   GraphExecutor::InNode *firsttoNode = NULL ;
1904   GraphExecutor::InNode *toNode ;
1905   int i ;
1906   int j ;
1907   list<GraphExecutor::InNode *> SomeDataNodes ;
1908
1909   DoneAction() ;
1910
1911   if ( IsMacroNode() ) {
1912       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " LinkedNodes->SomeDataReady already done"
1913              << endl ;
1914     return 1;
1915   }
1916
1917   if ( IsGOTONode() ||
1918        ( IsEndLoopNode() && GetNodeInLoop()->GetOutPort()->BoolValue() ) ) {
1919     cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name()
1920            << " SetWaitingStates " << endl ;
1921     const GraphBase::OutPort * aGateOutPort ;
1922     if ( IsGOTONode() ) {
1923       aGateOutPort = GetNodeOutGate() ;
1924     }
1925     else {
1926       aGateOutPort = GetNodeOutLoop() ;
1927     }
1928     if ( aGateOutPort->InPortsSize() != 1 ) {
1929       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction aGateOutPort->InPortsSize "
1930              << aGateOutPort->InPortsSize() << " != 1 ERROR " << Name() << endl ;
1931     }
1932     GraphExecutor::InNode * aLabelNode = NULL ;
1933     for ( i = 0 ; i < aGateOutPort->InPortsSize() ; i++ ) {
1934       const GraphBase::InPort * anInPort = aGateOutPort->InPorts( i ) ;
1935       aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
1936       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " will Loop to HeadNode "
1937              << aLabelNode->Name() << " from port " << anInPort->PortName() << endl ;
1938       aLabelNode->SetWaitingStates( this ) ;
1939 // JR 07.01.2005 Debug : Open the Gate of the coupledNode closed by SetWaitingStates
1940       GraphBase::OutPort * anOutPort = aLabelNode->GetChangeNodeInGate()->GetOutPort() ;
1941       if ( anOutPort ) {
1942         CORBA::Any * anAny = new CORBA::Any() ;
1943         *anAny <<= (long ) 1 ;
1944         anOutPort->Value( anAny ) ;
1945         aLabelNode->GetChangeNodeInGate()->State( SUPERV::ReadyState ) ;
1946       }
1947       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
1948         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
1949         if ( anInPort->GetOutPort() ) {
1950           cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
1951                  << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
1952                  << endl ;
1953         }
1954       }
1955       for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
1956         GraphBase::OutPort * aBusParamOutPort = GetChangeNodeOutPort( j ) ;
1957         if ( !aBusParamOutPort->IsGate() ) {
1958           GraphBase::InPort * aBusParamChangeInPort = NULL ;
1959           if ( aBusParamOutPort->IsLoop() ) {
1960 // For EndLoop do not copy EndLoop(DoLoop) in Loop(InLoop)
1961 //            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
1962           }
1963           else {
1964             aBusParamChangeInPort = aLabelNode->GetChangeInPort( aBusParamOutPort->PortName() ) ;
1965           }
1966           if ( aBusParamChangeInPort ) {
1967             aBusParamChangeInPort->ChangeOutPort( aBusParamOutPort ) ;
1968             cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " ChangeOutPort to HeadNode "
1969                    << aLabelNode->Name() << "(" << aBusParamChangeInPort->PortName() << ") from port "
1970                    << aBusParamOutPort->PortName() << endl ;
1971           }
1972         }
1973       }
1974     }
1975
1976     if ( aLabelNode && !aLabelNode->IsLockedDataWait() ) {
1977       res = aLabelNode->SendSomeDataReady( Name() ) ;
1978       if ( res ) {
1979         if ( firsttoNode == NULL &&
1980              aLabelNode->ThreadNo() == pthread_self() ) {
1981           firsttoNode = aLabelNode ;
1982           cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction firsttoNode "
1983                  << aLabelNode->Name() << endl ;
1984         }
1985         else if ( firstzeroNode == NULL &&
1986                   aLabelNode->ThreadNo() == 0 ) {
1987           firstzeroNode = aLabelNode ;
1988         }
1989         else {
1990           SomeDataNodes.push_back( aLabelNode ) ;
1991           cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
1992                  << aLabelNode->Name() << " " << SomeDataNodes.size() 
1993                  << endl ;
1994         }
1995       }
1996
1997       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
1998         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
1999         if ( anInPort->GetOutPort() ) {
2000           cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
2001                  << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
2002                  << endl ;
2003         }
2004       }
2005       const GraphBase::InPort * aGateInPort = aLabelNode->GetNodeInGate() ;
2006       if ( aGateInPort ) {
2007         if ( aGateInPort->GetOutPort() ) {
2008           aGateInPort->GetOutPort()->Value( aGateOutPort->Value() ) ;
2009         }
2010         if ( !aLabelNode->IsLockedDataWait() ) {
2011           res = aLabelNode->SendSomeDataReady( Name() ) ;
2012           if ( res ) {
2013             if ( firsttoNode == NULL &&
2014                  aLabelNode->ThreadNo() == pthread_self() ) {
2015               firsttoNode = aLabelNode ;
2016               cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction firsttoNode "
2017                      << aLabelNode->Name() << endl ;
2018             }
2019             else if ( firstzeroNode == NULL &&
2020                       aLabelNode->ThreadNo() == 0 ) {
2021               firstzeroNode = aLabelNode ;
2022             }
2023             else {
2024               SomeDataNodes.push_back( aLabelNode ) ;
2025               cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
2026                      << aLabelNode->Name() << " " << SomeDataNodes.size()
2027                      << endl ;
2028             }
2029           }
2030         }
2031       }
2032       else {
2033         cdebug << pthread_self() << "/" << ThreadNo() << " ERROR in Successed_SuccessAction of " << Name()
2034                << " NO port " << aGateOutPort->PortName() << " in "
2035                << aLabelNode->Name() << endl;
2036       }
2037     }
2038   }
2039
2040   else {
2041     cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
2042            << " with " << LinkedNodesSize() << " linked nodes :" ;
2043     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2044       if ( LinkedNodes( i )->IsDataFlowNode() ) {
2045         linkednodesnumber -= 1 ;
2046       }
2047       cdebug << " " << LinkedNodes( i )->Name() ;
2048     }
2049     cdebug << endl;
2050     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2051       bool IgnoreForEndLoop = false ;
2052       GraphBase::ComputingNode * aComputingNode ;
2053       aComputingNode = (GraphBase::ComputingNode * ) LinkedNodes( i ) ;
2054       toNode = (GraphExecutor::InNode *) aComputingNode->GetInNode() ;
2055       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction of " << Name()
2056              << " [" << i << "] " << LinkedNodes( i )->Name() << " toNode " << toNode << " IgnoreForEndLoop "
2057              << IgnoreForEndLoop ;
2058       if ( toNode ) {
2059         cdebug << " " << toNode->Kind() << endl ;
2060       }
2061       if ( toNode && !toNode->IsDataFlowNode() ) {
2062         if ( IsComputingNode() && toNode->IsInLineNode() ) {
2063           GraphBase::InPort * toGateInPort = toNode->GetChangeNodeInGate() ;
2064           toGateInPort->State( SUPERV::ReadyState ) ;
2065           GraphBase::OutPort * GateOutPort = toGateInPort->GetOutPort() ;
2066           if ( GateOutPort ) {
2067             GateOutPort->PortStatus( DataConnected );
2068             GateOutPort->State( SUPERV::ReadyState ) ;
2069             GateOutPort->Done( true ) ;
2070           }
2071         }
2072       }
2073       if ( toNode && IsLoopNode() ) {
2074         GraphBase::OutPort * fromLoopOutPort = GetChangeNodeOutLoop() ;
2075         if ( !fromLoopOutPort->BoolValue() ) { // Ne pas faire la boucle
2076           if ( strcmp( toNode->Name() , CoupledNode()->Name() ) ) {
2077             IgnoreForEndLoop = true ;
2078           }
2079           else { // toNode is the EndLoopNode
2080             GraphBase::InPort * toLoopInPort ;
2081             toLoopInPort = toNode->GetChangeNodeInLoop() ;
2082             if ( toLoopInPort->State() != SUPERV::ReadyState ) {
2083               toLoopInPort->State( SUPERV::ReadyState ) ;
2084             }
2085           }
2086         }
2087       }
2088       else if ( toNode && IsSwitchNode() ) {
2089       }
2090       else if ( toNode && toNode->IsInLineNode() ) {
2091         int j ;
2092         for ( j = 0 ; j < toNode->GetNodeInPortsSize() ; j++ ) {
2093           toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
2094         }
2095       }
2096       if ( toNode && !IgnoreForEndLoop ) {
2097         if ( toNode && toNode->IsLoopNode() ) {
2098           GraphBase::InPort * toLoopInPort = toNode->GetChangeNodeInLoop() ;
2099           toLoopInPort->State( SUPERV::ReadyState ) ;
2100           GraphBase::OutPort * LoopOutPort = toLoopInPort->GetOutPort() ;
2101           LoopOutPort->PortStatus( DataConnected );
2102           LoopOutPort->State( SUPERV::ReadyState ) ;
2103           LoopOutPort->Done( true ) ;
2104           CORBA::Any * anAny = new CORBA::Any() ; // InitLoop
2105           *anAny <<= (long ) 1 ;
2106           LoopOutPort->Value( anAny ) ;
2107           int j ;
2108           for ( j = 0 ; j < toNode->GetNodeInPortsSize() ; j++ ) {
2109             toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
2110           }
2111         }
2112         cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << toNode->Name() << "->SendSomeDataReady( "
2113                << Name() << " )" << endl ;
2114         res = toNode->SendSomeDataReady( Name() ) ;
2115         if ( res ) {
2116           if ( firsttoNode == NULL &&
2117                toNode->ThreadNo() == pthread_self() ) {
2118             firsttoNode = toNode ;
2119             cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction firsttoNode "
2120                    << toNode->Name() << endl ;
2121           }
2122           else if ( firstzeroNode == NULL &&
2123                     toNode->ThreadNo() == 0 ) {
2124             firstzeroNode = toNode ;
2125           }
2126           else {
2127             SomeDataNodes.push_back( toNode ) ;
2128             cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " push "
2129                    << toNode->Name() << " " << SomeDataNodes.size() << endl ;
2130           }
2131         }
2132       }
2133     }
2134   }
2135
2136   if ( firsttoNode == NULL && firstzeroNode ) {
2137     firsttoNode = firstzeroNode ;
2138     cdebug << pthread_self() << "/" << ThreadNo()
2139            << " Successed_SuccessAction firsttoNode = firstzeroNode "
2140            << endl ;
2141   }
2142   else if ( firsttoNode && firstzeroNode ) {
2143     SomeDataNodes.push_back( firstzeroNode ) ;
2144     cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " push firstzeroNode "
2145            << firstzeroNode->Name() << " " << SomeDataNodes.size() << endl ;
2146   }
2147   else {
2148     cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " firsttoNode " << firsttoNode
2149            << " firstzeroNode " << firstzeroNode << endl ;
2150   }
2151
2152   while ( SomeDataNodes.size() ) {
2153     GraphExecutor::InNode *aNode = SomeDataNodes.front() ;
2154     SomeDataNodes.pop_front() ;
2155 //    cdebug << pthread_self() << "/" << ThreadNo()
2156 //           << " Successed_SuccessAction pop "
2157 //           << SomeDataNodes.size() << " " << aNode->Name() << endl ;
2158     if ( aNode->State() == GraphExecutor::DataReadyState ) {
2159       aNode->CreateNewThreadIf( true ) ;
2160       aNode->UnLockDataWait() ;
2161       res = aNode->DataUndef_AllDataReadyAction() ;
2162     }
2163     else {
2164 //      cdebug << pthread_self() << "/" << ThreadNo() << " ERROR "
2165 //             << aNode->Name() << " "
2166 //             << Automaton()->StateName( aNode->State() ) << endl ;
2167     }
2168   }
2169
2170   if ( firsttoNode ) {
2171 //    cdebug << pthread_self() << "/" << ThreadNo()
2172 //           << " Successed_SuccessAction start firsttoNode "
2173 //           << SomeDataNodes.size() << " " << firsttoNode->Name() << endl ;
2174     firsttoNode->CreateNewThreadIf( false ) ;
2175     firsttoNode->RewindStack( RewindStack() ) ;
2176     if ( firsttoNode->State() == GraphExecutor::SuccessedState ) {
2177 //      cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
2178 //             << " : " << firsttoNode->Name() << " "
2179 //             << Automaton()->StateName( firsttoNode->State() )
2180 //             << " --> DataWaitingState for Thread "
2181 //             << firsttoNode->ThreadNo() << endl ;
2182       firsttoNode->State( GraphExecutor::DataWaitingState ) ;
2183     }
2184 //    pthread_t OldT = firsttoNode->ThreadNo() ;
2185     firsttoNode->ThreadNo( pthread_self() ) ;
2186 // On continue avec le meme thread
2187 //    cdebug << pthread_self() << "/" << ThreadNo() << " firsttoNode "
2188 //           << firsttoNode->Name() << "Thread(" << OldT << "-->"
2189 //           << firsttoNode->ThreadNo() << ")" << endl ;
2190     ThreadNo( 0 ) ;
2191 //    cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
2192 //           << " for " << firsttoNode->Name()
2193 //           << " !firsttoNode->CreateNewThreadIf() "
2194 //           << !firsttoNode->CreateNewThreadIf()
2195 //           << " " << Automaton()->StateName( firsttoNode->State() ) ;
2196     if ( firsttoNode->State() == GraphExecutor::DataReadyState ) {
2197       cdebug << endl ;
2198       firsttoNode->UnLockDataWait() ;
2199       res = firsttoNode->DataUndef_AllDataReadyAction() ;
2200     }
2201     else {
2202       cdebug << " ERROR " << endl ;
2203     }
2204   }
2205   else {
2206 //    cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
2207 //           << " NO DataReady ==> ThreadNo( 0 ) firsttoNode == NULL LINKEDnodesnumber " << linkednodesnumber << endl ;
2208     ThreadNo( 0 ) ;
2209   }
2210
2211 //  if ( linkednodesnumber == 0 && firsttoNode == NULL ) {
2212 //    cdebug << ThreadNo() << " Successed_SuccessAction " << Name() << " LinkedNodesSize " << LinkedNodesSize()
2213 //           << " firsttoNode == NULL LINKEDnodesnumber " << linkednodesnumber << " CHECK" << endl ;
2214 //    _OutNode->CheckAllDone() ;
2215 //  }
2216
2217 //  cdebug << pthread_self() << "/" << ThreadNo()
2218 //         << " <-- Successed_SuccessAction " << Name() << " linkednodesnumber "
2219 //         << linkednodesnumber << endl;
2220   return 1 ;
2221 }
2222
2223 bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
2224   bool RetVal = false ;
2225   if ( IsDataFlowNode() ) {
2226     cdebug << ThreadNo() << "InNode::SendSomeDataReady ----> " << Name()
2227          << " send Result to graph " << Name() << endl;
2228   }
2229   else {
2230 //    cdebug << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
2231 //           << " send SomeDataReady to " << Name() << " "
2232 //           << Automaton()->StateName( State() ) 
2233 //           << " CreateNewThreadIf() " << CreateNewThreadIf()
2234 //           << " LockedDataWait " << IsLockedDataWait() << endl;
2235 #if 0
2236   //cout << pthread_self() << "/" << ThreadNo() << " ----> " << FromNodeName
2237          << " send SomeDataReady to " << Name() << " "
2238          << Automaton()->StateName( State() ) 
2239          << " CreateNewThreadIf() " << CreateNewThreadIf()
2240          << " LockedDataWait " << IsLockedDataWait() << endl;
2241 #endif
2242     if ( State() == GraphExecutor::SuccessedState ||
2243          State() == GraphExecutor::SuspendedSuccessedState ||
2244          State() == GraphExecutor::SuspendedSuccessedToReStartState ) {
2245 //      cdebug << ThreadNo() << " " << FromNodeName
2246 //             << " : " << Name() << " " << Automaton()->StateName( State() )
2247 //             << " --> DataWaitingState for Thread "
2248 //             << ThreadNo() << " " << endl ;
2249       State( GraphExecutor::DataWaitingState ) ;
2250     }
2251 // We begin that LoopNode if SendSomeDataReady does not come from the corresponding EndLoopNode
2252     if ( IsLoopNode() && strcmp( LoopNode()->CoupledNodeName() , FromNodeName ) ) {
2253       cdebug << ThreadNo() << "InNode::SendSomeDataReady " << Name() << " Set _InitLoop from "
2254              << FromNodeName << endl ;
2255       _InitLoop = true ;
2256     }
2257     LockDataWait() ;
2258     DataFromNode( FromNodeName ) ;
2259     RetVal = !SendEvent( GraphExecutor::SomeDataReadyEvent );
2260     if ( !RetVal ) {
2261       UnLockDataWait() ;
2262     }
2263   }
2264   return RetVal ;
2265 }
2266
2267 int GraphExecutor::InNode::Errored_ErrorAction() {
2268   cdebug << ThreadNo() << " Errored_ErrorAction " << Name()
2269          << " will pthread_exit" << endl;
2270   DoneAction() ;
2271   return 1 ;
2272 }
2273
2274 int GraphExecutor::InNode::Successed_SuspendAction() {
2275   cdebug << ThreadNo() << " Successed_SuspendAction -->Suspend " << Name()
2276          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
2277          << _OutNode->SuspendedThreads() << endl;
2278   _OutNode->PushEvent( this , GraphExecutor::SuspendedSuccessedEvent ,
2279                        GraphExecutor::SuspendedSuccessedState ) ; 
2280   DoneAction() ;
2281   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
2282   cdebug << ThreadNo() << " Successed_SuspendAction Resumed " << Name() ;
2283   if ( aReStartNode ) {
2284     _aReStartNode = NULL ;
2285     cdebug << " for " << aReStartNode->Name() << endl;
2286     aReStartNode->SendEvent( _aReStartEvent ) ;
2287   }
2288   else {
2289     cdebug << endl;
2290     SendEvent( GraphExecutor::ResumeEvent ) ;
2291   }
2292   return 1 ;
2293 }
2294
2295 int GraphExecutor::InNode::Errored_SuspendAction() {
2296   cdebug << ThreadNo() << " Errored_SuspendAction -->Suspend " << Name()
2297          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
2298          << _OutNode->SuspendedThreads() << endl;
2299   _OutNode->PushEvent( this , GraphExecutor::SuspendedErroredEvent ,
2300                        GraphExecutor::SuspendedErroredState ) ; 
2301   DoneAction() ;
2302   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
2303   cdebug << ThreadNo() << " Errored_SuspendAction Resumed " << Name()
2304          << endl;
2305   if ( aReStartNode ) {
2306     _aReStartNode = NULL ;
2307     aReStartNode->SendEvent( _aReStartEvent ) ;
2308   }
2309   else {
2310     SendEvent( GraphExecutor::ResumeEvent ) ;
2311   }
2312   return 1 ;
2313 }
2314
2315 int GraphExecutor::InNode::SuspendedSuccessed_ResumeAction() {
2316   cdebug << ThreadNo() << " SuspendedSuccessed_ResumeAction " << Name() << endl;
2317 //  ResumeAction() ;
2318   _OutNode->PushEvent( this , GraphExecutor::ResumedSuccessedEvent ,
2319                        GraphExecutor::ResumedSuccessedState ) ; 
2320   SendEvent( ResumedSuccessedEvent ) ;
2321   return 1 ;
2322 }
2323
2324 int GraphExecutor::InNode::SuspendedErrored_ResumeAction() {
2325   cdebug << ThreadNo() << " SuspendedErrored_ResumeAction " << Name() << endl;
2326 //  ResumeAction() ;
2327   _OutNode->PushEvent( this , GraphExecutor::ResumedErroredEvent ,
2328                        GraphExecutor::ResumedErroredState ) ; 
2329   SendEvent( ResumedErroredEvent ) ;
2330   return 1 ;
2331 }
2332
2333 int GraphExecutor::InNode::Successed_KillAction() {
2334   KillAction() ;
2335   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
2336                        GraphExecutor::KilledSuccessedState ) ; 
2337   cdebug << ThreadNo() << " Successed_KillAction " << Name() << endl;
2338   return 1 ;
2339 }
2340
2341 int GraphExecutor::InNode::Errored_KillAction() {
2342   KillAction() ;
2343   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
2344                        GraphExecutor::KilledErroredState ) ; 
2345   cdebug << ThreadNo() << " Errored_KillAction " << Name() << endl;
2346   return 1 ;
2347 }
2348
2349 int GraphExecutor::InNode::Successed_StopAction() {
2350   StopAction() ;
2351   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
2352                        GraphExecutor::StoppedSuccessedState ) ; 
2353   cdebug << ThreadNo() << " Successed_StopAction " << Name() << endl;
2354   return 1 ;
2355 }
2356
2357 int GraphExecutor::InNode::Errored_StopAction() {
2358   StopAction() ;
2359   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
2360                        GraphExecutor::StoppedErroredState ) ; 
2361   cdebug << ThreadNo() << " Errored_StopAction " << Name() << endl;
2362   return 1 ;
2363 }
2364
2365 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAction() {
2366   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction " << Name() << endl;
2367   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
2368                        GraphExecutor::ReStartedState ) ;
2369   int i ;
2370   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
2371     GetChangeNodeInPort( i )->State( SUPERV::ReadyState ) ;
2372   }
2373   SendEvent( ExecuteEvent ) ;
2374   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction "  << Name() << endl;
2375   return 1 ;
2376 }
2377
2378 int GraphExecutor::InNode::SuspendedErrored_ReStartAction() {
2379   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction " << Name() << endl;
2380   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
2381                        GraphExecutor::ReStartedState ) ; 
2382   int i ;
2383   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
2384     GetChangeNodeInPort( i )->State( SUPERV::ReadyState ) ;
2385   }
2386   SendEvent( ExecuteEvent ) ;
2387   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction "  << Name() << endl;
2388   return 1 ;
2389 }
2390
2391 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAndSuspendAction() {
2392   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction " << Name()
2393          << endl;
2394   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
2395                        GraphExecutor::ReStartedState ) ; 
2396   State( GraphExecutor::DataWaitingState ) ;
2397   if ( !Suspend() ) {
2398     cdebug << "InNode::Suspend() Node " << Name() << endl ;
2399     return false ;
2400   }
2401   else if ( SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
2402     cdebug << "InNode::SendEvent( SomeDataReadyEvent ) Node "
2403            << Name() << endl ;
2404     return false ;
2405   }
2406   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction "  << Name()
2407          << endl;
2408   return 1 ;
2409 }
2410
2411 int GraphExecutor::InNode::SuspendedErrored_ReStartAndSuspendAction() {
2412   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction " << Name()
2413          << endl;
2414   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
2415                        GraphExecutor::ReStartedState ) ; 
2416   State( GraphExecutor::DataWaitingState ) ;
2417   if ( !Suspend() ) {
2418     cdebug << "InNode::Suspend() Node " << Name() << endl ;
2419     return false ;
2420   }
2421   else if ( SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
2422     cdebug << "InNode::SendEvent( SomeDataReadyEvent ) Node "
2423            << Name() << endl ;
2424     return false ;
2425   }
2426   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction "  << Name()
2427          << endl;
2428   return 1 ;
2429 }
2430
2431 void GraphExecutor::InNode::InParametersSet( bool & Err ,
2432                                              int  nInParams ,
2433                                              ServicesAnyData * InParametersList ) {
2434   int i ;
2435   cdebug << ThreadNo() << " InParametersSet " << Name() << endl ;
2436   for ( i = 0 ; i < nInParams ; i++ ) {
2437     ServicesAnyData D = InParametersList[i];
2438     GraphBase::InPort * anInPort = GetChangeNodeInPort(i) ;
2439     GraphBase::OutPort * theOutPort = anInPort->GetOutPort() ;
2440     if ( anInPort->IsGate() && theOutPort == NULL ) {
2441       cdebug << ThreadNo() << " ArgIn" << i << " " << D.Name << " "
2442              << anInPort->GetServicesParameter().Parametertype
2443              << " is inactive. " << anInPort->Kind() << endl ;
2444     }
2445     else if ( anInPort->State() == SUPERV::ReadyState ) {
2446       if ( anInPort->IsGate() ) {
2447         CORBA::Any * anAny = new CORBA::Any() ;
2448         *anAny <<= (long ) 0 ;
2449         theOutPort->Value( anAny ) ;
2450       }
2451       if ( !anInPort->IsDataStream() &&
2452            !anInPort->IsDataConnected() ) {
2453         anInPort->State( SUPERV::WaitingState ) ;
2454       }
2455       D.Name = CORBA::string_dup( anInPort->GetServicesParameter().Parametername ) ;
2456       cdebug << ThreadNo() << " ArgIn" << i << " " << anInPort->Kind()
2457              << " " << anInPort->State() ;
2458       cdebug << "      " << D.Name << " " << anInPort->GetServicesParameter().Parametertype << " : " ;
2459       D.Value = *theOutPort->Value() ; // CORBA::Any
2460       string _Type = CORBA::string_dup( anInPort->GetServicesParameter().Parametertype ) ;
2461       const char * Type = _Type.c_str() ;
2462       switch ( D.Value.type()->kind() ) { // { string , long , double , objref }
2463       case CORBA::tk_string:
2464         char * t;
2465         D.Value >>= t;
2466         cdebug << t << " (string)" ;
2467         if ( !strcmp( Type , "string" ) ) {
2468         }
2469         else if ( !strcmp( Type , "boolean" ) ) {
2470           bool b ;
2471           long d ;
2472           sscanf( t , "%ld" , &d ) ;
2473           b = (bool ) d ;
2474           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2475 //          theOutPort->Value( D.Value ) ;
2476         }
2477         else if ( !strcmp( Type , "char" ) ) {
2478           unsigned char c ;
2479           long d ;
2480           sscanf( t , "%ld" , &d ) ;
2481           c = (short ) d ;
2482           D.Value <<=  (CORBA::Any::from_char ) c ;
2483           cdebug << "string '" << t << "' --> " << d << " --> char " << c ;
2484 //          theOutPort->Value( D.Value ) ;
2485         }
2486         else if ( !strcmp( Type , "short" ) ) {
2487           short s ;
2488           long d ;
2489           sscanf( t , "%ld" , &d ) ;
2490           s = (short ) d ;
2491           D.Value <<=  s ;
2492           cdebug << "string '" << t << "' --> " << d << " --> short " << s ;
2493 //          theOutPort->Value( D.Value ) ;
2494         }
2495         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2496           long l ;
2497           sscanf( t , "%ld" , &l ) ;
2498           D.Value <<=  l ;
2499           cdebug << "string '" << t << " --> long " << l ;
2500 //          theOutPort->Value( D.Value ) ;
2501         }
2502         else if ( !strcmp( Type , "float" ) ) {
2503           double d ;
2504           sscanf( t , "%lf" , &d ) ;
2505           float f = d ;
2506           D.Value <<= f ;
2507           cdebug << "string '" << t << "' --> " << setw(25) << setprecision(18) << d << " --> float " << " = "
2508                  << setw(25) << setprecision(18) << f ;
2509 //          theOutPort->Value( D.Value ) ;
2510         }
2511         else if ( !strcmp( Type , "double" ) ) {
2512           double d ;
2513           sscanf( t , "%lf" , &d ) ;
2514           D.Value <<= d ;
2515           cdebug << "string '" << t << " --> double " << setw(25) << setprecision(18) << d ;
2516 //          theOutPort->Value( D.Value ) ;
2517         }
2518 //        else if ( !strcmp( Type , "objref" ) ) {
2519         else { // Default
2520           CORBA::Object_ptr ObjRef ;
2521           try {
2522             ObjRef = StringToObject( t ) ;
2523             D.Value <<= ObjRef ;
2524           }
2525           catch( ... ) {
2526             D.Value <<= CORBA::Object::_nil() ;
2527           }
2528 //          theOutPort->Value( D.Value ) ;
2529         }
2530 //        else {
2531 //          cdebug << " (other ERROR)" << endl ;
2532 //        }
2533         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2534         break;
2535       case CORBA::tk_long:
2536         long l;
2537         D.Value >>= l;
2538         cdebug << l << " (long)" << endl ;
2539         if ( !strcmp( Type , "string" ) ) {
2540           char t[40] ;
2541           sprintf( t , "%ld" , l ) ;
2542           D.Value <<= t ;
2543 //          theOutPort->Value( D.Value ) ;
2544         }
2545         else if ( !strcmp( Type , "boolean" ) ) {
2546           bool b ;
2547           b = (bool ) l ;
2548           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2549 //          theOutPort->Value( D.Value ) ;
2550         }
2551         else if ( !strcmp( Type , "char" ) ) {
2552           unsigned char c ;
2553           c = (unsigned char ) l ;
2554           D.Value <<=  (CORBA::Any::from_char ) c ;
2555 //          theOutPort->Value( D.Value ) ;
2556         }
2557         else if ( !strcmp( Type , "short" ) ) {
2558           short s ;
2559           s = (short ) l ;
2560           D.Value <<=  s ;
2561 //          theOutPort->Value( D.Value ) ;
2562         }
2563         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2564         }
2565         else if ( !strcmp( Type , "float" ) ) {
2566           float f ;
2567           f = (float ) l ;
2568           D.Value <<= f ;
2569 //          theOutPort->Value( D.Value ) ;
2570         }
2571         else if ( !strcmp( Type , "double" ) ) {
2572           double d ;
2573           d = (double ) l ;
2574           D.Value <<= d ;
2575 //          theOutPort->Value( D.Value ) ;
2576         }
2577 //        else if ( !strcmp( Type , "objref" ) ) {
2578         else { // Default
2579           D.Value <<= CORBA::Object::_nil() ;
2580 //          theOutPort->Value( D.Value ) ;
2581         }
2582 //        else {
2583 //          cdebug << " (other ERROR)" << endl ;
2584 //        }
2585         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2586         break;
2587       case CORBA::tk_double:
2588         double d;
2589         D.Value >>= d;
2590         cdebug << d << " (double)" << endl ;
2591         if ( !strcmp( Type , "string" ) ) {
2592           char t[40] ;
2593           sprintf( t , "%lf" , d ) ;
2594           D.Value <<= t ;
2595 //          theOutPort->Value( D.Value ) ;
2596         }
2597         else if ( !strcmp( Type , "boolean" ) ) {
2598           bool b ;
2599           b = (bool ) d ;
2600           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2601 //          theOutPort->Value( D.Value ) ;
2602         }
2603         else if ( !strcmp( Type , "char" ) ) {
2604           unsigned char c ;
2605           c = (unsigned char ) d ;
2606           D.Value <<=  (CORBA::Any::from_char ) c ;
2607 //          theOutPort->Value( D.Value ) ;
2608         }
2609         else if ( !strcmp( Type , "short" ) ) {
2610           short s ;
2611           s = (short ) d ;
2612           D.Value <<=  s ;
2613 //          theOutPort->Value( D.Value ) ;
2614         }
2615         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2616           long l ;
2617           l = (long ) d ;
2618           D.Value <<= l ;
2619 //          theOutPort->Value( D.Value ) ;
2620         }
2621         else if ( !strcmp( Type , "float" ) ) {
2622           float f ;
2623           f = (float ) d ;
2624           D.Value <<= f ;
2625 //          theOutPort->Value( D.Value ) ;
2626         }
2627         else if ( !strcmp( Type , "double" ) ) {
2628         }
2629 //        else if ( !strcmp( Type , "objref" ) ) {
2630         else { // Default
2631           D.Value <<= CORBA::Object::_nil() ;
2632 //          theOutPort->Value( D.Value ) ;
2633         }
2634 //        else {
2635 //          cdebug << " (other ERROR)" << endl ;
2636 //        }
2637         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2638         break;
2639       case CORBA::tk_objref:
2640         if ( !strcmp( Type , "string" ) ) {
2641           CORBA::Object_ptr ObjRef ;
2642           char * retstr ;
2643           try {
2644             D.Value >>= ObjRef ;
2645             retstr = ObjectToString( ObjRef ) ;
2646             D.Value <<= retstr ;
2647 //            theOutPort->Value( D.Value ) ;
2648           }
2649           catch( ... ) {
2650             if ( i != 0 ) {
2651               Err = true ;
2652             }
2653             cdebug << "ToString( object ) Catched ERROR" << endl ;
2654           }
2655         }
2656         else if ( !strcmp( Type , "boolean" ) ) {
2657           bool b = 0 ;
2658           D.Value <<=  (CORBA::Any::from_boolean ) b ;
2659 //          theOutPort->Value( D.Value ) ;
2660         }
2661         else if ( !strcmp( Type , "char" ) ) {
2662           unsigned char c = 0 ;
2663           D.Value <<=  (CORBA::Any::from_char ) c ;
2664 //          theOutPort->Value( D.Value ) ;
2665         }
2666         else if ( !strcmp( Type , "short" ) ) {
2667           short s = 0 ;
2668           D.Value <<=  s ;
2669 //          theOutPort->Value( D.Value ) ;
2670         }
2671         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2672           long l = 0 ;
2673           D.Value <<= l ;
2674 //          theOutPort->Value( D.Value ) ;
2675         }
2676         else if ( !strcmp( Type , "float" ) ) {
2677           float f = 0 ;
2678           D.Value <<= f ;
2679 //          theOutPort->Value( D.Value ) ;
2680         }
2681         else if ( !strcmp( Type , "double" ) ) {
2682           double d = 0 ;
2683           D.Value <<= d ;
2684 //          theOutPort->Value( D.Value ) ;
2685         }
2686 //        else if ( !strcmp( Type , "objref" ) ) {
2687         else { // Default
2688           CORBA::Object_ptr obj ;
2689           char * retstr ;
2690           try {
2691             D.Value >>= obj ;
2692             retstr = ObjectToString( obj ) ;
2693             cdebug << retstr << endl ;
2694           }
2695           catch( ... ) {
2696             if ( i != 0 ) {
2697               Err = true ;
2698             }
2699             cdebug << "ToString( object ) Catched ERROR" << endl ;
2700           }
2701         }
2702 //        else {
2703 //          cdebug << " (other ERROR)" << endl ;
2704 //        }
2705         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
2706         break;
2707       default:
2708         cdebug << " (other ERROR) " << D.Value.type()->kind() << endl ;
2709       }
2710     }
2711     else {
2712       cdebug << ThreadNo() << " In" << i << " : wrong state ERROR State "
2713              << anInPort->State() << " NameState "
2714              << Automaton()->StateName( anInPort->State() ) << " PortName "
2715              << anInPort->PortName() << " Parametername "
2716              << anInPort->GetServicesParameter().Parametername << endl ;
2717       Err = true ;
2718     }
2719     InParametersList[i] = D ;
2720   }
2721 }
2722
2723 void GraphExecutor::InNode::InOutParametersSet( int nOutParams ,
2724                                                 ServicesAnyData * OutParametersList ) {
2725   int i ;
2726   for ( i = 0 ; i < nOutParams ; i++ ) {
2727     ServicesAnyData D = OutParametersList[i] ;
2728
2729     D.Name = GetChangeNodeOutPort(i)->GetServicesParameter().Parametername;
2730     string _Type = CORBA::string_dup(GetChangeNodeOutPort(i)->GetServicesParameter().Parametertype) ;
2731     const char * Type = _Type.c_str() ;
2732     bool OutDone = GetChangeNodeOutPort(i)->Done() ;
2733     cdebug << ThreadNo() << " ArgOut" << i << " " << D.Name << " Done("
2734            << OutDone << ") " << Type << " : " << endl ;
2735     if ( !strcmp( Type , "string" ) ) {
2736       D.Value <<= (char *) NULL ;
2737     }
2738     else if ( !strcmp( Type , "boolean" ) ) {
2739       bool b = 0 ;
2740       D.Value <<=  (CORBA::Any::from_boolean ) b ;
2741     }
2742     else if ( !strcmp( Type , "char" ) ) {
2743       unsigned char c = 0 ;
2744       D.Value <<=  (CORBA::Any::from_char ) c ;
2745     }
2746     else if ( !strcmp( Type , "short" ) ) {
2747       short s = 0 ;
2748       D.Value <<=  s ;
2749     }
2750     else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
2751       D.Value <<= (long ) 0 ;
2752     }
2753     else if ( !strcmp( Type , "float" ) ) {
2754       float f = 0 ;
2755       D.Value <<= f ;
2756     }
2757     else if ( !strcmp( Type , "double" ) ) {
2758       double d = 0 ;
2759       D.Value <<= d ;
2760     }
2761     else {
2762       D.Value <<= CORBA::Object::_nil() ;
2763     }
2764 //#if 0
2765     switch (D.Value.type()->kind()) { // { string , long , double , objref }
2766     case CORBA::tk_string:
2767       char * t;
2768       D.Value >>= t;
2769       cdebug << ThreadNo() << " " << t << "(string)" << endl ;
2770       break;
2771     case CORBA::tk_boolean:
2772       bool b ;
2773       D.Value >>= (CORBA::Any::to_boolean ) b;
2774       cdebug << ThreadNo() << " " << b << "(boolean)" << endl ;
2775       break;
2776     case CORBA::tk_char:
2777       unsigned char c ;
2778       D.Value >>= (CORBA::Any::to_char ) c;
2779       cdebug << ThreadNo() << " " << c << "(char)" << endl ;
2780       break;
2781     case CORBA::tk_short:
2782       short s;
2783       D.Value >>= s;
2784       cdebug << ThreadNo() << " " << s << "(short)" << endl ;
2785       break;
2786     case CORBA::tk_long:
2787       long l;
2788       D.Value >>= l;
2789       cdebug << ThreadNo() << " " << l << "(long)" << endl ;
2790       break;
2791     case CORBA::tk_float:
2792       float f;
2793       D.Value >>= f;
2794       cdebug << ThreadNo() << " " << f << "(float)" << endl ;
2795       break;
2796     case CORBA::tk_double:
2797       double d;
2798       D.Value >>= d;
2799       cdebug << ThreadNo() << " " << d << "(double)" << endl ;
2800       break;
2801     case CORBA::tk_objref:
2802       try {
2803         CORBA::Object_ptr obj ;
2804         char * retstr ;
2805         D.Value >>= obj ;
2806         retstr = ObjectToString( obj ) ;
2807         cdebug << ThreadNo() << retstr << endl ;
2808       }
2809       catch( ... ) {
2810         cdebug << "ToString( object ) Catched ERROR" << endl ;
2811       }
2812       break;
2813     default:
2814       cdebug << ThreadNo() << " " << "(other ERROR)" << endl ;
2815     }
2816 //#endif
2817     OutParametersList[i] = D ;
2818   }
2819 }
2820
2821 bool GraphExecutor::InNode::OutParametersSet( bool Err ,
2822                                               SUPERV::GraphState NewState ,
2823                                               int nOutParams ,
2824                                               ServicesAnyData * OutParametersList ) {
2825   bool RetVal = true ;
2826   int i ;
2827   GraphBase::OutPort * aGateOutPort = NULL ;
2828   bool OrSwitch = false ;
2829   cdebug_in << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState "
2830             << NewState << endl ;
2831 //  cout << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState " << NewState << endl ;
2832   if ( nOutParams && !IsMacroNode() ) {
2833     GraphBase::OutPort * anOutPort ;
2834     for ( i = 0 ; i < nOutParams ; i++ ) {
2835       anOutPort = GetChangeNodeOutPort(i) ;
2836       if ( Err ) {
2837         anOutPort->State( NewState ) ;
2838         anOutPort->Done( true ) ;
2839       }
2840       else {
2841         cdebug << ThreadNo() << " " << "Out" << i << " " << Name() << " "
2842                << anOutPort->PortName() << " " << anOutPort->Kind() ;
2843         ServicesAnyData D = OutParametersList[i] ;
2844         switch (D.Value.type()->kind()) { // { string , long , double , objref }
2845         case CORBA::tk_string: {
2846           char * t;
2847           D.Value >>= t;
2848           cdebug << ThreadNo() << " " << t << "(string)" << endl ;
2849           break;
2850         }
2851         case CORBA::tk_boolean: {
2852           bool b ;
2853           D.Value >>= (CORBA::Any::to_boolean ) b;
2854           long l = (long ) b ;
2855           D.Value <<= l ;
2856           cdebug << ThreadNo() << " " << b << "(boolean)" << endl ;
2857           break;
2858         }
2859         case CORBA::tk_char: {
2860           unsigned char c ;
2861           D.Value >>= (CORBA::Any::to_char ) c;
2862           long l = (long ) c ;
2863           D.Value <<= l ;
2864           cdebug << ThreadNo() << " " << c << "(char)" << endl ;
2865           break;
2866         }
2867         case CORBA::tk_short: {
2868           short s;
2869           D.Value >>= s;
2870           long l = (long ) s ;
2871           D.Value <<= l ;
2872           cdebug << ThreadNo() << " " << s << "(short)" << endl ;
2873           break;
2874         }
2875         case CORBA::tk_long: {
2876           long l;
2877           D.Value >>= l;
2878           cdebug << ThreadNo() << " " << l << "(long)" << endl ;
2879           break;
2880         }
2881         case CORBA::tk_float: {
2882           float f;
2883           D.Value >>= f;
2884           double d = (double ) f ;
2885           D.Value <<= d ;
2886           cdebug << ThreadNo() << " " << f << "(float)" << endl ;
2887           break;
2888         }
2889         case CORBA::tk_double: {
2890           double d;
2891           D.Value >>= d;
2892           cdebug << ThreadNo() << " " << d << "(double)" << endl ;
2893           break;
2894         }
2895         case CORBA::tk_objref: {
2896           try {
2897             CORBA::Object_ptr obj ;
2898             char * retstr ;
2899             D.Value >>= obj ;
2900             retstr = ObjectToString( obj ) ;
2901             cdebug << ThreadNo() << retstr << endl ;
2902           }
2903           catch( ... ) {
2904             cdebug << "ToString( object ) Catched ERROR" << endl ;
2905           }
2906           break;
2907         }
2908         default: {
2909           cdebug << ThreadNo() << " " << "(other ERROR)" << endl ;
2910         }
2911         }
2912         OutParametersList[i] = D ;
2913         if ( !anOutPort->IsDataStream() ) {
2914           if ( anOutPort->IsGate() ) {
2915             aGateOutPort = anOutPort ;
2916             cdebug << " Gate " ;
2917             long l = 1;
2918             OutParametersList[i].Value <<= l;
2919             anOutPort->Value( OutParametersList[i].Value );
2920           }
2921           else if ( anOutPort->IsLoop() ) {
2922             cdebug << " Loop " ;
2923             anOutPort->Value( OutParametersList[i].Value );
2924 // InLoop Port of EndLoopNode is ready :
2925             anOutPort->ChangeInPorts(0)->State( SUPERV::ReadyState ) ;
2926           }
2927           else if ( anOutPort->IsSwitch() ) {
2928             cdebug << " Switch " ;
2929             anOutPort->Value( OutParametersList[i].Value );
2930             if ( anOutPort->InPortsSize() && anOutPort->ChangeInPorts( 0 )->IsGate() ) {
2931               if ( OrSwitch && anOutPort->BoolValue() ) {
2932                 cdebug << "GraphExecutor::InNodeThreads::OutParameters more than one switch is true ERROR"
2933                        << endl ;
2934                 RetVal = false ;
2935               }
2936               else {
2937                 OrSwitch = OrSwitch | anOutPort->BoolValue() ;
2938                 cdebug << "InNodeThreads::OutParameters OrSwitch = true" << endl ;
2939               }
2940             }
2941             cdebug << "OutParametersSet OrSwitch " << OrSwitch ;
2942           }
2943           else {
2944             cdebug << " Param " ;
2945             anOutPort->Value( OutParametersList[i].Value );
2946           }
2947           anOutPort->State( NewState ) ;
2948           anOutPort->Done( true ) ;
2949         }
2950         int j ;
2951         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
2952           bool fromGOTO = false ;
2953           const char * ToNodeName = anOutPort->ChangeInPorts( j )->NodeName() ;
2954           if ( !strcmp( ToNodeName , _OutNode->Graph()->Name() ) && _OutNode->Graph()->GraphMacroLevel() != 0 ) {
2955             cdebug << "OutParametersSet ToNodeName " << _OutNode->Graph()->Name() << " CoupledNode "
2956                    << _OutNode->Graph()->CoupledNodeName() << _OutNode->Graph()->CoupledNode()
2957                    << endl ;
2958             cdebug << " GraphExecutor " << _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor() << endl ;
2959             _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor()->OutputOfAny( _OutNode->Graph()->CoupledNodeName() ,
2960                                                                             anOutPort->ChangeInPorts( j )->PortName() ,
2961                                                                             *anOutPort->Value() ) ;
2962           }
2963           else {
2964             GraphBase::ComputingNode * ToNode = _OutNode->Graph()->GetChangeGraphNode( ToNodeName ) ;
2965             if ( ToNode ) {
2966 //              cout << "OutParametersSet ToNodeName " << ToNodeName << endl ;
2967               cdebug << "OutParametersSet ToNodeName " << ToNodeName << " " << ToNode->Name() << endl ;
2968               GraphBase::OutPort * aGOTOPort = ToNode->GetChangeNodeInGate()->GetOutPort() ;
2969               if ( aGOTOPort ) {
2970                 fromGOTO = aGOTOPort->IsGOTO() ;
2971               }
2972               if ( anOutPort->ChangeInPorts( j )->IsEndSwitch() || fromGOTO ) {
2973                 cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
2974                        << anOutPort->ChangeInPorts( j )->PortName() << ","
2975                        << anOutPort->ChangeInPorts( j )->Kind() << ") WILL BE changed from "
2976                        << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
2977                        << "("
2978                        << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
2979                        << ") to " << anOutPort->NodeName() << "("
2980                        << anOutPort->PortName() << ")" << endl ;
2981                 anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
2982               }
2983               else {
2984                 cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
2985                        << anOutPort->ChangeInPorts( j )->PortName() << ","
2986                        << anOutPort->ChangeInPorts( j )->Kind() << ") NOT changed from "
2987                        << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
2988                        << "("
2989                        << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
2990                        << ") to " << anOutPort->NodeName() << "("
2991                        << anOutPort->PortName() << ")" << endl ;
2992               }
2993             }
2994           }
2995         }
2996 //#if 0
2997         switch (anOutPort->Value()->type()->kind()) {
2998         case CORBA::tk_string:
2999           char * t;
3000           (*anOutPort->Value()) >>= t;
3001           cdebug << ThreadNo() << " Out" << i << " : " << t << "(string)" << endl ;
3002           break;
3003         case CORBA::tk_boolean:
3004           bool b ;
3005           (*anOutPort->Value()) >>= (CORBA::Any::to_boolean ) b;
3006           cdebug << ThreadNo() << " Out" << i << " : " << b << "(boolean)" << endl ;
3007           break;
3008         case CORBA::tk_char:
3009           unsigned char c ;
3010           (*anOutPort->Value()) >>= (CORBA::Any::to_char ) c;
3011           cdebug << ThreadNo() << " Out" << i << " : " << c << "(char)" << endl ;
3012           break;
3013         case CORBA::tk_short:
3014           short s;
3015           (*anOutPort->Value()) >>= s;
3016           cdebug << ThreadNo() << " Out" << i << " : " << s << "(short)" << endl ;
3017           break;
3018         case CORBA::tk_long:
3019           long l;
3020           (*anOutPort->Value()) >>= l;
3021           cdebug << ThreadNo() << " Out" << i << " : " << l << "(long)" << endl ;
3022           break;
3023         case CORBA::tk_float:
3024           float f;
3025           (*anOutPort->Value()) >>= f;
3026           cdebug << ThreadNo() << " Out" << i << " : " << f << "(float)" << endl ;
3027           break;
3028         case CORBA::tk_double:
3029           double d;
3030           (*anOutPort->Value()) >>= d;
3031           cdebug << ThreadNo() << " Out" << i << " : " << d << "(double)" << endl ;
3032           break;
3033         case CORBA::tk_objref:
3034           CORBA::Object_ptr obj ;
3035           char * retstr ;
3036           try {
3037             (*anOutPort->Value()) >>= obj ;
3038             retstr = ObjectToString( obj );
3039             cdebug << ThreadNo() << " Out" << i << " : " << "ToString( object ) "
3040                    << retstr << endl ;
3041           }
3042           catch ( ... ) {
3043             cdebug << ThreadNo() << " Out" << i << " : " << "ToString( object ) "
3044                    << "Catched ERROR" << endl ;
3045           }
3046           break;
3047         default:
3048           cdebug << ThreadNo() << " Out" << i << " : " << "(other ERROR)" << endl ;
3049           RetVal = false ;
3050         }
3051 //#endif
3052       }
3053     }
3054     if ( aGateOutPort && IsSwitchNode() ) {
3055       if ( OrSwitch ) {
3056         cdebug << ThreadNo() << " " << "Out0 " << Name() << " Close of "
3057                << aGateOutPort->PortName() << " " << aGateOutPort->Kind() ;
3058         long l = 0;
3059         OutParametersList[0].Value <<= l ;
3060         aGateOutPort->Value( OutParametersList[0].Value ) ;
3061       }
3062       else {
3063         cdebug << ThreadNo() << " " << "Out0 " << Name() << " Open of "
3064                << aGateOutPort->PortName() << " " << aGateOutPort->Kind() ;
3065         long l = 1;
3066         OutParametersList[0].Value <<= l ;
3067         aGateOutPort->Value( OutParametersList[0].Value ) ;
3068         int i ;
3069         for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
3070           GraphBase::InPort * anInPort ;
3071           anInPort = CoupledNode()->GetChangeInPort( GetNodeOutPort( i )->PortName() ) ;
3072           if ( anInPort ) {
3073             anInPort->ChangeOutPort( GetChangeNodeOutPort( i ) ) ;
3074           }
3075         }
3076       }
3077     }
3078   }
3079   cdebug_out << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewState "
3080              << NewState << " RetVal " << RetVal << endl ;
3081   return RetVal ;
3082 }