Salome HOME
8befd46338cac854ffcd303a1da80288b22da16e
[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 #define SendEventTrace 1
74 int GraphExecutor::InNode::SendEvent( const GraphExecutor::NodeEvent anEvent ) {  
75
76   _CurrentEvent = (GraphExecutor::NodeEvent ) anEvent ;
77 #if SendEventTrace
78   cdebug_in << pthread_self() << "/" << ThreadNo() << " SendEvent Graph " << _OutNode->Name()
79             << " Node " << Name() << " Event : " << Automaton()->EventName( anEvent )
80             << " State : " << Automaton()->StateName( State() ) << " _RewindStack " << _RewindStack
81             << " ControlState : " << Automaton()->ControlStateName( ControlState() )
82             << endl;
83 #endif
84
85   _OldState = State() ;
86   _NextState = Automaton()->NextState( _OldState , anEvent ) ;
87   if ( _NextState == _OldState ) {
88     cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
89            << " GraphExecutor::InNodeThreads::SendEvent SameStates ERROR _OldState/_NextState "
90            << _OldState << " Event " << Automaton()->EventName( anEvent ) << endl ;
91     _NextAction = GraphExecutor::VoidAction ;
92     return 0 ;
93   }
94   else {
95     _NextAction = Automaton()->NextAction( _NextState , anEvent ) ;
96   }
97 #if SendEventTrace
98   cdebug << pthread_self() << "/" << ThreadNo() << "NextState( " << _OldState << " , "
99          << Automaton()->EventName( anEvent ) << " ) --> _NextState = " << _NextState
100          << " NextAction( " << _NextState << " , " << Automaton()->EventName( anEvent )
101          << " ) --> _NextAction = "
102          << Automaton()->ActionName( _NextAction ) << endl ;
103 #endif
104
105 //  State( _NextState ) ;
106 //  if ( _OldState == GraphExecutor::SuccessedExecutingState ||
107 //       _OldState == GraphExecutor::ErroredExecutingState ) {
108 //    DoneAction() ;
109 //  }
110
111 #if SendEventTrace
112   cdebug << pthread_self() << "/" << ThreadNo() << " SendedEvent Node "
113          << Name() << 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          << " _RewindStack " << _RewindStack  << endl ;
121 #endif
122
123   int sts = true ;
124 #if ExitWhenNodeAborted
125   if ( _OutNode->IsNodeAborted() ) {
126 #if SendEventTrace
127     cdebug << pthread_self() << "/" << ThreadNo() << " SendedEvent Node " << Name()
128            << " will exit : a node was aborted ..." << endl ;
129 #endif
130   }
131   else {
132     sts = executeAction() ;
133   }
134 #else
135   sts = executeAction() ;
136 #endif
137   
138 #if SendEventTrace
139   cdebug_out << pthread_self() << "/" << ThreadNo() << " <--- SendEvent Node " << Name() 
140              << " Event : " << Automaton()->EventName( anEvent )
141              << " State : " << Automaton()->StateName( State() )
142              << endl;
143 #endif
144
145   return sts ;
146
147 }
148
149 #define ActionsTrace 1
150 // ReadyAction - RunningAction - DoneAction - SuspendedAction :
151 // for StateWait( ReadyW - RunningW - DoneW - SuspendedW )
152 void GraphExecutor::InNode::ReadyAction() {
153   if ( pthread_mutex_lock( &_MutexWait ) ) {
154     perror("Ready pthread_mutex_lock ") ;
155     exit( 0 ) ;
156   }
157 #if ActionsTrace
158   cdebug << pthread_self() << "/" << ThreadNo()
159          << "ReadyAction pthread_cond_broadcast _ReadyWait "
160          << Name() << endl ;
161 #endif
162   if ( pthread_cond_broadcast( &_ReadyWait ) ) {
163     perror("Ready pthread_cond_broadcast ") ;
164   }
165   if ( pthread_mutex_unlock( &_MutexWait ) ) {
166     perror("Ready pthread_mutex_unlock ") ;
167     exit( 0 ) ;
168   }
169 }
170
171 void GraphExecutor::InNode::RunningAction() {
172   if ( pthread_mutex_lock( &_MutexWait ) ) {
173     perror("Running pthread_mutex_lock ") ;
174     exit( 0 ) ;
175   }
176 #if ActionsTrace
177   cdebug << pthread_self() << "/" << ThreadNo()
178          << "RunningAction pthread_cond_broadcast _RunningWait "
179          << Name() << endl ;
180 #endif
181 // That activate the pthread_cond_wait for RunninWait
182   if ( pthread_cond_broadcast( &_RunningWait ) ) {
183     perror("Running pthread_cond_broadcast ") ;
184   }
185   if ( pthread_mutex_unlock( &_MutexWait ) ) {
186     perror("Running pthread_mutex_unlock ") ;
187     exit( 0 ) ;
188   }
189 }
190
191 void GraphExecutor::InNode::DoneAction() {
192   if ( pthread_mutex_lock( &_MutexWait ) ) {
193     perror("Done pthread_mutex_lock ") ;
194     exit( 0 ) ;
195   }
196 #if ActionsTrace
197   cdebug << pthread_self() << "/" << ThreadNo()
198          << "DoneAction pthread_cond_broadcast _DoneWait "
199          << Name() << endl ;
200 #endif
201   if ( pthread_cond_broadcast( &_DoneWait ) ) {
202     perror("Done pthread_cond_broadcast ") ;
203   }
204   if ( pthread_mutex_unlock( &_MutexWait ) ) {
205     perror("Done pthread_mutex_unlock ") ;
206     exit( 0 ) ;
207   }
208 }
209
210 void GraphExecutor::InNode::SuspendedAction() {
211   if ( pthread_mutex_lock( &_MutexWait ) ) {
212     perror("Suspended pthread_mutex_lock ") ;
213     exit( 0 ) ;
214   }
215 #if ActionsTrace
216   cdebug << pthread_self() << "/" << ThreadNo()
217          << "SuspendedAction pthread_cond_broadcast _SuspendedWait "
218          << Name() << endl ;
219 #endif
220   if ( pthread_cond_broadcast( &_SuspendedWait ) ) {
221     perror("Suspended pthread_cond_broadcast ") ;
222   }
223   if ( pthread_mutex_unlock( &_MutexWait ) ) {
224     perror("Suspended pthread_mutex_unlock ") ;
225     exit( 0 ) ;
226   }
227 }
228
229 // SuspendAction <--> { ResumeAction - ReStartAction }
230 GraphExecutor::InNode * GraphExecutor::InNode::SuspendAction() {
231   SuspendedAction() ;
232   if ( pthread_mutex_lock( &_MutexWait ) ) {
233     perror("Suspend pthread_mutex_lock ") ;
234     exit( 0 ) ;
235   }
236   if ( !_SuspendSync ) {
237     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
238            << " SuspendAction pthread_cond_wait _SuspendWait "
239            << Automaton()->StateName( State() ) << endl ;
240     _SuspendSync = true ;
241     _OutNode->SuspendThread() ;
242     if ( pthread_cond_wait( &_SuspendWait , &_MutexWait ) ) {
243       perror("SuspendAction pthread_cond_wait ") ;
244     }
245     _OutNode->ResumeThread() ;
246 #if ActionsTrace
247     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
248            << " SuspendAction pthread_cond_waited"  
249            << Automaton()->StateName( State() ) << endl ;
250 #endif
251   }
252   else {
253 #if ActionsTrace
254     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
255            << " NO SuspendAction pthread_cond_wait"  
256            << Automaton()->StateName( State() ) << endl ;
257 #endif
258   }
259 //  SendEvent( _aResumeEvent ) ; ===> Mutex with myself !
260   _SuspendSync = false ;  
261   if ( ControlState() == SUPERV::ToSuspendStartState ||
262        ControlState() == SUPERV::ToSuspendState ) {
263     ControlState( SUPERV::VoidState ) ;
264   }
265   if ( pthread_mutex_unlock( &_MutexWait ) ) {
266     perror("SuspendAction pthread_mutex_unlock ") ;
267     exit( 0 ) ;
268   }
269
270   SendEvent( _aResumeEvent ) ;
271 //  if ( ControlState() == SUPERV::ToSuspendStartState ) {
272 //    ControlState( SUPERV::VoidState ) ;
273 //  }
274
275   if ( pthread_mutex_lock( &_MutexWait ) ) {
276     perror("SuspendAction pthread_mutex_lock ") ;
277     exit( 0 ) ;
278   }
279   if ( _ResumeSync ) {
280 #if ActionsTrace
281     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
282            << " SuspendAction pthread_cond_signal _ResumeWait" << endl ;
283 #endif
284     if ( pthread_cond_signal( &_ResumeWait ) ) {
285       perror("SuspendAction pthread_cond_signal _ResumeWait ") ;
286     }
287 #if ActionsTrace
288     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
289            << " SuspendAction pthread_cond_signaled _ResumeWait " << endl ;
290 #endif
291   }
292   else {
293 #if ActionsTrace
294     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
295            << " NO SuspendAction pthread_cond_signal _ResumeWait" << endl ;
296 #endif
297     _ResumeSync = true ;  
298   }
299   if ( pthread_mutex_unlock( &_MutexWait ) ) {
300     perror("SuspendAction pthread_mutex_unlock ") ;
301     exit( 0 ) ;
302   }
303   if ( _aReStartNode ) {
304     cdebug << Name() << " " << Automaton()->StateName( State() )
305            << "aReStartNode : " << _aReStartNode->Name() << " "
306            << Automaton()->StateName( _aReStartNode->State() ) << endl ;
307     _aReStartNode->SendEvent( _aResumeEvent ) ;
308   }
309   else {
310     cdebug << "NO aReStartNode" 
311            << Automaton()->StateName( State() ) << endl ;
312   }
313   return _aReStartNode ;
314 }
315
316 bool GraphExecutor::InNode::ResumeAction( GraphExecutor::NodeEvent aResumeEvent ) {
317   bool RetVal ;
318   if ( pthread_mutex_lock( &_MutexWait ) ) {
319     perror("ResumeAction pthread_mutex_lock ") ;
320     exit( 0 ) ;
321   }
322   _aResumeEvent = aResumeEvent ;
323   if ( _SuspendSync ) {
324 #if ActionsTrace
325     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
326            << " ResumeAction pthread_cond_signal" << endl ;
327 #endif
328     if ( pthread_cond_signal( &_SuspendWait ) ) {
329       perror("ResumeAction pthread_cond_signal ") ;
330     }
331 #if ActionsTrace
332     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
333            << " ResumeAction pthread_cond_signaled _SuspendWait " << endl ;
334 #endif
335     RetVal = true ;
336   }
337   else {
338 #if ActionsTrace
339     cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond " << Name()
340            << " NO ResumeAction pthread_cond_signal" << endl ;
341 #endif
342     if ( pthread_self() == ThreadNo() ) {
343       RetVal = false ; /*/ Ne pas s'attendre soi-meme !...*/
344     }
345     else {
346       _SuspendSync = true ;
347       RetVal = true ; // Il faut tout de meme attendre ci-apres ...
348     }
349   }
350   if ( pthread_mutex_unlock( &_MutexWait ) ) {
351     perror("ResumeAction pthread_mutex_unlock ") ;
352     exit( 0 ) ;
353   }
354
355   if ( RetVal ) {
356     if ( pthread_mutex_lock( &_MutexWait ) ) {
357       perror("ResumeAction pthread_mutex_lock ") ;
358       exit( 0 ) ;
359     }
360     if ( !_ResumeSync ) {
361 #if ActionsTrace
362       cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond "
363              << Name() << " ResumeAction pthread_cond_wait _ResumeWait " 
364              << Automaton()->StateName( State() ) << endl ;
365 #endif
366       _ResumeSync = true ;
367       if ( pthread_cond_wait( &_ResumeWait , &_MutexWait ) ) {
368         perror("ResumeAction pthread_cond_wait ") ;
369       }
370 #if ActionsTrace
371       cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond "
372              << Name() << " ResumeAction pthread_cond_waited _ResumeWait"  
373              << Automaton()->StateName( State() ) << endl ;
374 #endif
375       RetVal = true ;
376     }
377     else {
378 #if ActionsTrace
379       cdebug << pthread_self() << "/" << ThreadNo() << " pthread_cond "
380              << Name() << " NO ResumeAction pthread_cond_wait _ResumeWait" 
381              << Automaton()->StateName( State() ) << endl ;
382 #endif
383       RetVal = false ;
384     }
385     _ResumeSync = false ;  
386     if ( pthread_mutex_unlock( &_MutexWait ) ) {
387       perror("ResumeAction pthread_mutex_unlock ") ;
388       exit( 0 ) ;
389     }
390   }
391 #if ActionsTrace
392   cdebug << pthread_self() << "/" << ThreadNo()
393          << "GraphExecutor::InNodeThreads::ResumeAction RetVal " << RetVal << endl ;
394 #endif
395   return RetVal ;
396 }
397
398 bool GraphExecutor::InNode::ReStartAction( GraphExecutor::InNode * aReStartNode ,
399                                            GraphExecutor::NodeEvent anEvent ) {
400   GraphExecutor::InNode * oldReStartNode = _aReStartNode ;
401   _aReStartNode = aReStartNode ;
402   _aReStartEvent = anEvent ;
403   cdebug << pthread_self() << "/" << ThreadNo()
404           << " GraphExecutor::InNodeThreads::ReStartAction from "
405          << Name() << " " << Automaton()->StateName( State() ) << " to "
406          << aReStartNode->ThreadNo() << " " << aReStartNode->Name() << " "
407          << Automaton()->StateName( aReStartNode->State() ) ;
408   if ( oldReStartNode ) {
409     cdebug << " oldReStartNode " << oldReStartNode->Name() << endl ;
410   }
411   else {
412     cdebug << endl ;
413   }
414   return ResumeAction( GraphExecutor::ToReStartEvent ) ;
415 }
416
417 void GraphExecutor::InNode::KilledAction() {
418   if ( pthread_mutex_lock( &_MutexWait ) ) {
419     perror("Killed pthread_mutex_lock ") ;
420     exit( 0 ) ;
421   }
422   if ( !_KillSync ) {
423     cdebug << "pthread_cond " << Name() << " Killed pthread_cond_wait"
424            << endl ;
425     _KillSync = true ;
426     if ( pthread_cond_wait( &_KillWait , &_MutexWait ) ) {
427       perror("Killed pthread_cond_wait ") ;
428     }
429     cdebug << "pthread_cond " << Name() << " Killed pthread_cond_waited"
430            << endl ;
431   }
432   else {
433     cdebug << "pthread_cond " << Name() << " NO Killed pthread_cond_wait"
434            << endl ;
435   }
436   _KillSync = false ;  
437   if ( pthread_mutex_unlock( &_MutexWait ) ) {
438     perror("Killed pthread_mutex_unlock ") ;
439     exit( 0 ) ;
440   }
441 }
442
443 void GraphExecutor::InNode::KillAction() {
444   if ( pthread_mutex_lock( &_MutexWait ) ) {
445     perror("Kill pthread_mutex_lock ") ;
446     exit( 0 ) ;
447   }
448   if ( _KillSync ) {
449     cdebug << "pthread_cond " << Name() << " Kill pthread_cond_signal"
450            << endl ;
451 //    if ( pthread_cond_broadcast( &_KillWait ) ) {
452     if ( pthread_cond_signal( &_KillWait ) ) {
453       perror("Kill pthread_cond_broadcast ") ;
454     }
455     cdebug << "pthread_cond " << Name() << " Kill pthread_cond_signaled"
456            << endl ;
457   }
458   else {
459     cdebug << "pthread_cond " << Name() << " NO Kill pthread_cond_signal"
460            << endl ;
461     _KillSync = true ;  
462   }
463   if ( pthread_mutex_unlock( &_MutexWait ) ) {
464     perror("Kill pthread_mutex_unlock ") ;
465     exit( 0 ) ;
466   }
467 }
468
469 void GraphExecutor::InNode::StoppedAction() {
470   if ( pthread_mutex_lock( &_MutexWait ) ) {
471     perror("Stopped pthread_mutex_lock ") ;
472     exit( 0 ) ;
473   }
474   if ( pthread_cond_wait( &_StopWait , &_MutexWait ) ) {
475     perror("Stopped pthread_cond_wait ") ;
476   }
477   if ( pthread_mutex_unlock( &_MutexWait ) ) {
478     perror("Stopped pthread_mutex_unlock ") ;
479     exit( 0 ) ;
480   }
481 }
482
483 void GraphExecutor::InNode::StopAction() {
484   if ( pthread_mutex_lock( &_MutexWait ) ) {
485     perror("Stop pthread_mutex_lock ") ;
486     exit( 0 ) ;
487   }
488   if ( pthread_cond_broadcast( &_StopWait ) ) {
489     perror("Stop pthread_cond_broadcast ") ;
490   }
491   if ( pthread_mutex_unlock( &_MutexWait ) ) {
492     perror("Stop pthread_mutex_unlock ") ;
493     exit( 0 ) ;
494   }
495 }
496
497 void GraphExecutor::InNode::ThreadStartedAction() {
498   if ( pthread_mutex_lock( &_MutexWait ) ) {
499     perror("ThreadStarted pthread_mutex_lock ") ;
500     exit( 0 ) ;
501   }
502   if ( !_ThreadStartedSync ) {
503 #if ActionsTrace
504     cdebug << pthread_self() << "/" << ThreadNo()
505            << "pthread_cond " << Name() << " ThreadStarted pthread_cond_wait"
506            << endl ;
507 #endif
508     _ThreadStartedSync = true ;
509     if ( pthread_cond_wait( &_ThreadStartedWait , &_MutexWait ) ) {
510       perror("ThreadStarted pthread_cond_wait ") ;
511     }
512 #if ActionsTrace
513     cdebug << pthread_self() << "/" << ThreadNo()
514            << "pthread_cond " << Name() << " ThreadStarted pthread_cond_waited"
515            << endl ;
516 #endif
517   }
518   else {
519 #if ActionsTrace
520     cdebug << pthread_self() << "/" << ThreadNo()
521            << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_wait"
522            << endl ;
523 #endif
524 //Debug :
525     _ThreadStartedSync = false ;  
526     if ( pthread_cond_signal( &_ThreadStartedWait ) ) {
527       perror("ThreadStart pthread_cond_signal ") ;
528     }
529 //Debug
530 #if ActionsTrace
531     cdebug << pthread_self() << "/" << ThreadNo()
532            << "pthread_cond " << Name() << " NO ThreadStarted pthread_cond_signaled"
533            << endl ;
534 #endif
535   }
536   if ( pthread_mutex_unlock( &_MutexWait ) ) {
537     perror("ThreadStarted pthread_mutex_unlock ") ;
538     exit( 0 ) ;
539   }
540 }
541
542 void GraphExecutor::InNode::ThreadStartAction() {
543   if ( pthread_mutex_lock( &_MutexWait ) ) {
544     perror("ThreadStart pthread_mutex_lock ") ;
545     exit( 0 ) ;
546   }
547   if ( _ThreadStartedSync ) {
548 #if ActionsTrace
549     cdebug << pthread_self() << "/" << ThreadNo()
550            << "pthread_cond " << Name() << " ThreadStart pthread_cond_signal"
551            << endl ;
552 #endif
553     _ThreadStartedSync = false ;  
554     if ( pthread_cond_signal( &_ThreadStartedWait ) ) {
555       perror("ThreadStart pthread_cond_broadcast ") ;
556     }
557 #if ActionsTrace
558     cdebug << pthread_self() << "/" << ThreadNo()
559            << "pthread_cond " << Name() << " ThreadStart pthread_cond_signaled"
560            << endl ;
561 #endif
562   }
563   else {
564 #if ActionsTrace
565     cdebug << pthread_self() << "/" << ThreadNo()
566            << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_signal"
567            << endl ;
568 #endif
569     _ThreadStartedSync = true ;
570 //Debug :
571     if ( pthread_cond_wait( &_ThreadStartedWait , &_MutexWait ) ) {
572       perror("ThreadStarted pthread_cond_wait ") ;
573     }
574 //Debug
575 #if ActionsTrace
576     cdebug << pthread_self() << "/" << ThreadNo()
577            << "pthread_cond " << Name() << " NO ThreadStart pthread_cond_waited"
578            << endl ;
579 #endif
580   }
581   if ( pthread_mutex_unlock( &_MutexWait ) ) {
582     perror("ThreadStart pthread_mutex_unlock ") ;
583     exit( 0 ) ;
584   }
585 }
586
587 int GraphExecutor::InNode::executeAction() {
588   int oldRewindStack = ( _RewindStack > MAXSTACKTHREADSIZE ) ;
589   if ( !CreateNewThread() && oldRewindStack ) {
590 #if ActionsTrace
591     cdebug << pthread_self() << "/" << ThreadNo()
592            << " executeAction start Thread _RewindStack " << _RewindStack << " > "
593            << MAXSTACKTHREADSIZE << " CreateNewThread "
594            << CreateNewThread() << " " << Automaton()->ActionName( _NextAction ) << "("
595            << Name() << ")" << endl;
596 #endif
597     CreateNewThread( true ) ;
598     _OutNode->IncrCreatedThreads() ;
599     ThreadNo( 0 ) ;
600   }
601   if ( CreateNewThread() ) {
602     CreateNewThread( false ) ;
603 //JR 15.04.2005 Debug PAL8624 RetroConception :
604 //    if ( ThreadNo() == 0 ) {
605       _RewindStack = 1 ;
606 #if ActionsTrace
607       cdebug << pthread_self() << "/" << ThreadNo()
608              << " executeAction start Thread _RewindStack " << _RewindStack << " "
609              << Automaton()->ActionName( _NextAction ) << "(" << Name() << ")"
610              << endl;
611 #endif
612       pthread_t T;
613       int pthread_sts = 1 ;
614 //      _OutNode->PushEvent( NULL , GraphExecutor::NewThreadEvent ,
615 //                           GraphExecutor::ExecutingState ) ; 
616       while ( (pthread_sts = pthread_create(&T, NULL, run_function, this )) ) {
617         char * msg = "Cannot pthread_create " ;
618         perror( msg ) ;
619         cdebug << ThreadNo() << " " << msg << " --> sleep(5)" << endl ;
620         cdebug << ThreadNo() << " PTHREAD_THREADS_MAX : "
621                << PTHREAD_THREADS_MAX << " pthread_create status : " ;
622         if ( pthread_sts == EAGAIN ) {
623           cdebug << "EAGAIN(" << pthread_sts << ")" << endl ;
624           cdebug << _OutNode->CreatedThreads() << " was created (and exited)" << endl ;
625           cdebug << "It seems to me that with gdb we are limited to 256 threads" << endl ;
626         }
627         else {
628           cdebug << pthread_sts << endl ;
629         }
630         string smsg = msg ;
631         delete [] msg ;
632         pthread_exit( msg ) ;
633       }
634 #if ActionsTrace
635       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
636              << " executeAction has created thread " << T << endl ;
637 #endif
638       ThreadStartedAction() ;
639 #if ActionsTrace
640       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
641              << "executeAction the thread " << T << " has called NewThread and will call ExecuteAction for node "
642              << Name() << endl ;
643 #endif
644     }
645 //JR 15.04.2005 Debug PAL8624 RetroConception :
646 #if 0
647     else {
648 #if ActionsTrace
649       cdebug << pthread_self() << "/" << ThreadNo()
650              << " executeAction restart Thread _RewindStack " << _RewindStack << " "
651              << Automaton()->StateName( State() ) << " "
652              << Automaton()->ActionName( _NextAction ) << "(" << Name()
653              << ") ReStartAction ==>" << endl;
654 #endif
655       State( GraphExecutor::SuspendedSuccessedState ) ;
656       if ( !ReStartAction( this , GraphExecutor::ReStartEvent ) ) {
657         cdebug << pthread_self() << "/" << ThreadNo()
658                << " executeAction STATE & CALLED "
659                << Automaton()->ActionName( _NextAction ) << "(" << Name()
660                << ") ERROR-DEBUG " << endl;
661       }
662       else {
663 #if ActionsTrace
664         cdebug << pthread_self() << "/" << ThreadNo() << " executeAction NO CALL "
665                << Automaton()->ActionName( _NextAction ) << "(" << Name()
666                << ")" << endl;
667 #endif
668       }
669     }
670   }
671 #endif
672   else {
673     if ( _CurrentEvent == ExecuteEvent ) {
674       _RewindStack += 1 ;
675     }
676 #if ActionsTrace
677     cdebug << pthread_self() << "/" << ThreadNo() << " executeAction call "
678            << Automaton()->ActionName( _NextAction ) << "(" << Name() << ") _RewindStack " << _RewindStack
679            << endl;
680 #endif
681     return ExecuteAction() ;
682   }
683   return 1 ;
684 }
685
686 void GraphExecutor::InNode::coutbegin() {
687 #if ActionsTrace
688   cdebug << pthread_self() << "/" << ThreadNo() << " run_function begin"
689          << " " << Name() << " " << Automaton()->StateName( State() ) << endl ;
690 #endif
691 }
692 void GraphExecutor::InNode::coutexit() {
693 #if ActionsTrace
694   cdebug << pthread_self() << "/" << ThreadNo() << " run_function pthread_exit _RewindStack " << _RewindStack
695          << " " << Name() << " " << Automaton()->StateName( State() ) << endl ;
696 #endif
697 }
698 void * run_function(void *p) {
699   GraphExecutor::InNode *aNode = (GraphExecutor::InNode *) p;
700   aNode->coutbegin() ;
701   aNode->NewThread( pthread_self() ) ;
702   if ( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS , NULL ) ) {
703     perror("pthread_setcanceltype ") ;
704     exit(0) ;
705   }
706   if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , NULL ) ) {
707     perror("pthread_setcancelstate ") ;
708     exit(0) ;
709   }
710   aNode->ThreadStartAction() ;
711 //  cout << "run_function " << aNode->Name() << "->ExecuteAction() Coupled : " << aNode->CoupledNode()
712 //       << endl ;
713   aNode->ExecuteAction() ;
714   char * msg = new char[40] ;
715   sprintf( msg , "%d" , (int ) aNode->ThreadNo() ) ;
716   strcat( msg , " thread exit" ) ;
717   aNode->coutexit() ;
718   aNode->ExitThread() ;
719   string smsg = msg ;
720   delete [] msg ;
721   pthread_exit( (void * ) smsg.c_str() ) ;
722   return msg ;
723 }
724
725 int GraphExecutor::InNode::ExecuteAction() {
726   int sts ;
727
728 #if ActionsTrace
729   const char * nextactionname = Automaton()->ActionName( _NextAction ) ;
730   const char * statename = Automaton()->StateName( State() ) ;
731   const char * nextstatename = Automaton()->StateName( _NextState ) ;
732   cdebug_in << pthread_self() << "/" << ThreadNo() << " " << Name() << " --> ExecuteAction "
733             << nextactionname << " "  << statename << " NextState "
734             << nextstatename << endl ;
735 #endif
736
737   State( _NextState ) ;
738   switch ( _NextAction ) {
739   case GraphExecutor::ErrorAction : {
740     sts = ErrorAction() ;
741     break ;
742   }
743   case GraphExecutor::VoidAction : {
744     sts = VoidAction() ;
745     break ;
746   }
747   case GraphExecutor::DataWaiting_SomeDataReadyAction : {
748     sts = DataWaiting_SomeDataReadyAction() ;
749     break ;
750   }
751   case GraphExecutor::DataUndef_NotAllDataReadyAction : {
752     sts = DataUndef_NotAllDataReadyAction() ;
753     break ;
754   }
755   case GraphExecutor::DataUndef_AllDataReadyAction : {
756     sts = DataUndef_AllDataReadyAction() ;
757     break ;
758   }
759   case GraphExecutor::DataReady_SuspendAction : {
760     sts = DataReady_SuspendAction() ;
761     break ;
762   }
763   case GraphExecutor::SuspendedReady_ResumeAction : {
764     sts = SuspendedReady_ResumeAction() ;
765     break ;
766   }
767   case GraphExecutor::DataReady_KillAction : {
768     sts = DataReady_KillAction() ;
769     break ;
770   }
771   case GraphExecutor::DataReady_StopAction : {
772     sts = DataReady_StopAction() ;
773     break ;
774   }
775   case GraphExecutor::DataReady_ExecuteAction : {
776     sts = DataReady_ExecuteAction() ;
777     break ;
778   }
779   case GraphExecutor::Executing_SuspendAction : {
780     sts = Executing_SuspendAction() ;
781     break ;
782   }
783   case GraphExecutor::SuspendedExecuting_ResumeAction : {
784     sts = SuspendedExecuting_ResumeAction() ;
785     break ;
786   }
787   case GraphExecutor::Executing_KillAction : {
788     sts = Executing_KillAction() ;
789     break ;
790   }
791   case GraphExecutor::Executing_StopAction : {
792     sts = Executing_StopAction() ;
793     break ;
794   }
795   case GraphExecutor::Executing_SuccessAction : {
796     sts = Executing_SuccessAction() ;
797     break ;
798   }
799   case GraphExecutor::Errored_ExecutingAction : {
800     sts = Errored_ExecutingAction() ;
801     break ;
802   }
803   case GraphExecutor::Successed_SuccessAction : {
804     sts = Successed_SuccessAction() ;
805     break ;
806   }
807   case GraphExecutor::Errored_ErrorAction : {
808     sts = Errored_ErrorAction() ;
809     break ;
810   }
811   case GraphExecutor::Successed_SuspendAction : {
812     sts = Successed_SuspendAction() ;
813     break ;
814   }
815   case GraphExecutor::Errored_SuspendAction : {
816     sts = Errored_SuspendAction() ;
817     break ;
818   }
819   case GraphExecutor::SuspendedSuccessed_ResumeAction : {
820     sts = SuspendedSuccessed_ResumeAction() ;
821     break ;
822   }
823   case GraphExecutor::SuspendedErrored_ResumeAction : {
824     sts = SuspendedErrored_ResumeAction() ;
825     break ;
826   }
827   case GraphExecutor::Successed_KillAction : {
828     sts = Successed_KillAction() ;
829     break ;
830   }
831   case GraphExecutor::Errored_KillAction : {
832     sts = Errored_KillAction() ;
833     break ;
834   }
835   case GraphExecutor::Successed_StopAction : {
836     sts = Successed_StopAction() ;
837     break ;
838   }
839   case GraphExecutor::Errored_StopAction : {
840     sts = Errored_StopAction() ;
841     break ;
842   }
843   case GraphExecutor::SuspendedSuccessed_ReStartAction : {
844     sts = SuspendedSuccessed_ReStartAction() ;
845     break ;
846   }
847   case GraphExecutor::SuspendedErrored_ReStartAction : {
848     sts = SuspendedErrored_ReStartAction() ;
849     break ;
850   }
851   case GraphExecutor::SuspendedSuccessed_ReStartAndSuspendAction : {
852     sts = SuspendedSuccessed_ReStartAndSuspendAction() ;
853     break ;
854   }
855   case GraphExecutor::SuspendedErrored_ReStartAndSuspendAction : {
856     sts = SuspendedErrored_ReStartAndSuspendAction() ;
857     break ;
858   }
859   default : {
860     cdebug << pthread_self() << "/" << ThreadNo()
861            << " GraphExecutor::InNodeThreads::SendEvent Error Undefined Action : "
862            << _NextAction << endl ;
863     return 0 ;
864   }
865   }
866 #if ActionsTrace
867   cdebug_out << pthread_self() << "/" << ThreadNo() << "<-- ExecuteAction "
868              << nextactionname << endl ;
869 #endif
870   return sts ;
871 }
872
873 int GraphExecutor::InNode::ErrorAction() {
874   cdebug << pthread_self() << "/" << ThreadNo() << " Automaton ErrorAction Node "
875          << Name() << endl;
876   return 0;
877 }
878
879 int GraphExecutor::InNode::VoidAction() {
880   cdebug << pthread_self() << "/" << ThreadNo() << " VoidAction "  << Name() << endl;
881   return 1;
882 }
883
884 #define SomeDataReadyActionTrace 1
885 int GraphExecutor::InNode::DataWaiting_SomeDataReadyAction() {
886 #if SomeDataReadyActionTrace
887   cdebug_in << pthread_self() << "/" << ThreadNo() << " " << Name()
888             << " DataWaiting_SomeDataReadyAction from " << DataFromNode() << endl;
889 #endif
890   unsigned int k;
891   int InReady = 0 ;
892   int res = 1;
893   bool LoopBeginning = false ;
894   bool LoopFinished = false ;
895   bool SwitchFinished = false ;
896   bool SwitchDefault = false ;
897   bool DoAllDataReadyIf = true ;
898
899   if ( IsLoopNode() ) {
900     GraphBase::OutPort * anOutLoopPort = GetChangeNodeInLoop()->GetOutPort() ; // DoLoop Port
901     if ( anOutLoopPort && anOutLoopPort->BoolValue() ) {
902       LoopBeginning = true ; // Beginning of Loop
903     }
904   }
905   else if ( IsEndLoopNode() ) {
906     GraphBase::OutPort * anOutLoopPort = GetChangeNodeInLoop()->GetOutPort() ; // DoLoop Port
907     if ( anOutLoopPort && !anOutLoopPort->BoolValue() ) {
908       LoopFinished = true ; // End of Loop
909     }
910   }
911   else if ( IsEndSwitchNode() ) {
912     if ( strcmp( GOTONode()->CoupledNode()->Name() , DataFromNode() ) ) {
913       GraphBase::OutPort * anOutGateSwitchPort = GetChangeNodeInGate()->GetOutPort() ; // Default Port
914 //JR 09.02.2005 : SomeDataReady is NOT from the SwitchNode
915       if ( anOutGateSwitchPort && !anOutGateSwitchPort->BoolValue() ) {
916 //JR 09.02.2005 : the OutPort of the SwitchNode connected to the default port is closed ===>
917 // Here after we consider that that DefaultPort is Ready (even if it's value is false) in
918 // order to have the good count of InPorts Ready in the EndSwitchNode
919 //        SwitchFinished = true ; // End of Switch
920 //JR 25.08.2005 :
921 // But we do that only if the InDefaultPort of the EndSwitchNode is not connected or
922 // is connected from the OutDefaultPort of the corresponding SwitchNode
923         if ( !strcmp( GOTONode()->CoupledNode()->Name() , anOutGateSwitchPort->NodeName() ) ) {
924           SwitchFinished = true ; // End of Switch
925         }
926       }
927     }
928     else {
929 //JR 20.04.2005 : SomeDataReady is FROM the SwitchNode to that EndSwitchNode
930 //PAL8518
931 //JR 16.02.2005 Debug : Change InPorts of EndSwitchNode that have the same name as an OutPort of
932 // the SwitchNode even if it is the DefaultPort : GraphSwitchCheckDefault1.xml
933       GraphBase::OutPort * anOutGateSwitchPort = GetChangeNodeInGate()->GetOutPort() ; // Default P
934 //JR 20.04.2005 : SomeDataReady is from the SwitchNode and Default is activated :
935       if ( anOutGateSwitchPort ) {
936         if ( anOutGateSwitchPort->BoolValue() ) {
937           SwitchDefault = true ;
938         }
939 //JR 20.04.2005 : SomeDataReady is from the SwitchNode and Default is NOT activated :
940 //                a SwitchBranch should be activated
941         else {
942           DoAllDataReadyIf = false ;
943         }
944 #if SomeDataReadyActionTrace
945         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
946                << " activated from CoupledNode " << GOTONode()->CoupledNode()->Name() << " "
947                << anOutGateSwitchPort->NodeName() << "( " << anOutGateSwitchPort->PortName()
948                << " ) to InDefault " ;
949 #ifdef _DEBUG_
950         if ( GraphBase::Base::_prof_debug ) {
951           anOutGateSwitchPort->StringValue( *GraphBase::Base::_fdebug ) ;
952         }
953 #endif
954         cdebug << endl ;
955 #endif
956       }
957 //JR 28.06.2005 : SomeDataReady is from the SwitchNode and the InDefault is not connected :
958 //                a SwitchBranch should be activated
959       else {
960         DoAllDataReadyIf = false ;
961       }
962     }
963   }
964
965 #if SomeDataReadyActionTrace
966   cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " LoopFinished " << LoopFinished
967          << " LoopBeginning " << LoopBeginning << " SwitchFinished " << SwitchFinished
968          << " SwitchDefault " << SwitchDefault << " DoAllDataReadyIf " << DoAllDataReadyIf << endl ;
969 #endif
970   for ( k = 0 ; k < (unsigned int ) GetNodeInPortsSize() ; k++ ) {
971     GraphBase::InPort * anInPort = GetChangeNodeInPort(k) ;
972     GraphBase::OutPort * anOutPort ;
973     if ( SwitchDefault && !anInPort->IsDataStream() ) {
974 //Get or Set the field OutPort of that InPort of the EndSwitchNode to the corresponding OutPort
975 // of the SwitchNode
976       anOutPort = anInPort->GetOutPort() ;
977       if ( anOutPort ) {
978 #if SomeDataReadyActionTrace
979         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort "
980                << anInPort->PortName() << " already setted to OutPort " << anOutPort->NodeName()
981                << "( " << anOutPort->PortName() << " )" << endl ;
982 #endif
983       }
984       else {
985         anOutPort = CoupledNode()->GetChangeOutPort( anInPort->PortName() ) ;
986         if ( anOutPort ) {
987 #if SomeDataReadyActionTrace
988           cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort "
989                  << anInPort->PortName() << " change of OutPort from "
990                  << anInPort->GetOutPort()->NodeName() << "( " << anInPort->GetOutPort()->PortName()
991                  << " ) to " << anOutPort->NodeName() << "( " << anOutPort->PortName() << " )"
992                  << endl ;
993 #endif
994         }
995         else {
996           cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort "
997                  << anInPort->PortName() << " have NO OutPort ERROR " << endl ;
998           return 0 ;
999         }
1000         anInPort->ChangeOutPort( anOutPort ) ;
1001       }
1002     }
1003     else {
1004       anOutPort = anInPort->GetOutPort() ;
1005     }
1006 #if SomeDataReadyActionTrace
1007     cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort "
1008            << anInPort->PortName() << " " << anInPort->PortState() << " "
1009            << anInPort->PortStatus() << " " << anInPort->Kind()  ;
1010     if ( anOutPort ) {
1011       cdebug << " from OutPort " << anOutPort->NodeName() << "( " << anOutPort->PortName()
1012              << " )" ;
1013     }
1014     else {
1015       cdebug << " without OutPort " ;
1016     }
1017     cdebug<< endl ;
1018 #endif
1019     if ( anInPort->IsGate() && anOutPort == NULL ) {
1020       InReady += 1 ;
1021       anInPort->PortState( SUPERV::ReadyState ) ;
1022 #if SomeDataReadyActionTrace
1023       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1024              << anInPort->PortName() << " ControlPort inactive." << endl ;
1025 #endif
1026     }
1027
1028 // That InPort get its value from an other node : the node of anOutPort linked to that anInPort is
1029 // different from the sender of SomeDataReady (DataFromNode) :
1030     else if ( strcmp( DataFromNode() , anOutPort->NodeName() ) ) {
1031       if ( anInPort->PortState() == SUPERV::ReadyState ) {
1032         InReady += 1 ;
1033 #if SomeDataReadyActionTrace
1034         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1035                << anInPort->PortName() << " " << anInPort->PortState() << " Was Done from Node "
1036                << anOutPort->NodeName() << "( " << anOutPort->PortName() << " , "
1037                << anOutPort->PortState() << " ) PortDone " << anOutPort->PortDone() << " " ;
1038 #ifdef _DEBUG_
1039         if ( GraphBase::Base::_prof_debug ) {
1040           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1041         }
1042 #endif
1043         cdebug << endl ;
1044 #endif
1045       }
1046       else if ( IsLoopNode() && anInPort->IsDataConnected() ) {
1047         anInPort->PortState( SUPERV::ReadyState ) ;
1048         InReady += 1 ;
1049 #if SomeDataReadyActionTrace
1050         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1051                << anInPort->PortName() << " Was Done from Node "
1052                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1053                << ") LoopBeginning " << LoopBeginning << " " ;
1054 #ifdef _DEBUG_
1055         if ( GraphBase::Base::_prof_debug ) {
1056           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1057         }
1058 #endif
1059         cdebug << endl ;
1060 #endif
1061       }
1062       else if ( LoopFinished ) {
1063         anInPort->PortState( SUPERV::ReadyState ) ;
1064         InReady += 1 ;
1065 #if SomeDataReadyActionTrace
1066         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1067                << anInPort->PortName() << " Was Done from Node "
1068                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1069                << ") LoopFinished " << LoopFinished << " " ;
1070 #ifdef _DEBUG_
1071         if ( GraphBase::Base::_prof_debug ) {
1072           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1073         }
1074 #endif
1075         cdebug << endl ;
1076 #endif
1077       }
1078       else if ( anInPort->IsGate() && SwitchFinished ) {
1079         anInPort->PortState( SUPERV::ReadyState ) ;
1080         InReady += 1 ;
1081 #if SomeDataReadyActionTrace
1082         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1083                << anInPort->PortName() << " Was Done from Node "
1084                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1085                << ") SwitchFinished " << SwitchFinished << " " ;
1086 #ifdef _DEBUG_
1087         if ( GraphBase::Base::_prof_debug ) {
1088           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1089         }
1090 #endif
1091         cdebug << endl ;
1092 #endif
1093       }
1094       else if ( anInPort->IsGate() &&
1095                 _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() )->IsGOTONode() ) {
1096 // GateOutPort of GOTONodes are always opened
1097         anInPort->PortState( SUPERV::ReadyState ) ;
1098         InReady += 1 ;
1099 //JR 21.02.2005 Debug Memory leak :        CORBA::Any * anAny = new CORBA::Any() ;
1100         CORBA::Any anAny = CORBA::Any() ;
1101 //JR 21.02.2005 Debug Memory leak :        *anAny <<= (long ) 1 ;
1102         anAny <<= (long ) 1 ;
1103         _OutNode->Graph()->GetGraphNode( anOutPort->NodeName() )->GetChangeNodeOutGate()->SetValue( anAny ) ;
1104 #if SomeDataReadyActionTrace
1105         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1106                << anInPort->PortName() << " Was Done from Node "
1107                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1108                << ") GOTONode " ;
1109 #ifdef _DEBUG_
1110         if ( GraphBase::Base::_prof_debug ) {
1111           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1112         }
1113 #endif
1114         cdebug << endl ;
1115 #endif
1116       }
1117       else {
1118 #if SomeDataReadyActionTrace
1119         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1120                << " " << Automaton()->StateName( State() ) << " LoopBeginning "
1121                << LoopBeginning << " " << anInPort->PortName() << " DataConnected "
1122                << anInPort->IsDataConnected() << " Was NOT Done from Node "
1123                << anOutPort->NodeName() << "( " << anOutPort->PortName() << " , "
1124                << anOutPort->PortState() << " , PortDone " << anOutPort->PortDone() << ") "
1125                << endl ;
1126 #endif
1127       }
1128     }
1129
1130 // That InPort get its value from the sending node (DataFromNode)
1131     else if ( anInPort->IsGate() ) {
1132 //JR 30.03.2005      const CORBA::Any * theValue = anOutPort->Value() ;
1133       const CORBA::Any theValue = anOutPort->Value() ;
1134       long GateOpened ;
1135 //JR 30.03.2005      (*theValue) >>= GateOpened ;
1136       theValue >>= GateOpened ;
1137       if ( GateOpened != 0 ) {
1138         InReady += 1 ;
1139         anInPort->PortState( SUPERV::ReadyState ) ;
1140 #if SomeDataReadyActionTrace
1141         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1142                << anInPort->PortName() << " Gate is Opened from Node "
1143                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1144                << ") " ;
1145 #ifdef _DEBUG_
1146         if ( GraphBase::Base::_prof_debug ) {
1147           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1148         }
1149 #endif
1150         cdebug << endl ;
1151 #endif
1152       }
1153       else if ( LoopFinished ) {
1154         anInPort->PortState( SUPERV::ReadyState ) ;
1155 #if SomeDataReadyActionTrace
1156         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1157                << anInPort->PortName() << " GATE IS CLOSED from Node "
1158                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1159                << ") LoopFinished" ;
1160 #ifdef _DEBUG_
1161         if ( GraphBase::Base::_prof_debug ) {
1162           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1163         }
1164 #endif
1165         cdebug << endl ;
1166 #endif
1167       }
1168       else {
1169 #if SomeDataReadyActionTrace
1170         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " "
1171                << anInPort->PortName() << " GATE IS CLOSED from Node "
1172                << anOutPort->NodeName() << "( " << anOutPort->PortName()
1173                << ") " ;
1174 #ifdef _DEBUG_
1175         if ( GraphBase::Base::_prof_debug ) {
1176           anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1177         }
1178 #endif
1179         cdebug << endl ;
1180 #endif
1181       }
1182     }
1183     else if ( anOutPort->PortDone() ) {
1184 #if SomeDataReadyActionTrace
1185       cdebug << pthread_self() << "/" << ThreadNo() << " " << Name() << " InPort "
1186              << anInPort->PortName() << " " << anInPort->PortStatus() << " "
1187              << Automaton()->StateName( anInPort->PortState() ) << " is Done from Node "
1188              << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
1189              << anOutPort->PortStatus() << " --> ReadyState " ;
1190 #ifdef _DEBUG_
1191       if ( GraphBase::Base::_prof_debug ) {
1192         anOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
1193       }
1194 #endif
1195       cdebug << endl ;
1196 #endif
1197       InReady += 1 ;
1198       anInPort->PortState( SUPERV::ReadyState ) ;
1199 // MacroNode : give immediately the value to the corresponding graph
1200       if ( IsMacroNode() ) {
1201         GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
1202         cdebug << "SomeDataReadyAction MacroNode " << aMacroGraph->Name() << " --> InputOfAny "
1203                << InReady << "/" << GetNodeInPortsSize() << " InPorts are Ready ( "
1204                << anInPort->PortName() << " ) ===> InputOfAny" << endl ;
1205 //        GraphMacroNode()->MacroObject()->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
1206 //JR 30.03.2005        aMacroGraph->InputOfAny( anInPort->PortName() , *anOutPort->Value() ) ;
1207         aMacroGraph->InputOfAny( anInPort->PortName() , anOutPort->Value() ) ;
1208       }
1209     }
1210     else {
1211 #if SomeDataReadyActionTrace
1212       cdebug << pthread_self() << "/" << ThreadNo() << " Node " << Name() << "( "
1213              << anInPort->PortName() << ") " << anInPort->PortStatus()
1214              << " is NOT Done from Node "
1215              << anOutPort->NodeName() << "( " << anOutPort->PortName() << ") "
1216              << anOutPort->PortStatus() << " " << anOutPort->PortDone() << endl ;
1217 #endif
1218     }
1219   }
1220
1221   if ( InReady == GetNodeInPortsSize() && DoAllDataReadyIf ) { // All Flags != 0 :
1222 //JR 15.04.2005 Debug PAL8624 RetroConception :
1223 //    res = SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
1224 #if SomeDataReadyActionTrace
1225     cdebug << pthread_self() << "/" << ThreadNo() << " Node " << Name() << " HasAllDataReady"
1226            << endl ;
1227 #endif
1228     HasAllDataReady( true ) ; // ==> Ready to execute
1229     res = 1 ;
1230   }
1231   else { // At least one Flag == 0 :
1232     HasAllDataReady( false ) ;
1233     res = SendEvent( GraphExecutor::NotAllDataReadyEvent );
1234   }
1235
1236 #if SomeDataReadyActionTrace
1237   cdebug_out << pthread_self() << "/" << ThreadNo() << Name()
1238              << " DataWaiting_SomeDataReadyAction " << endl;
1239 #endif
1240   return res ;
1241
1242 }
1243
1244 #define NotAllDataReadyActionTrace 1
1245 int GraphExecutor::InNode::DataUndef_NotAllDataReadyAction() {
1246 //JR 15.04.2005 Debug PAL8624 RetroConception :
1247 //  CreateNewThreadIf( false ) ;
1248 #if NotAllDataReadyActionTrace
1249   cdebug << pthread_self() << " for " << ThreadNo()
1250          << " DataUndef_NotAllDataReadyAction " << Name() << endl;
1251 #endif
1252   return 1;
1253 }
1254
1255 #define AllDataReadyActionTrace 1
1256 int GraphExecutor::InNode::DataUndef_AllDataReadyAction() {
1257 #if AllDataReadyActionTrace
1258   cdebug << pthread_self() << "/" << ThreadNo()
1259          << " --> DataUndef_AllDataReadyAction " << Name() << endl ;
1260 //         << " CreateNewThreadIf " << CreateNewThreadIf() << " IsLockedDataWait "
1261 //         << IsLockedDataWait() ;
1262 #endif
1263 //JR 15.04.2005 Debug PAL8624 RetroConception :
1264   if ( !CreateNewThread() ) {
1265 #if AllDataReadyActionTrace
1266     cdebug << "Thread " << ThreadNo() << " --> " << pthread_self() << endl ;
1267 #endif
1268     ThreadNo( pthread_self() ) ;
1269   }
1270   else {
1271     _OutNode->IncrCreatedThreads() ;
1272   }
1273   _OutNode->PushEvent( this , GraphExecutor::AllDataReadyEvent ,
1274                        GraphExecutor::DataReadyState ) ; 
1275   ReadyAction() ;
1276   SUPERV::ControlState aControl = ControlState() ;
1277   switch ( aControl ) {
1278   case SUPERV::VoidState : {
1279     SendEvent( GraphExecutor::ExecuteEvent ) ;
1280     break ;
1281   }
1282   case SUPERV::ToSuspendState : {
1283     SendEvent( GraphExecutor::SuspendEvent ) ;
1284     break ;
1285   }
1286   case SUPERV::ToSuspendStartState : {
1287     SendEvent( GraphExecutor::SuspendEvent ) ;
1288     break ;
1289   }
1290   case SUPERV::ToSuspendDoneState : {
1291     SendEvent( GraphExecutor::ExecuteEvent ) ;
1292     break ;
1293   }
1294   case SUPERV::ToKillState : {
1295     SendEvent( GraphExecutor::KillEvent ) ;
1296     break ;
1297   }
1298   case SUPERV::ToKillDoneState : {
1299     SendEvent( GraphExecutor::ExecuteEvent ) ;
1300     break ;
1301   }
1302   case SUPERV::ToStopState : {
1303     SendEvent( GraphExecutor::StopEvent ) ;
1304     break ;
1305   }
1306   default : {
1307     cdebug << ThreadNo()
1308            << " GraphExecutor::InNodeThreads::DataUndef_AllDataReadyAction Error Undefined Control : "
1309            << aControl << endl ;
1310     return 0;
1311   }
1312   }
1313 #if AllDataReadyActionTrace
1314   cdebug << pthread_self() << "/" << ThreadNo()
1315          << " <-- DataUndef_AllDataReadyAction " << Name() << endl;
1316 #endif
1317   return 1;
1318 }
1319
1320 int GraphExecutor::InNode::DataReady_SuspendAction() {
1321   cdebug << pthread_self() << "/" << ThreadNo()
1322          << "DataReady_SuspendAction --> Suspend " << Name()
1323          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
1324          << _OutNode->SuspendedThreads() << endl;
1325   _OutNode->PushEvent( this , GraphExecutor::SuspendedReadyEvent ,
1326                        GraphExecutor::SuspendedReadyState ) ;
1327   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
1328   cdebug << pthread_self() << "/" << ThreadNo()
1329          << "DataReady_SuspendAction Resumed " << Name() << endl;
1330   if ( aReStartNode ) {
1331     _aReStartNode = NULL ;
1332     aReStartNode->SendEvent( _aReStartEvent ) ;
1333   }
1334   else {
1335     SendEvent( GraphExecutor::ExecuteEvent ) ;
1336   }
1337   return 1 ;
1338 }
1339
1340 int GraphExecutor::InNode::SuspendedReady_ResumeAction() {
1341   cdebug << pthread_self() << "/" << ThreadNo() << "SuspendedReady_ResumeAction "
1342          << Name() << endl;
1343 //  ResumeAction() ;
1344   _OutNode->PushEvent( this , GraphExecutor::ResumedReadyEvent ,
1345                        GraphExecutor::ResumedReadyState ) ; 
1346   return 1 ;
1347 }
1348
1349 int GraphExecutor::InNode::DataReady_KillAction() {
1350   _OutNode->PushEvent( this , GraphExecutor::KilledReadyEvent ,
1351                        GraphExecutor::KilledReadyState ) ;
1352   KillAction() ;
1353   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_KillAction " << Name()
1354          << " will pthread_exit()" << endl;
1355   return 1 ;
1356 }
1357
1358 int GraphExecutor::InNode::DataReady_StopAction() {
1359   _OutNode->PushEvent( this , GraphExecutor::StoppedReadyEvent ,
1360                        GraphExecutor::StoppedReadyState ) ; 
1361   StopAction() ;
1362   cdebug << pthread_self() << "/" << ThreadNo() << "DataReady_StopAction " << Name()
1363          << " will pthread_exit()" << endl;
1364   return 1 ;
1365 }
1366
1367 #include <CORBA.h>
1368
1369 #define TraceDataReady_ExecuteAction 1
1370 int GraphExecutor::InNode::DataReady_ExecuteAction() {
1371
1372 #if TraceDataReady_ExecuteAction
1373   cdebug_in << pthread_self() << "/" << ThreadNo() << " DataReady_ExecuteAction "
1374             << Name() << endl;
1375 #endif
1376   _OutNode->PushEvent( this , GraphExecutor::ExecuteEvent ,
1377                        GraphExecutor::ExecutingState ) ; 
1378
1379   RunningAction() ;
1380
1381   bool Err = false ;
1382
1383   Engines::Container_var myContainer ;
1384   Engines::Component_var myObjComponent ;
1385
1386   SUPERV::GraphState PortState = SUPERV::ReadyState ;
1387   GraphExecutor::AutomatonState NewState = GraphExecutor::DataUndefState ;
1388   GraphExecutor::NodeEvent NewEvent = GraphExecutor::UndefinedEvent ;
1389
1390   int nInParams ;
1391   ServicesAnyData * InParametersList = NULL ;
1392   int nOutParams ;
1393   ServicesAnyData * OutParametersList = NULL ;
1394
1395   nInParams = GetNodeInPortsSize()  ;
1396 #if TraceDataReady_ExecuteAction
1397   char * aName = Name() ;
1398   cdebug << pthread_self() << "/" << ThreadNo() << " " << aName
1399          << " nInParams " << nInParams << " InParametersList "
1400          << (void * ) InParametersList << endl ;
1401 #endif
1402   InParametersList = new ServicesAnyData[nInParams];
1403   InParametersSet( Err , nInParams , InParametersList ) ;
1404
1405   nOutParams = GetNodeOutPortsSize() ;
1406   OutParametersList = new ServicesAnyData[nOutParams];
1407   InOutParametersSet( nOutParams , OutParametersList ) ;
1408 #if 0
1409   if ( !Err && IsComputingNode() ) {
1410     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " "
1411            << " after creation of InParametersList : nInParams " << nInParams
1412            << " :" << endl;
1413     int i ;
1414     for ( i = 0 ; i < nInParams-1 ; i++ ) { // Without Gates
1415       cdebug << "InParametersList[" << i << "] : "
1416              << InParametersList[i].Name << " "
1417              << AnyValue( InParametersList[i].Value ) << endl ;
1418     }
1419     CORBA::Object * obj ;
1420     InParametersList[0].Value >>= obj ;
1421     Engines::Component_var theObjComponent ;
1422     theObjComponent = Engines::Component::_narrow( obj ) ;
1423     DynInvoke( theObjComponent , "ping" ,
1424                NULL , 0 , NULL , 0 ) ;
1425     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " ping done "
1426            << endl ;
1427     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " "
1428            << " after creation of OutParametersList :" << endl;
1429     for ( i = 0 ; i < nOutParams-1 ; i++ ) { // Without Gates
1430       cdebug << "OutParametersList[" << i << "] : "
1431              << OutParametersList[i].Name << " "
1432              << AnyValue( OutParametersList[i].Value ) << endl ;
1433     }
1434   }
1435 #endif
1436
1437   if ( !IsMacroNode() ) {
1438
1439     if ( !IsFactoryNode() ) {
1440 #if TraceDataReady_ExecuteAction
1441       cdebug << ThreadNo() << "No Component : NO StartComponent & No Ping" << endl ;
1442 #endif
1443       if ( IsComputingNode() ) {
1444         ObjInterface( true ) ;
1445 //JR 05.08.2005 DEBUG : the folowing code runs with OMNIOrb3 but gives
1446 //                      unpredictable results with SALOME_3 (OMNIOrb4) ...
1447 #if !omniORB_4_0_5
1448         CORBA::Object_ptr obj ;
1449         InParametersList[0].Value >>= obj ;
1450         CORBA::Object_var objvar = CORBA::Object_var( obj ) ;
1451         myObjComponent = Engines::Component::_duplicate( Engines::Component::_narrow( objvar ) ) ;
1452 //JR 05.08.2005 DEBUG : that code runs with SALOME_3 (OMNIOrb4) ...
1453 #else
1454         CORBA::Object * obj ;
1455         InParametersList[0].Value >>= obj ;
1456         Engines::Component_var theObjComponent ;
1457         myObjComponent = Engines::Component::_narrow( obj ) ;
1458 #endif
1459       }
1460       else {
1461       }
1462     }
1463     else if ( CORBA::is_nil( Component() ) ) {
1464       Err = !_OutNode->Graph()->StartComponent( ThreadNo() , Computer() ,
1465 //JR 17.02.2005 Memory Leak                                                my_strdup( ComponentName() ) ,
1466                                                 ComponentName() ,
1467                                                 myContainer , myObjComponent ) ;
1468       ObjInterface( false ) ;
1469       SetContainer( myContainer ) ;
1470       SetComponent( myObjComponent ) ;
1471     }
1472     else {
1473       myContainer = Container() ;
1474       myObjComponent = Component() ;
1475 #if TraceDataReady_ExecuteAction
1476       cdebug << ThreadNo() << "Component known : NO StartComponent & Ping"
1477              << endl ;
1478       try {
1479         myObjComponent->ping() ;
1480       }
1481       catch( ... ) {
1482         cdebug << "ping() ERROR catched" << endl ;
1483         Err = true ;
1484       }
1485 #endif
1486     }
1487
1488     if ( Err || ControlState() == SUPERV::ToKillState ||
1489                 ControlState() == SUPERV::ToKillDoneState ||
1490                 ControlState() == SUPERV::ToStopState ) {
1491 #if TraceDataReady_ExecuteAction
1492       cdebug << ThreadNo() << "StartComponent Error or ToKillState" << endl ;
1493 #endif
1494       Err = true ;
1495     }
1496     else {
1497       if ( ControlState() == SUPERV::ToSuspendState ) {
1498 #if TraceDataReady_ExecuteAction
1499         cdebug << ThreadNo() << "ToSuspendState before running." << endl ;
1500         MESSAGE(ThreadNo() << "ToSuspendState before running.") ;
1501 #endif
1502       }
1503 #if TraceDataReady_ExecuteAction
1504       int i;
1505       cdebug << ThreadNo() << " Run( '" << ServiceName() << "'" ;
1506       for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
1507         cdebug << " , " << InParametersList[ i ].Name << "[kind"
1508                << InParametersList[ i ].Value.type()->kind() << "]" ;
1509       }
1510       for ( i = 0 ; i < (int ) ServiceOutParameter().length() ; i++ ) {
1511         cdebug << " , " << OutParametersList[ i ].Name << "[kind"
1512                << OutParametersList[ i ].Value.type()->kind() << "]" ;
1513       }
1514       if ( IsOneOfInLineNodes() ) {
1515         cdebug << " , PyFuncName '" << InLineNode()->PyFuncName() << "' PyRunMethod "
1516                << InLineNode()->PyRunMethod() << " length "
1517                << (*InLineNode()->PythonFunction()).length()
1518                << " InParametersList " << InParametersList
1519                << " OutParametersList " << OutParametersList ;
1520       }
1521       cdebug << ")" << endl ;
1522 #endif
1523
1524       if ( IsOneOfInLineNodes() ) {
1525         Err = DataReady_ExecuteActionInLineNodes( InParametersList ,
1526                                                   OutParametersList ) ;
1527       }
1528
1529       else {
1530 #if 0
1531         if ( IsComputingNode() ) {
1532           cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name()
1533                  << " myObjComponent " << myObjComponent << " "
1534                  << ObjectToString( myObjComponent ) << endl ;
1535           cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " "
1536                  << " before DynInvoke nInParams " << nInParams
1537                  << " :" << endl;
1538           int i ;
1539           CORBA::Object * obj ;
1540           InParametersList[0].Value >>= obj ;
1541           Engines::Component_var theObjComponent ;
1542           theObjComponent = Engines::Component::_narrow( obj ) ;
1543           DynInvoke( theObjComponent , "ping" ,
1544                      NULL , 0 , NULL , 0 ) ;
1545           for ( i = 0 ; i < nInParams-1 ; i++ ) { // Without Gates
1546             cdebug << "InParametersList[" << i << "] : "
1547                    << InParametersList[i].Name << " "
1548                    << AnyValue( InParametersList[i].Value ) << endl ;
1549           }
1550         }
1551 #endif
1552         try {
1553 #if TraceDataReady_ExecuteAction
1554           cdebug << "DynInvoke -> Names " << _OutNode->Name() << " " << Name() << endl ;
1555 #endif
1556           DynInvoke( myObjComponent, "Names" ,
1557                      _OutNode->Name() , Name() ) ;
1558         }
1559         catch( ... ) {
1560           string anErrorMessage = string( "Dynamic CORBA call to Names for node " ) +
1561                                   string( Name() ) + " catched." ;
1562           _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1563           cdebug << "DynInvoke Names catched ERROR" << endl ;
1564         }
1565 // for DataStreamNodes : call of SetProperties ===> environment variables in the component/container
1566         if ( ComputingNode()->HasDataStream() ) {
1567           try {
1568 #if TraceDataReady_ExecuteAction
1569             cdebug << "DynInvoke -> SetProperties " << _OutNode->Name() << " " << Name() << endl ;
1570 #endif
1571             Engines::FieldsDict_var dict = new Engines::FieldsDict;
1572             dict->length( 4 );
1573             dict[ 0 ].key = CORBA::string_dup( "CAL_MACHINE");
1574                 // myContainer->getHostName() ne renvoit pas le nom complet (avec domaine).
1575                 //              dict[ 0 ].value <<= myContainer->getHostName() ;
1576             char FullyQualifiedDomainName[256]="";
1577             gethostname(FullyQualifiedDomainName,255);
1578             dict[ 0 ].value <<=  FullyQualifiedDomainName ;
1579             dict[ 1 ].key = CORBA::string_dup( "CAL_REPERTOIRE");
1580             dict[ 1 ].value <<= "/tmp" ;
1581             dict[ 2 ].key = CORBA::string_dup( "CAL_COUPLAGE");
1582             stringstream ofst1 ;
1583             ofst1 << ComputingNode()->SubStreamGraph() ;
1584             string cpl = string( "/tmp/" ) + string( _OutNode->Name() ) + string( "_" ) + 
1585                          ofst1.str() + string( ".cpl" );
1586             dict[ 2 ].value <<= cpl.c_str() ;
1587             dict[ 3 ].key = CORBA::string_dup( "SALOME_INSTANCE_NAME");
1588             string uname = Name();
1589             UpperCase( uname);
1590             dict[ 3 ].value <<= uname.c_str() ;
1591
1592             myObjComponent->setProperties( dict ) ;
1593           }
1594           catch( ... ) {
1595             string anErrorMessage = string( "Dynamic CORBA call to setProperties for node " ) +
1596                                     string( Name() ) + " catched." ;
1597             _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1598             cdebug << "DynInvoke setProperties catched ERROR" << endl ;
1599             Err = true;
1600           }
1601         }
1602
1603         try {
1604           if ( !Err && IsComputingNode() ) {
1605 #if TraceDataReady_ExecuteAction
1606             cdebug << ThreadNo() << " !ObjInterface " << Name()
1607                    << " IsComputingNode DynInvoke"  << endl ;
1608             cdebug << ServiceInParameter().length()-1 << " input parameters and "
1609                    << ServiceOutParameter().length() << " output parameters" << endl ;
1610 #endif
1611             IsLoading( false ) ;
1612             DynInvoke( myObjComponent,
1613                        ServiceName() ,
1614                        &InParametersList[1] , ServiceInParameter().length()-1 ,
1615                        &OutParametersList[0] , ServiceOutParameter().length() ) ;
1616 #if 0
1617             { cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name()
1618                      << " myObjComponent " << myObjComponent << " "
1619                      << ObjectToString( myObjComponent ) << endl ;
1620               cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " "
1621                      << " after DynInvoke nInParams " << nInParams
1622                      << " :" << endl;
1623               CORBA::Object * obj ;
1624               InParametersList[0].Value >>= obj ;
1625               Engines::Component_var theObjComponent ;
1626               theObjComponent = Engines::Component::_narrow( obj ) ;
1627               DynInvoke( theObjComponent , "ping" ,
1628                          NULL , 0 , NULL , 0 ) ;
1629               for ( i = 0 ; i < nInParams-1 ; i++ ) { // Without Gates
1630                 cdebug << "InParametersList[" << i << "] : "
1631                        << InParametersList[i].Name << " "
1632                        << AnyValue( InParametersList[i].Value ) << endl ;
1633               }
1634             }
1635 #endif
1636           }
1637           else if ( !Err && IsFactoryNode() ) {
1638 #if TraceDataReady_ExecuteAction
1639             cdebug << pthread_self() << "/" << ThreadNo() << " !ObjInterface " << Name()
1640                    << " IsFactoryNode DynInvoke"  << endl ;
1641             cdebug << ServiceInParameter().length() << " input parameters and "
1642                    << ServiceOutParameter().length() << " output parameters" << endl ;
1643 #endif
1644             IsLoading( false ) ;
1645             DynInvoke( myObjComponent,
1646                        ServiceName() ,
1647                        &InParametersList[0] , ServiceInParameter().length() ,
1648                        &OutParametersList[0] , ServiceOutParameter().length() ) ;
1649           }
1650 //            cdebug << ThreadNo() << " Component::CpuUsed " << Name() << " "
1651 //                   << myObjComponent->CpuUsed_impl() << endl ;
1652         }
1653         catch( ... ) {
1654           Err = true ;
1655           string anErrorMessage = string( "Dynamic CORBA call for node " ) +
1656                                   string( Name() ) + " catched." ;
1657           _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1658           cdebug << pthread_self() << "/" << ThreadNo() << " !ObjInterface " << Name()
1659                  << " Node(Component) Dynamic Call Exception catched ERROR"
1660                  << endl ;
1661 //Reset of _ThreadId in the Container ...
1662           try {
1663             myObjComponent->Kill_impl() ;
1664           }
1665           catch( ... ) {
1666           }
1667         }
1668       }
1669     }
1670   }
1671
1672   if ( Err ) {
1673     
1674     // if exception or something else - IsLoading( false ) may not NOT has been called
1675     if ( IsLoading() )
1676       IsLoading( false );
1677
1678     if ( ControlState() == SUPERV::ToKillState ||
1679          ControlState() == SUPERV::ToKillDoneState ||
1680          ControlState() == SUPERV::ToStopState ) {
1681       PortState = SUPERV::ErrorState ;
1682       NewState = GraphExecutor::KilledState ;
1683       NewEvent = GraphExecutor::KillEvent ;
1684     }
1685     else {
1686       PortState = SUPERV::ErrorState ;
1687       NewState = GraphExecutor::ErroredState ;
1688       NewEvent = GraphExecutor::ErrorEvent ;
1689     }
1690   }
1691   else {
1692     PortState = SUPERV::ReadyState ;
1693     NewState = GraphExecutor::DataReadyState ;
1694     NewEvent = GraphExecutor::SuccessEvent ;
1695   }
1696
1697   if ( !IsMacroNode() ) {
1698 //JRStep A
1699     bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
1700     if ( !ErrOut ) {
1701       NewEvent = GraphExecutor::ErrorEvent ;
1702     }
1703 #if 0
1704     if ( !Err && IsComputingNode() ) {
1705       cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name()
1706              << " myObjComponent " << myObjComponent << " "
1707              << ObjectToString( myObjComponent ) << endl ;
1708       cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " "
1709              << " delete [] InParametersList nInParams " << nInParams
1710              << " :" << endl;
1711       int i ;
1712       CORBA::Object * obj ;
1713       InParametersList[0].Value >>= obj ;
1714       Engines::Component_var theObjComponent ;
1715       theObjComponent = Engines::Component::_narrow( obj ) ;
1716       DynInvoke( theObjComponent , "ping" ,
1717                  NULL , 0 , NULL , 0 ) ;
1718       for ( i = 0 ; i < nInParams-1 ; i++ ) { // Without Gates
1719         cdebug << "InParametersList[" << i << "] : "
1720                << InParametersList[i].Name << " "
1721                << AnyValue( InParametersList[i].Value ) << endl ;
1722       }
1723     }
1724 #endif
1725     try {
1726       delete [] InParametersList ;
1727     }
1728     catch(...) {
1729       cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name()
1730              << " catch ERROR of delete [] InParametersList" << endl ;
1731     }
1732 #if TraceDataReady_ExecuteAction
1733     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " "
1734            << " delete [] OutParametersList :" << endl;
1735     int i ;
1736     for ( i = 0 ; i < nOutParams-1 ; i++ ) { // Without Gates
1737       cdebug << "OutParametersList[" << i << "] : "
1738              << OutParametersList[i].Name << " "
1739              << AnyValue( OutParametersList[i].Value ) << endl ;
1740     }
1741 #endif
1742     try {
1743       delete [] OutParametersList ;
1744     }
1745     catch(...) {
1746       cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name()
1747              << " catch ERROR of delete [] OutParametersList" << endl ;
1748     }
1749     SendEvent( NewEvent ) ;
1750   }
1751   else {
1752     GraphExecutor::DataFlow * aMacroGraph = GraphMacroNode()->CoupledNode()->GraphEditor()->Executor() ;
1753 #if TraceDataReady_ExecuteAction
1754     cdebug << ThreadNo() << " DataReady_ExecuteAction " << aMacroGraph << " "
1755            << aMacroGraph->Name() << " ->DoneWait()"
1756            << " State " << aMacroGraph->State() << endl;
1757 #endif
1758     aMacroGraph->DoneWait() ;
1759 #if TraceDataReady_ExecuteAction
1760     cdebug << ThreadNo() << " DataReady_ExecuteAction " << Name() << " State " << aMacroGraph->State() << endl;
1761 #endif
1762     if ( aMacroGraph->State() == SUPERV::DoneState ) {
1763       PortState = SUPERV::ReadyState ;
1764       NewState = GraphExecutor::DataReadyState ;
1765       NewEvent = GraphExecutor::SuccessEvent ;
1766     }
1767     else {
1768       Err = true ;
1769       if ( ControlState() == SUPERV::ToKillState ||
1770            ControlState() == SUPERV::ToKillDoneState ||
1771            ControlState() == SUPERV::ToStopState ) {
1772         PortState = SUPERV::ErrorState ;
1773         NewState = GraphExecutor::KilledState ;
1774         NewEvent = GraphExecutor::KillEvent ;
1775       }
1776       else {
1777         PortState = SUPERV::ErrorState ;
1778         NewState = GraphExecutor::ErroredState ;
1779         NewEvent = GraphExecutor::ErrorEvent ;
1780       }
1781     }
1782     bool ErrOut = OutParametersSet( Err , PortState , nOutParams , OutParametersList ) ;
1783     if ( !ErrOut ) {
1784       NewEvent = GraphExecutor::ErrorEvent ;
1785     }
1786     delete [] InParametersList ;
1787     delete [] OutParametersList ;
1788     SendEvent( NewEvent ) ;
1789   }
1790
1791 #if TraceDataReady_ExecuteAction
1792   cdebug_out << ThreadNo() << " DataReady_ExecuteAction " << Name() << endl;
1793 #endif
1794   return 1 ;
1795 }
1796
1797 int GraphExecutor::InNode::DataReady_ExecuteActionInLineNodes( ServicesAnyData * InParametersList ,
1798                                                                ServicesAnyData * OutParametersList ) {
1799
1800 #if TraceDataReady_ExecuteAction
1801   cdebug_in << pthread_self() << "/" << ThreadNo()
1802             << " DataReady_ExecuteActionInLineNodes " << Name()
1803             << " InParametersList " << InParametersList
1804             << " OutParametersList " << OutParametersList  << endl;
1805 #endif
1806   bool Err = false ;
1807   bool StsPyDynInvoke = true ;
1808   _OutNode->PyThreadLock() ;
1809   SetPyCpuUsed() ;
1810   try {
1811     bool ItIsaLoop = false ;
1812     bool CopyInOut = false ;
1813     if ( IsInLineNode() &&
1814          strlen( InLineNode()->PyFuncName() ) ) {
1815 #if TraceDataReady_ExecuteAction
1816       cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1817              << InLineNode()->PyFuncName()
1818              << "' IsInLineNode PyDynInvoke"  << endl ;
1819 #endif
1820       StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1821                                     InLineNode()->PyFuncName() ,
1822                                     InParametersList , ServiceInParameter().length() ,
1823                                     OutParametersList , ServiceOutParameter().length() ) ;
1824       if ( !StsPyDynInvoke ) {
1825         RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1826       }
1827     }
1828     else if ( IsLoopNode() ) {
1829       ItIsaLoop = true ;
1830       Err = DataReady_ExecuteActionLoopNodes( InParametersList ,
1831                                               OutParametersList ,
1832                                               CopyInOut ) ;
1833     }
1834     else if ( IsSwitchNode() && /*InLineNode()->PyRunMethod() &&*/
1835               strlen( InLineNode()->PyFuncName() ) ) {
1836 #if TraceDataReady_ExecuteAction
1837       cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1838              << InLineNode()->PyFuncName()
1839              << "' IsSwitchNode PyDynInvoke"  << endl ;
1840 #endif
1841       StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1842                                     InLineNode()->PyFuncName() ,
1843                                     InParametersList , ServiceInParameter().length() ,
1844                                     OutParametersList , ServiceOutParameter().length() ) ;
1845       if ( !StsPyDynInvoke ) {
1846         string anErrorMessage = string( "Dynamic Python call for node " ) +
1847                                 string( Name() ) + " function " +
1848                                 InLineNode()->PyFuncName() + " error." ;
1849         _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1850         RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1851       }
1852     }
1853     else if ( IsGOTONode() && /*InLineNode()->PyRunMethod() &&*/
1854               strlen( InLineNode()->PyFuncName() ) ) {
1855 #if TraceDataReady_ExecuteAction
1856       cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1857              << InLineNode()->PyFuncName()
1858              << "' IsGOTONode PyDynInvoke"  << endl ;
1859 #endif
1860       StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1861                                     InLineNode()->PyFuncName() ,
1862                                     InParametersList , ServiceInParameter().length() ,
1863                                     OutParametersList , ServiceOutParameter().length() ) ;
1864       if ( !StsPyDynInvoke ) {
1865         string anErrorMessage = string( "Dynamic Python call for node " ) +
1866                                 string( Name() ) + " function " +
1867                                 InLineNode()->PyFuncName() + " error." ;
1868         _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1869         RemovePyDynInvoke( GOTONode()->PyFuncName() ) ;
1870       }
1871     }
1872     else if ( ( IsEndSwitchNode() ) &&
1873               InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
1874 #if TraceDataReady_ExecuteAction
1875       cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1876              << InLineNode()->PyFuncName()
1877              << "' IsSwitchNode PyDynInvoke"  << endl ;
1878 #endif
1879       StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1880                                     InLineNode()->PyFuncName() ,
1881                                     InParametersList , ServiceInParameter().length() ,
1882                                     OutParametersList , ServiceOutParameter().length() ) ;
1883       if ( !StsPyDynInvoke ) {
1884         string anErrorMessage = string( "Dynamic Python call for node " ) +
1885                                 string( Name() ) + " function " +
1886                                 InLineNode()->PyFuncName() + " error." ;
1887         _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1888         RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1889       }
1890     }
1891     else if ( IsEndLoopNode() &&
1892               InLineNode()->PyRunMethod() && strlen( InLineNode()->PyFuncName() ) ) {
1893 #if TraceDataReady_ExecuteAction
1894       cdebug << ThreadNo() << " !ObjInterface " << Name() << " PyFuncName '"
1895              << InLineNode()->PyFuncName()
1896              << "' IsSwitchNode PyDynInvoke"  << endl ;
1897 #endif
1898       StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
1899                                     InLineNode()->PyFuncName() ,
1900                                     InParametersList , ServiceInParameter().length() + 1 ,
1901                                     OutParametersList , ServiceOutParameter().length() + 1 ) ;
1902       if ( !StsPyDynInvoke ) {
1903         string anErrorMessage = string( "Dynamic Python call for node " ) +
1904                                 string( Name() ) + " function " +
1905                                 InLineNode()->PyFuncName() + " error." ;
1906         _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1907         RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
1908       }
1909     }
1910
1911     if ( (!ItIsaLoop && ( InLineNode()->PyRunMethod() == NULL ||
1912                           strlen( InLineNode()->PyFuncName() ) == 0 ) ) || CopyInOut ) {
1913 // This is a void Python Function : without code (No PyFuncName)
1914 #if TraceDataReady_ExecuteAction
1915       cdebug << ThreadNo() << " !ObjInterface " << Name()
1916              << " Copy of " << ServiceInParameter().length()
1917              << " OutParameters" << endl ;
1918 #endif
1919       int i ;
1920       int argout0 = 0 ;
1921       int argin0 = 0 ;
1922       if ( IsLoopNode() || IsEndLoopNode() ) {
1923         argout0 = 1 ;
1924         argin0 = 1 ; // after DoLoop
1925         if ( IsLoopNode() ) { // More() is void
1926 #if TraceDataReady_ExecuteAction
1927           cdebug << Name() << " Not Beginning of loop and non void EndLoop : DoLoop = EndLoop(DoLoop)"
1928                  << endl ;
1929 #endif
1930           GraphExecutor::InNode * anEndLoopNode = (GraphExecutor::InNode * ) CoupledNode()->GetInNode() ;
1931           OutParametersList[0].Value = anEndLoopNode->GetNodeOutLoop()->Value() ; // DoLoop = EndLoop(DoLoop)
1932         }
1933       }
1934 //PAL8072 ==> PAL8512
1935 //JR 24.03.2005 : Debug : void InLine Python function : check of the number of Input Ports
1936 //                        equals the number of Output Ports was missing
1937       if ( ServiceInParameter().length() != ServiceOutParameter().length() ) {
1938          string anErrorMessage = string( "Inconsistent number of In<->Out parameters for the vois Python function of the node " ) +
1939                                  string( Name() ) ;
1940          _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1941          StsPyDynInvoke = false ;
1942       }
1943       else {
1944         for ( i = 0 ; i < (int ) ServiceInParameter().length() ; i++ ) {
1945           OutParametersList[argout0 + i].Value = InParametersList[argin0 + i].Value ;
1946 #if TraceDataReady_ExecuteAction
1947           cdebug << "ArgOut->In" << InParametersList[argin0 + i].Name.c_str()
1948                  << " " << AnyValue( InParametersList[argin0 + i].Value )
1949                  << endl ;
1950 #endif
1951         }
1952       }
1953     }
1954     if ( !StsPyDynInvoke ) {
1955       Err = true ;
1956       string anErrorMessage = string( "Dynamic Python call for node " ) +
1957                               string( Name() ) + " error." ;
1958       _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1959       cdebug << ThreadNo() << " InLineNode " << Name()
1960              << " Python Dynamic Call Error"
1961              << endl ;
1962     }
1963   }
1964   catch( ... ) {
1965     Err = true ;
1966     string anErrorMessage = string( "Dynamic Python call for node " ) +
1967                             string( Name() ) + " catched." ;
1968     _OutNode->Graph()->SetMessages( anErrorMessage ) ;
1969     cdebug << ThreadNo() << " InLineNode " << Name()
1970            << " Python Dynamic Call Exception catched ERROR"
1971            << endl ;
1972   }
1973   CpuUsed( true ) ;
1974   _OutNode->PyThreadUnLock() ;
1975 #if TraceDataReady_ExecuteAction
1976   cdebug_out << pthread_self() << "/" << ThreadNo()
1977              << " DataReady_ExecuteActionInLineNodes " << Name() << endl;
1978 #endif
1979   return Err ;
1980 }
1981
1982 int GraphExecutor::InNode::DataReady_ExecuteActionLoopNodes( ServicesAnyData * InParametersList ,
1983                                                              ServicesAnyData * OutParametersList ,
1984                                                              bool & CopyInOut ) {
1985
1986 #if TraceDataReady_ExecuteAction
1987   cdebug_in << pthread_self() << "/" << ThreadNo()
1988             << " DataReady_ExecuteActionLoopNodes " << Name()
1989             << " InParametersList " << InParametersList
1990             << " OutParametersList " << OutParametersList  << endl;
1991 #endif
1992   bool Err = false ;
1993   bool StsPyDynInvoke = true ;
1994       bool CopyOutIn = false ;
1995 // Switch between Init() and Next()
1996 // if InLoop port is true and does not come from EndLoop ==> execute Init
1997 // if InLoop port is false or come from EndLoop ==> execute Next
1998   if ( _InitLoop ) {
1999     if ( strlen( InLineNode()->PyFuncName() ) ) { // InLoop Port = true ==> Init()
2000 #if TraceDataReady_ExecuteAction
2001       cdebug << ThreadNo() << " !ObjInterface " << Name()
2002              << " IsLoopNode PyDynInvoke '" << InLineNode()->PyFuncName()
2003              << "' InitLoop " << LoopNode()->PyRunMethod() << endl ;
2004 #endif
2005       StsPyDynInvoke = PyDynInvoke( InLineNode()->PyRunMethod() ,
2006                                     InLineNode()->PyFuncName() ,
2007                                     &InParametersList[1] , ServiceInParameter().length() ,
2008                                     &OutParametersList[1] , ServiceOutParameter().length() ) ;
2009       if ( !StsPyDynInvoke ) {
2010         string anErrorMessage = string( "Dynamic Python call for node " ) +
2011                                 string( Name() ) + " function " +
2012                                 InLineNode()->PyFuncName() + " error." ;
2013         _OutNode->Graph()->SetMessages( anErrorMessage ) ;
2014         RemovePyDynInvoke( InLineNode()->PyFuncName() ) ;
2015       }
2016       CopyOutIn = true ;
2017     }
2018     else {
2019 #if TraceDataReady_ExecuteAction
2020       cdebug << ThreadNo() << " !ObjInterface " << Name()
2021              << " IsLoopNode NO PyDynInvoke Void PyFuncName InitLoop" << endl ;
2022 #endif
2023     }
2024 #if TraceDataReady_ExecuteAction
2025     cdebug << ThreadNo() << " !ObjInterface " << Name()
2026            << " IsLoopNode _InitLoop Reset after Init() Python Function" << endl ;
2027 #endif
2028     _InitLoop = false ;
2029   }
2030   else if ( LoopNode()->PyNextMethod() &&
2031             strlen( LoopNode()->PyNextName() ) ){ // InLoop Port = false ==> Next()
2032 #if TraceDataReady_ExecuteAction
2033     cdebug << ThreadNo() << " !ObjInterface " << Name()
2034            << " IsLoopNode PyDynInvoke '" << LoopNode()->PyNextName()
2035            << "' " << LoopNode()->PyNextMethod() << endl ;
2036 #endif
2037     StsPyDynInvoke = PyDynInvoke( LoopNode()->PyNextMethod() ,
2038                                   LoopNode()->PyNextName() ,
2039                                   &InParametersList[1] , ServiceInParameter().length() ,
2040                                   &OutParametersList[1] , ServiceOutParameter().length() ) ;
2041     if ( !StsPyDynInvoke ) {
2042       string anErrorMessage = string( "Dynamic Python call for node " ) +
2043                               string( Name() ) + " function " +
2044                               LoopNode()->PyNextName() + " error." ;
2045       _OutNode->Graph()->SetMessages( anErrorMessage ) ;
2046       RemovePyDynInvoke( LoopNode()->PyNextName() ) ;
2047     }
2048     CopyOutIn = true ;
2049   }
2050   else {
2051 #if TraceDataReady_ExecuteAction
2052     cdebug << ThreadNo() << " !ObjInterface " << Name()
2053            << " IsLoopNode NO PyDynInvoke Void PyFuncName NextLoop" << endl ;
2054 #endif
2055   }
2056   if ( StsPyDynInvoke ) {
2057     if ( CopyOutIn ) {
2058 #if TraceDataReady_ExecuteAction
2059       cdebug << ThreadNo() << " !ObjInterface " << Name()
2060              << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
2061              << "' Copy of " << ServiceInParameter().length()
2062              << " OutParameters" << endl ;
2063 #endif
2064       int i ;
2065 // Start at 1 : Do not copy InLoop ( InLoop == true <==> Init ; InLoop == false <==> Next )
2066       for ( i = 1 ; i <= (int ) ServiceInParameter().length() ; i++ ) {
2067         InParametersList[i].Value = OutParametersList[i].Value ;
2068         InParametersList[i].Name = OutParametersList[i].Name ;
2069 #if TraceDataReady_ExecuteAction
2070         cdebug << "ArgOut->In" << InParametersList[ i].Name.c_str()
2071                << " " << AnyValue( InParametersList[ i].Value )
2072                << endl ;
2073 #endif
2074       }
2075     }
2076     if ( LoopNode()->PyMoreMethod() && strlen( LoopNode()->PyMoreName() ) ) {
2077 #if TraceDataReady_ExecuteAction
2078       cdebug << ThreadNo() << " !ObjInterface " << Name()
2079              << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
2080              << "' " << LoopNode()->PyMoreMethod() << endl ;
2081 #endif
2082       StsPyDynInvoke = PyDynInvoke( LoopNode()->PyMoreMethod() ,
2083                                     LoopNode()->PyMoreName() ,
2084                                     &InParametersList[1] , ServiceInParameter().length() ,
2085                                     &OutParametersList[0] , ServiceOutParameter().length()+1 ) ;
2086       if ( !StsPyDynInvoke ) {
2087         string anErrorMessage = string( "Dynamic Python call for node " ) +
2088                                 string( Name() ) + " function " +
2089                                 LoopNode()->PyMoreName() + " error." ;
2090         _OutNode->Graph()->SetMessages( anErrorMessage ) ;
2091         RemovePyDynInvoke( LoopNode()->PyMoreName() ) ;
2092       }
2093     }
2094     else {
2095 #if TraceDataReady_ExecuteAction
2096       cdebug << ThreadNo() << " !ObjInterface " << Name()
2097              << " IsLoopNode PyDynInvoke '" << LoopNode()->PyMoreName()
2098              << "' No MoreMethod" << endl ;
2099 #endif
2100       CopyInOut = true ;
2101     }
2102   }
2103   else {
2104     Err = true ;
2105     cdebug << ThreadNo() << " InLineNode " << Name() << " "
2106            << InLineNode()->PyFuncName() << "/" << LoopNode()->PyNextName()
2107            << " Python Dynamic Call Error"
2108            << endl ;
2109   }
2110 #if TraceDataReady_ExecuteAction
2111   cdebug_out << pthread_self() << "/" << ThreadNo()
2112              << " DataReady_ExecuteActionLoopNodes " << Name() << endl;
2113 #endif
2114   return Err ;
2115 }
2116
2117 int GraphExecutor::InNode::Executing_SuspendAction() {
2118   _OutNode->PushEvent( this , GraphExecutor::SuspendedExecutingEvent ,
2119                        GraphExecutor::SuspendedExecutingState ) ; 
2120   cdebug << ThreadNo() << " Executing_SuspendAction " << Name() << endl;
2121   return 1 ;
2122 }
2123
2124 int GraphExecutor::InNode::SuspendedExecuting_ResumeAction() {
2125   cdebug << ThreadNo() << " SuspendedExecuting_ResumeAction " << Name() << endl;
2126   GraphExecutor::AutomatonState next_state ;
2127   next_state = Automaton()->NextState( State() , GraphExecutor::ExecutingEvent ) ;
2128   _OutNode->NewThread() ; // Only for Threads count
2129   _OutNode->PushEvent( this , GraphExecutor::ResumedExecutingEvent ,
2130                        next_state ) ; 
2131   State( next_state ) ;
2132   return 1 ;
2133 }
2134
2135 int GraphExecutor::InNode::Executing_KillAction() {
2136   cdebug << ThreadNo() << " Executing_KillAction " << Name() << " Thread " << ThreadNo()<< endl;
2137   int RetVal = 0 ;
2138   if ( pthread_self() == ThreadNo() ) {
2139     cdebug << "Executing_KillAction would pthread_canceled itself" << endl ;
2140     KillAction() ;
2141     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
2142                          GraphExecutor::KilledExecutingState ) ; 
2143     RetVal = 1 ;
2144   }
2145   else if ( pthread_cancel( ThreadNo() ) ) {
2146     perror("Executing_KillAction pthread_cancel error") ;
2147   }
2148   else {
2149     cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
2150            << " pthread_canceled" << endl ;
2151     KillAction() ;
2152     _OutNode->ExitThread( ThreadNo() ) ;
2153     _OutNode->PushEvent( this , GraphExecutor::KilledExecutingEvent ,
2154                          GraphExecutor::KilledExecutingState ) ; 
2155   }
2156   return RetVal ;
2157 }
2158
2159 int GraphExecutor::InNode::Executing_StopAction() {
2160   cdebug << ThreadNo() << " Executing_StopAction " << Name() << " Thread " << ThreadNo() << endl;
2161   int RetVal = 0 ;
2162   if ( pthread_cancel( ThreadNo() ) ) {
2163     perror("Executing_KillAction pthread_cancel error") ;
2164   }
2165   else {
2166     cdebug << pthread_self() << " Executing_KillAction : ThreadId " << ThreadNo()
2167            << " pthread_canceled" << endl ;
2168     StopAction() ;
2169     _OutNode->ExitThread( ThreadNo() ) ;
2170     _OutNode->PushEvent( this , GraphExecutor::StoppedExecutingEvent ,
2171                          GraphExecutor::StoppedExecutingState ) ; 
2172   }
2173   return RetVal ;
2174 }
2175
2176 int GraphExecutor::InNode::Executing_SuccessAction() {
2177 //  cdebug << ThreadNo() << " --> Executing_SuccessAction " << Name() << endl;
2178   _OutNode->PushEvent( this , GraphExecutor::SuccessedExecutingEvent ,
2179                        GraphExecutor::SuccessedState ) ; 
2180 //  MESSAGE(pthread_self() << "Executor::InNode::Executing_SuccessAction of " << Name()
2181 //          << " ControlState " << Automaton()->ControlStateName( ControlState() )
2182 //          << " AFTER execution ThreadNo " << ThreadNo() ) ;
2183   SUPERV::ControlState aControl = ControlState() ;
2184   switch ( aControl ) {
2185   case SUPERV::VoidState : {
2186     SendEvent( SuccessEvent ) ;
2187     break ;
2188   }
2189   case SUPERV::ToSuspendState : {
2190     SendEvent( SuccessEvent ) ;
2191     break ;
2192   }
2193   case SUPERV::ToSuspendDoneState : {
2194     SendEvent( GraphExecutor::SuspendEvent ) ;
2195     return 1 ;
2196   }
2197   case SUPERV::ToKillState : {
2198     SendEvent( GraphExecutor::KillEvent ) ;
2199     return 1 ;
2200   }
2201   case SUPERV::ToKillDoneState : {
2202     SendEvent( GraphExecutor::KillEvent ) ;
2203     return 1 ;
2204   }
2205   case SUPERV::ToStopState : {
2206     SendEvent( GraphExecutor::StopEvent ) ;
2207     return 1 ;
2208   }
2209   default : {
2210     cdebug << ThreadNo()
2211            << " GraphExecutor::InNodeThreads::Executing_SuccessAction Error Undefined Control : "
2212            << aControl << endl ;
2213     return 0;
2214   }
2215   }
2216 //  cdebug << ThreadNo() << " <-- Executing_SuccessAction "  << Name() << endl;
2217   return 1 ;
2218 }
2219
2220 int GraphExecutor::InNode::Errored_ExecutingAction() {
2221   cdebug << ThreadNo() << " --> Errored_ExecutingAction " << Name() << endl;
2222   _OutNode->PushEvent( this , GraphExecutor::ErroredExecutingEvent ,
2223                        GraphExecutor::ErroredState ) ; 
2224
2225   _OutNode->NodeAborted( Name() ) ;
2226
2227   SUPERV::ControlState aControl = ControlState() ;
2228   switch ( aControl ) {
2229   case SUPERV::VoidState : {
2230     SendEvent( ErrorEvent ) ;
2231     break ;
2232   }
2233   case SUPERV::ToSuspendState : {
2234     SendEvent( ErrorEvent ) ;
2235     break ;
2236   }
2237   case SUPERV::ToSuspendDoneState : {
2238     SendEvent( GraphExecutor::SuspendEvent ) ;
2239     return 1 ;
2240   }
2241   case SUPERV::ToKillState : {
2242     SendEvent( GraphExecutor::KillEvent ) ;
2243     return 1 ;
2244   }
2245   case SUPERV::ToKillDoneState : {
2246     SendEvent( GraphExecutor::KillEvent ) ;
2247     return 1 ;
2248   }
2249   case SUPERV::ToStopState : {
2250     SendEvent( GraphExecutor::StopEvent ) ;
2251     return 1 ;
2252   }
2253   default : {
2254     cdebug << ThreadNo()
2255            << " GraphExecutor::InNodeThreads::Errored_ExecutingAction Error Undefined Control : "
2256            << aControl << endl ;
2257     return 0;
2258   }
2259   }
2260   cdebug << ThreadNo() << " <-- Errored_ExecutingAction "  << Name() << endl;
2261   return 1 ;
2262 }
2263
2264 #define SetWaitingStatesTrace 1
2265 // Set SUPERV::WaitingState to all InPorts 
2266 void GraphExecutor::InNode::SetWaitingStates(GraphExecutor::InNode * EndNode ) {
2267   int i ;
2268   int j ;
2269   bool docdebug = false ;
2270   State( GraphExecutor::DataWaitingState ) ;
2271 #if SetWaitingStatesTrace
2272   cdebug << "SetWaitingStates " << Name() << " " << Automaton()->StateName( State() ) << endl ;
2273 #endif
2274   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
2275     GraphBase::InPort * anInPort = GetChangeNodeInPort( i ) ;
2276 #if SetWaitingStatesTrace
2277     cdebug << "SetWaitingStates InPort " << Name() << "( " << anInPort->PortName() << " ) "
2278            << anInPort->PortStatus() << " " << anInPort->PortState() << endl ;
2279 #endif
2280 // PAL8513
2281 // JR Debug 07.01.2005 : Close the Gates instead of open !!!
2282     if ( anInPort->IsGate() ) { // Loop : Close the doors
2283       GraphBase::OutPort * anOutPort = anInPort->GetOutPort() ;
2284       if ( anOutPort ) {
2285 //JR 21.02.2005 Debug Memory leak :        CORBA::Any * anAny = new CORBA::Any() ;
2286         CORBA::Any anAny = CORBA::Any() ;
2287 //        *anAny <<= (long ) 1 ;
2288 //JR 21.02.2005 Debug Memory leak :        *anAny <<= (long ) 0 ;
2289         anAny <<= (long ) 0 ;
2290         anOutPort->SetValue( anAny ) ;
2291         anInPort->PortState( SUPERV::WaitingState ) ;
2292 //        delete anAny ;
2293       }
2294     }
2295     else if ( anInPort->PortState() != SUPERV::WaitingState &&
2296               !anInPort->IsDataConnected() ) {
2297       if ( !docdebug ) {
2298 #if SetWaitingStatesTrace
2299         cdebug << ThreadNo()
2300                << " --> GraphExecutor::InNodeThreads::SetWaitingStates " << Name() << endl;
2301 #endif
2302         docdebug = true ;
2303       }
2304       if ( !anInPort->IsDataStream() ) {
2305         anInPort->PortState( SUPERV::WaitingState ) ;
2306       }
2307     }
2308 #if SetWaitingStatesTrace
2309     cdebug << "               --> InPort " << Name() << "( " << anInPort->PortName() << " ) "
2310            << anInPort->PortStatus() << " " << anInPort->PortState() << endl ;
2311 #endif
2312   }
2313   for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
2314     GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i ) ;
2315 // PAL8514
2316 //JR 07.03.2005 Debug : Reset of Done flag in OutPorts !... :
2317     if ( !anOutPort->IsDataStream() ) {
2318       anOutPort->PortDone( false ) ;
2319       anOutPort->PortState( SUPERV::WaitingState ) ;
2320     }
2321     for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
2322       if ( !( IsGOTONode() && anOutPort->IsGate() ) &&
2323            !( IsEndLoopNode() && ( anOutPort->IsGate() || anOutPort->IsLoop() ) ) &&
2324            !anOutPort->IsDataStream() &&
2325            !anOutPort->ChangeInPorts( j )->IsDataStream() &&
2326            !anOutPort->ChangeInPorts( j )->IsExternConnected() ) {
2327 #if SetWaitingStatesTrace
2328         cdebug << ThreadNo()
2329                << " InNodeThreads::SetWaitingStates OutPort "
2330                << Name() << "/" << anOutPort->ChangeInPorts( j )->NodeName() << "( "
2331                << anOutPort->PortName() << " " << anOutPort->PortStatus() << " ) --> InPort "
2332                << anOutPort->ChangeInPorts( j )->NodeName() << "( "
2333                << anOutPort->ChangeInPorts( j )->PortName() << " "
2334                << anOutPort->ChangeInPorts( j )->PortStatus() << " )" << endl;
2335 #endif
2336         GraphBase::ComputingNode * aToNode ;
2337         aToNode = _OutNode->Graph()->GetChangeGraphNode( anOutPort->ChangeInPorts( j )->NodeName() ) ;
2338 // JR 12.01.2005 Debug : the OutPort linked to the InPort of a EndSwitchNode was changed so final
2339 //                       values of InPorts of EndSwitchNode may be wrong
2340 //                       (depending of order of linkednodes)
2341         if ( !aToNode->IsEndSwitchNode() && 
2342              strcmp( anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() , Name() ) ) {
2343 // After EndLoopNode or GOTONode the Input Ports of LoopNode or LabelNode have their values from
2344 // EndLoopNode or GOTONode. But if there is several nested loops we should re-establish.
2345 #if SetWaitingStatesTrace
2346           cdebug << ThreadNo()
2347                  << " InNodeThreads::SetWaitingStates Node " << Name() << " " 
2348                  << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() << "( "
2349                  << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName() << " ) != "
2350                  << Name() << " : Restored to " << anOutPort->NodeName() << "( "
2351                  << anOutPort->PortName() << " )" << endl ;
2352 #endif
2353           anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
2354         }
2355 //PAL8624
2356 //JR 21.04.2005 Debug : the OutPort field of InPorts of EndSwitchNodes must be an OutPort
2357 //                      of a SwitchBranch or of a NOTSwitchBranch if a link exist
2358 //                      (if not there is no change)
2359         else if ( !IsSwitchNode() && aToNode->IsEndSwitchNode() &&
2360                   strcmp( anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() , Name() ) ) {
2361 #if SetWaitingStatesTrace
2362           cdebug << ThreadNo()
2363                  << " InNodeThreads::SetWaitingStates Node " << Name() << " " 
2364                  << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName() << "( "
2365                  << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName() << " ) != "
2366                  << Name() << " : Restored to " << anOutPort->NodeName() << "( "
2367                  << anOutPort->PortName() << " )" << endl ;
2368 #endif
2369           anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
2370         }
2371         GraphExecutor::InNode * aNode = (GraphExecutor::InNode * ) aToNode->GetInNode() ;
2372         if ( aNode != EndNode ) {
2373           aNode->SetWaitingStates( EndNode ) ;
2374         }
2375       }
2376     }
2377 #if SetWaitingStatesTrace
2378     cdebug << "               --> OutPort " << Name() << "( " << anOutPort->PortName() << " ) "
2379            << anOutPort->PortStatus() << " " << anOutPort->PortState() << endl ;
2380 #endif
2381   }
2382 }
2383
2384 #define SuccessActionTrace 1
2385 //JR Step B
2386 int GraphExecutor::InNode::Successed_SuccessAction() {
2387 #if SuccessActionTrace
2388   cdebug_in << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "  << Name()
2389             << endl;
2390 #endif
2391   int res = 1;
2392 //PAL8624
2393 //JR 15.04.2005 Debug RetroConception :
2394 //The behavior of firstzeroNode and firsttoNode is not reliable and must be removed
2395 //The real problem is :
2396 // 1. send "SomeDataReady" event to linked nodes of the current node
2397 // 2. DO NOT send "AllDataReady" event even if all data are ready in SomeDataReady Action
2398 //    but register only that all data are ready :
2399 //    MAJOR ENHANCEMENT OF GRAPHEXECUTOR
2400 // 3. activate AllDataReady Action for each node (except the first one ) which have all
2401 //    its data ready with a creation of a new thread
2402 // 3. activate AllDataReady Action for the first node which have all its data
2403 //    ready in the current thread
2404 //The difficult problem (that I had in the past) was to clearly identify the above behavior ==>
2405 // firstzeroNode, firsttoNode, createnewthreadif, loackdatawait, "would dead lock" etc...
2406 // because if SomeDataReady Action see that all data were ready, it called immediately
2407 // AllDataReady Action ==> bugs difficult to understand and to reproduce
2408 //And the MAJOR DEBUG is (since the first "maquette") : we may have concurrent executions
2409 // of "SomeDataReady" in several threads and there WAS NO MUTEX to protect that
2410 // concurrent actions on the same node
2411 //  int linkednodesnumber = LinkedNodesSize() ;
2412 //  GraphExecutor::InNode *firstzeroNode = NULL ;
2413   GraphExecutor::InNode *firsttoNode = NULL ;
2414   GraphExecutor::InNode *toNode ;
2415   int i ;
2416   int j ;
2417   list<GraphExecutor::InNode *> SomeDataNodes ;
2418
2419   DoneAction() ;
2420
2421   if ( IsMacroNode() ) {
2422 #if SuccessActionTrace
2423       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " LinkedNodes->SomeDataReady already done"
2424              << endl ;
2425 #endif
2426     return 1;
2427   }
2428
2429 //JR 09.02.2005 : That complicated part of the code manages LOOPS and GOTO
2430   if ( IsGOTONode() ||
2431        ( IsEndLoopNode() && GetNodeInLoop()->GetOutPort()->BoolValue() ) ) {
2432 #if SuccessActionTrace
2433     cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name()
2434            << " SetWaitingStates " << endl ;
2435 #endif
2436     const GraphBase::OutPort * aGateOutPort ;
2437     if ( IsGOTONode() ) {
2438       aGateOutPort = GetNodeOutGate() ;
2439     }
2440     else {
2441       aGateOutPort = GetNodeOutLoop() ;
2442     }
2443     if ( aGateOutPort->InPortsSize() != 1 ) {
2444       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction aGateOutPort->InPortsSize "
2445              << aGateOutPort->InPortsSize() << " != 1 ERROR " << Name() << endl ;
2446     }
2447     GraphExecutor::InNode * aLabelNode = NULL ;
2448     for ( i = 0 ; i < aGateOutPort->InPortsSize() ; i++ ) {
2449       const GraphBase::InPort * anInPort = aGateOutPort->InPorts( i ) ;
2450       aLabelNode = (GraphExecutor::InNode *) _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() )->GetInNode() ;
2451 #if SuccessActionTrace
2452       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " will Loop to HeadNode "
2453              << aLabelNode->Name() << " from port " << anInPort->PortName() << endl ;
2454 #endif
2455       State( GraphExecutor::DataWaitingState ) ;
2456       aLabelNode->SetWaitingStates( this ) ;
2457 // JR 07.01.2005 Debug : Open the Gate of the coupledNode closed by SetWaitingStates
2458       GraphBase::OutPort * anOutPort = aLabelNode->GetChangeNodeInGate()->GetOutPort() ;
2459       if ( anOutPort ) {
2460 //JR 21.02.2005 Debug Memory leak :        CORBA::Any * anAny = new CORBA::Any() ;
2461         CORBA::Any anAny = CORBA::Any() ;
2462 //JR 21.02.2005 Debug Memory leak :        *anAny <<= (long ) 1 ;
2463         anAny <<= (long ) 1 ;
2464         anOutPort->SetValue( anAny ) ;
2465         aLabelNode->GetChangeNodeInGate()->PortState( SUPERV::ReadyState ) ;
2466 //        delete anAny ;
2467       }
2468       for ( j = 0 ; j < aLabelNode->GetNodeInPortsSize() ; j++ ) {
2469         const GraphBase::InPort * anInPort = aLabelNode->GetNodeInPort( j ) ;
2470         if ( anInPort->GetOutPort() ) {
2471 #if SuccessActionTrace
2472           cdebug << aLabelNode->Name() << "(" << anInPort->PortName() << ") value : "
2473                  << anInPort->GetOutPort()->NodeName() << "(" << anInPort->GetOutPort()->PortName() << ")"
2474                  << endl ;
2475 #endif
2476         }
2477       }
2478 //PAL8176 ==> PAL8516
2479 //JR 24.03.2005 Debug : the number of OutPorts of a GOTONode and of InPorts of its linked
2480 //                      InLine node must be the same
2481       if ( GetNodeOutPortsSize() != aLabelNode-> GetNodeInPortsSize() ) {
2482         cdebug << pthread_self() << "/" << ThreadNo()
2483                << " Successed_SuccessAction # number of ports " << GetNodeOutPortsSize()
2484                << " != " << aLabelNode-> GetNodeInPortsSize() << endl ;
2485         SendEvent( GraphExecutor::ErrorEvent ) ;
2486         return 0 ;
2487       }
2488       else {
2489         for ( j = 0 ; j < GetNodeOutPortsSize() ; j++ ) {
2490           GraphBase::OutPort * aBusParamOutPort = GetChangeNodeOutPort( j ) ;
2491           if ( !aBusParamOutPort->IsGate() ) {
2492             GraphBase::InPort * aBusParamChangeInPort = NULL ;
2493             if ( aBusParamOutPort->IsLoop() ) {
2494 // For EndLoop do not copy EndLoop(DoLoop) in Loop(InLoop)
2495 //            aBusParamChangeInPort = aLabelNode->GetChangeNodeInLoop() ;
2496             }
2497             else {
2498               aBusParamChangeInPort = aLabelNode->GetChangeInPort( aBusParamOutPort->PortName() ) ;
2499             }
2500             if ( aBusParamChangeInPort ) {
2501               aBusParamChangeInPort->ChangeOutPort( aBusParamOutPort ) ;
2502 #if SuccessActionTrace
2503               cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name() << " ChangeOutPort to HeadNode "
2504                      << aLabelNode->Name() << "(" << aBusParamChangeInPort->PortName() << ") from port "
2505                      << aBusParamOutPort->PortName() << endl ;
2506 #endif
2507             }
2508             else if ( IsGOTONode() ) {
2509 //PAL8176 ==> PAL8516
2510 //JR 24.03.2005 Debug : the names of OutPorts of a GOTONode and of InPorts of its linked
2511 //                      InLine node must be the same
2512               cdebug << pthread_self() << "/" << ThreadNo()
2513                      << " Successed_SuccessAction # names of ports "
2514                      << aBusParamOutPort->PortName() << endl ;
2515               SendEvent( GraphExecutor::ErrorEvent ) ;
2516               return 0 ;
2517             }
2518           }
2519         }
2520       }
2521     }
2522
2523 //JR 15.04.2005 Debug PAL8624 RetroConception :
2524 // THERE IS ONLY ONE NODE COUPLED TO A GOTONODE OR AN ENDLOOPNODE BUT Mutex/Lock for consistency
2525     if ( aLabelNode ) {
2526       const GraphBase::InPort * aGateInPort = aLabelNode->GetNodeInGate() ;
2527       if ( aGateInPort ) {
2528         if ( aGateInPort->GetOutPort() ) {
2529 //JR 21.02.2005 Debug Memory leak :          aGateInPort->GetOutPort()->Value( aGateOutPort->Value() ) ;
2530 //JR 30.03.2005          aGateInPort->GetOutPort()->Value( *aGateOutPort->Value() ) ;
2531           aGateInPort->GetOutPort()->SetValue( aGateOutPort->Value() ) ;
2532         }
2533 //JR 15.04.2005 Debug PAL8624 RetroConception :
2534         if ( !aLabelNode->SendSomeDataReady( Name() ) ) {
2535           cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "
2536                  << Name() << " SendSomeDataReady to " << aLabelNode->Name() << " ERROR"
2537                  << endl ;
2538 //JR 30.06.2005 :
2539           SendEvent( GraphExecutor::ErrorEvent ) ;
2540           return 0 ;
2541         }
2542         if ( aLabelNode->HasAllDataReady() ) {
2543           aLabelNode->ThreadNo( pthread_self() ) ;
2544           aLabelNode->CreateNewThread( false ) ;
2545           aLabelNode->RewindStack( RewindStack() ) ;
2546           aLabelNode->HasAllDataReady( false ) ;
2547           res = aLabelNode->SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
2548         }
2549       }
2550       else {
2551         cdebug << pthread_self() << "/" << ThreadNo() << " ERROR in Successed_SuccessAction of " << Name()
2552                << " NO port " << aGateOutPort->PortName() << " in "
2553                << aLabelNode->Name() << endl;
2554       }
2555     }
2556   }
2557
2558 //JR Step B
2559 //==================================================
2560 // JR 09.02.2005 : this is not a EndLoop or a GOTO :
2561 //==================================================
2562   else { // Not a EndLoop or a GOTO
2563 #if SuccessActionTrace
2564     cdebug << ThreadNo() << " Successed_SuccessAction of " << Name()
2565            << " with " << LinkedNodesSize() << " linked nodes :" ;
2566     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2567       cdebug << " " << LinkedNodes( i )->Name() ;
2568     }
2569     cdebug << endl;
2570 #endif
2571 //JR 15.04.2005 Debug PAL8624 RetroConception :
2572 // If this is a LoopNode and if DoLoopPort == false, we go directly to the EndOfLoopNode and
2573 // we do not activate Nodes within the loop
2574     bool IgnoreForEndLoop = false ;
2575 // If this is a SwitchNode and if DefaultOutPort == true, we do not activate Nodes within Switch
2576 // We activate directly the EnSwitch
2577 // BUT the NotSwitchBranch(es) are NOT activated :
2578     bool IgnoreForDefaultSwitch = false ;
2579     if ( IsLoopNode() ) {
2580       GraphBase::OutPort * fromLoopOutPort = GetChangeNodeOutLoop() ;
2581       if ( !fromLoopOutPort->BoolValue() ) { // Ne pas faire la boucle
2582         IgnoreForEndLoop = true ;
2583       }
2584     }
2585     else if ( IsSwitchNode() ) {
2586       const GraphBase::OutPort * anOutGatePort = GetNodeOutGate() ;
2587       if ( anOutGatePort->BoolValue() && anOutGatePort->InPortsSize() ) { // DefaultPort is activated
2588 // The DefaultOutPort of that SwitchNode is true and is connected
2589         IgnoreForDefaultSwitch = true ;
2590       }
2591     }
2592
2593 //Loop of LinkedNodes for SendSomeDataReady :
2594     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2595       GraphBase::ComputingNode * aComputingNode ;
2596       aComputingNode = (GraphBase::ComputingNode * ) LinkedNodes( i ) ;
2597       toNode = (GraphExecutor::InNode *) aComputingNode->GetInNode() ;
2598 #if SuccessActionTrace
2599       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction of " << Name()
2600              << " [" << i << "] " << LinkedNodes( i )->Name() << " toNode " << toNode
2601              << " IgnoreForEndLoop " << IgnoreForEndLoop ;
2602       if ( toNode ) {
2603         cdebug << " " << toNode->Kind() << endl ;
2604       }
2605 #endif
2606 //JR 15.04.2005 Debug PAL8624 RetroConception :
2607       if ( toNode ) {
2608 //JR 18.05.2005 : we must lock because of concurrent SendEvent if NotAllDataReady :
2609         toNode->LockDataReady() ;
2610         if ( IsComputingNode() && toNode->IsInLineNode() ) {
2611           GraphBase::InPort * toGateInPort = toNode->GetChangeNodeInGate() ;
2612           toGateInPort->PortState( SUPERV::ReadyState ) ;
2613           GraphBase::OutPort * GateOutPort = toGateInPort->GetOutPort() ;
2614           if ( GateOutPort ) {
2615             GateOutPort->PortStatus( DataConnected );
2616             GateOutPort->PortState( SUPERV::ReadyState ) ;
2617             GateOutPort->PortDone( true ) ;
2618           }
2619         }
2620
2621 //JR 15.04.2005 Debug PAL8624 RetroConception :
2622         if ( IsLoopNode() ) {
2623           if ( IgnoreForEndLoop && !strcmp( toNode->Name() , CoupledNode()->Name() ) ) {
2624             GraphBase::InPort * toLoopInPort ;
2625             toLoopInPort = toNode->GetChangeNodeInLoop() ;
2626             if ( toLoopInPort->PortState() != SUPERV::ReadyState ) {
2627               toLoopInPort->PortState( SUPERV::ReadyState ) ;
2628             }
2629           }
2630         }
2631 //JR 15.04.2005 Debug PAL8624 RetroConception :
2632         else if ( toNode->IsInLineNode() ) {
2633           int j ;
2634           for ( j = 0 ; j < toNode->GetNodeInPortsSize() ; j++ ) {
2635             toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
2636           }
2637         }
2638
2639         bool activatetoNode = true ;
2640 //We have to execute the loop :
2641         if ( !IgnoreForEndLoop ) {
2642 //The loop is not finished :
2643           if (  toNode->IsLoopNode() ) {
2644 //We enter in a new loop :
2645             GraphBase::InPort * toLoopInPort = toNode->GetChangeNodeInLoop() ;
2646             toLoopInPort->PortState( SUPERV::ReadyState ) ;
2647             GraphBase::OutPort * LoopOutPort = toLoopInPort->GetOutPort() ;
2648             LoopOutPort->PortStatus( DataConnected );
2649             LoopOutPort->PortState( SUPERV::ReadyState ) ;
2650             LoopOutPort->PortDone( true ) ;
2651 //JR 21.02.2005 Debug Memory leak :          CORBA::Any * anAny = new CORBA::Any() ; // InitLoop
2652             CORBA::Any anAny = CORBA::Any() ; // InitLoop
2653 //JR 21.02.2005 Debug Memory leak :          *anAny <<= (long ) 1 ;
2654             anAny <<= (long ) 1 ;
2655             LoopOutPort->SetValue( anAny ) ;
2656             int j ;
2657             for ( j = 0 ; j < toNode->GetNodeInPortsSize() ; j++ ) {
2658               toNode->GetChangeNodeInPort( j )->InitialOutPort() ;
2659             }
2660           }
2661         }
2662 //The loop is finished :
2663         else if ( IsLoopNode() ) {
2664           if ( toNode->IsEndLoopNode() ) {
2665 //Not the corresponding EndLoopNode :
2666             if ( strcmp( toNode->Name() , CoupledNode()->Name() ) ) {
2667 #if SuccessActionTrace
2668               cdebug << pthread_self() << "/" << ThreadNo()
2669                      << " Successed_SuccessAction NO activate EndLoopNode " << toNode->Name()
2670                      << endl ;
2671 #endif
2672               activatetoNode = false ;
2673             }
2674           }
2675 //Not a EndLoopNode :
2676           else {
2677 #if SuccessActionTrace
2678             cdebug << pthread_self() << "/" << ThreadNo()
2679                    << " Successed_SuccessAction NO activate node " << toNode->Name() << endl ;
2680 #endif
2681             activatetoNode = false ;
2682           }
2683         }
2684
2685 // If the DefaultPort of that SwitchNode is connected to the DefaultPort of the EndSwitchNode
2686 // the NotSwitchBranch(es) are NOT activated :
2687         if ( IgnoreForDefaultSwitch ) {
2688 //We have to activate Default to EndSwitchNode
2689 #if SuccessActionTrace
2690           cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction search "
2691                  << toNode->Name() << " among linked nodes to DefaultPort of " << Name()
2692                  << "IgnoreForDefaultSwitch" << IgnoreForDefaultSwitch << endl ;
2693 #endif
2694           activatetoNode = false ;
2695           const GraphBase::OutPort * anOutGatePort = GetNodeOutGate() ;
2696           const GraphBase::InPort * anInPort = NULL ;
2697           int j ;
2698           for ( j = 0 ; j < anOutGatePort->InPortsSize() ; j++ ) {
2699             anInPort = anOutGatePort->InPorts( j ) ;
2700             const GraphBase::ComputingNode * aNode ;
2701             aNode = _OutNode->Graph()->GetGraphNode( anInPort->NodeName() ) ;
2702             if ( aNode ) {
2703 #if SuccessActionTrace
2704               cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction try "
2705                      << aNode << " " << aNode->Name() << " == " << toNode << " " << toNode->Name()
2706                      << endl ;
2707 #endif
2708             }
2709             if ( aNode && (const GraphBase::ComputingNode * ) toNode->ComputingNode() == aNode ) {
2710 // toNode is connected to the DefaultPort of that SwitchNode :
2711 #if SuccessActionTrace
2712               cdebug << pthread_self() << "/" << ThreadNo()
2713                      << " Successed_SuccessAction activate node " << aNode->Name() << endl ;
2714 #endif
2715               activatetoNode = true ;
2716               break ;
2717             }
2718             else {
2719 #if SuccessActionTrace
2720               cdebug << pthread_self() << "/" << ThreadNo()
2721                      << " Successed_SuccessAction NO activate node " << aNode->Name() << endl ;
2722 #endif
2723             }
2724           }
2725         }
2726 //JR 19.04.2005 Debug : Do not activate the EndSwitchNode if DefaultGate is close.
2727 //JR 20.04.2005 : it is false : an outport of the SwitchNode may be connected to an
2728 //                              input port of the EndSwitchNode
2729         if ( activatetoNode ) {
2730 #if SuccessActionTrace
2731           cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "
2732                  << toNode->Name() << "->SendSomeDataReady( " << Name() << " )" << endl ;
2733 #endif
2734           if ( !toNode->SendSomeDataReady( Name() ) ) {
2735             cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "
2736                  << Name() << " SendSomeDataReady to " << toNode->Name() << " ERROR"
2737                  << endl ;
2738 //JR 30.06.2005 :
2739             toNode->UnLockDataReady() ;
2740             SendEvent( GraphExecutor::ErrorEvent ) ;
2741             return 0 ;
2742           }
2743         }
2744         toNode->UnLockDataReady() ;
2745       }
2746     } //End of Loop of LinkedNodes for SendSomeDataReady
2747
2748 //JR 10.02.2005 : Debug at the end of execution of a SwitchNode :
2749 // Here after we may start execution of only one SwitchBranch or of the Default
2750 // But with activation of only one SwitchBranch we may activate several nodes of that SwitchBranch and
2751 // we may activate several nodes of NotSwitchBranch ( a NotSwitchBranch is a Branch of the Switch
2752 // where GatePorts of Nodes are not connected ; that Branches are always executed for each of SwitchBranch
2753 // BUT are not executed when Default is activated).
2754     if ( IsSwitchNode() ) {
2755       GraphBase::InLineNode * anEndSwitchNode = GOTONode()->CoupledNode() ;
2756 //The InPorts of the EndSwitchNode may be connected from that SwitchNode
2757 //So at first, if we activate a SwitchBranch, we have to establish the correct OutPort in the InPorts
2758 // of the EndSwitchNode (for the SwitchBranch and the NOTSwitchBranch[es] :
2759 //PAL8517
2760 // So the bug is that all input ports of the corresponding EndSwitchNode must have the status NOTDONE !
2761 // (Only if Default OutPort is closed and Default InPort is closed) :
2762       if ( !GetNodeOutGate()->BoolValue() && anEndSwitchNode->GetNodeInGate()->GetOutPort() &&
2763            !anEndSwitchNode->GetNodeInGate()->GetOutPort()->BoolValue() ) {
2764 #if SuccessActionTrace
2765         cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << anEndSwitchNode->Name()
2766                << " reset of InPort()->OutPort()->Done flag in EndSwitch" << endl ;
2767 #endif
2768         int i ;
2769         for ( i = 0 ; i < anEndSwitchNode->GetNodeInPortsSize() ; i++ ) {
2770           GraphBase::OutPort * anOutPort = anEndSwitchNode->GetChangeNodeInPort( i )->GetOutPort() ;
2771 //PAL8519
2772 //JR 08.03.2005 Debug : update of state only if not a StreamPort
2773           if ( anOutPort && strcmp( anOutPort->NodeName() , Name() ) &&
2774                !anOutPort->IsDataStream() ) {
2775 #if SuccessActionTrace
2776             cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "
2777                    << anEndSwitchNode->Name() << " InPort "
2778                    << anEndSwitchNode->GetChangeNodeInPort( i )->PortName() << " NOTDONE from "
2779                    << anOutPort->NodeName() << " " << anOutPort->PortName() << endl ;
2780 #endif
2781             anEndSwitchNode->GetChangeNodeInPort( i )->PortState( SUPERV::WaitingState ) ;
2782             anEndSwitchNode->GetChangeNodeInPort( i )->GetOutPort()->PortDone( false ) ;
2783           }
2784           else {
2785 #if SuccessActionTrace
2786             cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "
2787                    << anEndSwitchNode->Name() << " InPort "
2788                    << anEndSwitchNode->GetChangeNodeInPort( i )->PortName() << " NOT Changed : directly from "
2789                    << anOutPort->NodeName() << " " << anOutPort->PortName() << endl ;
2790 #endif
2791           }
2792         }
2793       }
2794       else {
2795 #if SuccessActionTrace
2796         cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name()
2797                << " " << Kind() << " OutGate->Value " << GetNodeOutGate()->BoolValue()
2798                << " NO reset of InPort()->OutPort()->Done flag in EndSwitch" << endl ;
2799 #endif
2800       }
2801     }
2802
2803 //JR 15.04.2005 Debug PAL8624 RetroConception :
2804 //Make the list of nodes to activate :
2805     for ( i = 0 ; i < LinkedNodesSize() ; i++ ) {
2806       GraphBase::ComputingNode * aComputingNode ;
2807       aComputingNode = (GraphBase::ComputingNode * ) LinkedNodes( i ) ;
2808       toNode = (GraphExecutor::InNode *) aComputingNode->GetInNode() ;
2809       if ( toNode ) { // Only Not DataFlowNode :
2810         toNode->LockDataReady() ; // Only ONE Node may send AllDataReadyEvent to an other node
2811         if ( toNode->HasAllDataReady() ) {
2812           SomeDataNodes.push_back( toNode ) ;
2813           toNode->HasAllDataReady( false ) ;
2814 #if SuccessActionTrace
2815           cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction "
2816                  << Name() << " push "
2817                  << toNode->Name() << " " << SomeDataNodes.size() << endl ;
2818 #endif
2819         }
2820         toNode->UnLockDataReady() ;
2821       }
2822     }
2823
2824 // firsttoNode : node that has the same ThreadNo() as the current node and that have to be activated
2825 //JR 15.04.2005 Debug PAL8624 RetroConception :
2826 //Activation of nodes that have AllDataReady in a new thread except one :
2827     while ( SomeDataNodes.size() > 1 ) {
2828       GraphExecutor::InNode *aNode = SomeDataNodes.front() ;
2829       SomeDataNodes.pop_front() ;
2830 #if SuccessActionTrace
2831       cdebug << pthread_self() << "/" << ThreadNo()
2832              << " Successed_SuccessAction pop size "
2833              << SomeDataNodes.size() << " " << aNode->Name() << endl ;
2834       cdebug << pthread_self() << "/" << ThreadNo() << " " << aNode->Name()
2835              << " Successed_SuccessAction poped and will start in a new thread" << endl ;
2836 #endif
2837       aNode->CreateNewThread( true ) ;
2838       _OutNode->IncrCreatedThreads() ;
2839 //JR 15.04.2005 Debug PAL8624 RetroConception :
2840       res = aNode->SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
2841     }
2842
2843 //Activation of the last node that have AllDataReady in the same thread :
2844     if ( SomeDataNodes.size() ) {
2845       firsttoNode = SomeDataNodes.front() ;
2846       SomeDataNodes.pop_front() ;
2847     }
2848     if ( firsttoNode ) {
2849 #if SuccessActionTrace
2850       cdebug << pthread_self() << "/" << ThreadNo()
2851              << " Successed_SuccessAction start firsttoNode "
2852              << SomeDataNodes.size() << " " << firsttoNode->Name() << endl ;
2853 #endif
2854 //      firsttoNode->CreateNewThreadIf( false ) ;
2855       firsttoNode->CreateNewThread( false ) ;
2856       firsttoNode->RewindStack( RewindStack() ) ;
2857       if ( firsttoNode->State() == GraphExecutor::SuccessedState ) {
2858 #if SuccessActionTrace
2859         cdebug << pthread_self() << "/" << ThreadNo() << " " << Name()
2860                << " : " << firsttoNode->Name() << " "
2861                << Automaton()->StateName( firsttoNode->State() )
2862                << " --> DataWaitingState for Thread "
2863                << firsttoNode->ThreadNo() << endl ;
2864 #endif
2865         firsttoNode->State( GraphExecutor::DataWaitingState ) ;
2866       }
2867       firsttoNode->ThreadNo( pthread_self() ) ;
2868 // On continue avec le meme thread
2869       ThreadNo( 0 ) ;
2870 #if SuccessActionTrace
2871       cdebug << pthread_self() << "/" << ThreadNo() << " Successed_SuccessAction " << Name()
2872              << " for firsttoNode " << firsttoNode->Name()
2873              << " " << Automaton()->StateName( firsttoNode->State() ) << endl ;
2874 #endif
2875 //JR 15.04.2005 Debug PAL8624 RetroConception :
2876 //No creation of thread and with LockDataReady, an other node in an other thread cannot be
2877 // waiting for that lock ( if it was the case we could not find AllDataReady for firsttoNode
2878       res = firsttoNode->SendEvent( GraphExecutor::AllDataReadyEvent ); // ==> Ready to execute
2879     }
2880     else {
2881 #if SuccessActionTrace
2882       cdebug << ThreadNo() << " Successed_SuccessAction " << Name()
2883              << " NO DataReady ==> ThreadNo( 0 ) firsttoNode == NULL" << endl ;
2884 #endif
2885       ThreadNo( 0 ) ;
2886     }
2887   }
2888 #if SuccessActionTrace
2889   cdebug_out << pthread_self() << "/" << ThreadNo()
2890              << " Successed_SuccessAction " << Name() << endl;
2891 #endif
2892   return 1 ;
2893 }
2894
2895 #define SendSomeDataReadyTrace 1
2896 bool GraphExecutor::InNode::SendSomeDataReady( char * FromNodeName ) {
2897   bool RetVal = false ;
2898   if ( IsDataFlowNode() ) {
2899 #if SendSomeDataReadyTrace
2900     cdebug_in << ThreadNo() << "InNode::SendSomeDataReady " << FromNodeName
2901               << " send Result to graph " << Name() << endl;
2902 #endif
2903   }
2904   else {
2905 #if SendSomeDataReadyTrace
2906     cdebug_in << pthread_self() << "/" << ThreadNo() << FromNodeName
2907               << " GraphExecutor::InNode::SendSomeDataReady to " << Name() << " State "
2908               << Automaton()->StateName( State() ) << endl;
2909 #endif
2910     if ( State() == GraphExecutor::SuccessedState ||
2911          State() == GraphExecutor::SuspendedSuccessedState ||
2912          State() == GraphExecutor::SuspendedSuccessedToReStartState ) {
2913 #if SendSomeDataReadyTrace
2914       cdebug << ThreadNo() << " " << FromNodeName
2915              << " : " << Name() << " " << Automaton()->StateName( State() )
2916              << " --> DataWaitingState for Thread "
2917              << ThreadNo() << " " << endl ;
2918 #endif
2919       State( GraphExecutor::DataWaitingState ) ;
2920     }
2921 // We begin that LoopNode if SendSomeDataReady does not come from the corresponding EndLoopNode
2922     if ( IsLoopNode() && strcmp( LoopNode()->CoupledNodeName() , FromNodeName ) ) {
2923 #if SendSomeDataReadyTrace
2924       cdebug << ThreadNo() << "InNode::SendSomeDataReady " << Name() << " Set _InitLoop from "
2925              << FromNodeName << endl ;
2926 #endif
2927       _InitLoop = true ;
2928     }
2929 #if SendSomeDataReadyTrace
2930     cdebug << "SendEvent( SomeDataReadyEvent )" << endl ;
2931 #endif
2932 //JR 15.04.2005 Debug PAL8624 RetroConception :
2933     DataFromNode( FromNodeName ) ;
2934 //    RetVal = !SendEvent( GraphExecutor::SomeDataReadyEvent );
2935     RetVal = SendEvent( GraphExecutor::SomeDataReadyEvent );
2936 //JR 15.04.2005 Debug PAL8624 RetroConception :
2937   }
2938 #if SendSomeDataReadyTrace
2939   cdebug_out << pthread_self() << "/" << ThreadNo() << FromNodeName
2940              << " GraphExecutor::InNode::SendSomeDataReady to " << Name() << " State "
2941              << Automaton()->StateName( State() ) << " " << RetVal << endl;
2942 #endif
2943   return RetVal ;
2944 }
2945
2946 int GraphExecutor::InNode::Errored_ErrorAction() {
2947   cdebug << ThreadNo() << " Errored_ErrorAction " << Name()
2948          << " will pthread_exit" << endl;
2949
2950   _OutNode->NodeAborted( Name() ) ;
2951
2952   DoneAction() ;
2953   return 1 ;
2954 }
2955
2956 int GraphExecutor::InNode::Successed_SuspendAction() {
2957   cdebug << ThreadNo() << " Successed_SuspendAction -->Suspend " << Name()
2958          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
2959          << _OutNode->SuspendedThreads() << endl;
2960   _OutNode->PushEvent( this , GraphExecutor::SuspendedSuccessedEvent ,
2961                        GraphExecutor::SuspendedSuccessedState ) ; 
2962   DoneAction() ;
2963   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
2964   cdebug << ThreadNo() << " Successed_SuspendAction Resumed " << Name() ;
2965   if ( aReStartNode ) {
2966     _aReStartNode = NULL ;
2967     cdebug << " for " << aReStartNode->Name() << endl;
2968     aReStartNode->SendEvent( _aReStartEvent ) ;
2969   }
2970   else {
2971     cdebug << endl;
2972     SendEvent( GraphExecutor::ResumeEvent ) ;
2973   }
2974   return 1 ;
2975 }
2976
2977 int GraphExecutor::InNode::Errored_SuspendAction() {
2978   cdebug << ThreadNo() << " Errored_SuspendAction -->Suspend " << Name()
2979          << " Threads " << _OutNode->Threads() << " SuspendedThreads "
2980          << _OutNode->SuspendedThreads() << endl;
2981   _OutNode->PushEvent( this , GraphExecutor::SuspendedErroredEvent ,
2982                        GraphExecutor::SuspendedErroredState ) ; 
2983
2984   _OutNode->NodeAborted( Name() ) ;
2985
2986   DoneAction() ;
2987   GraphExecutor::InNode * aReStartNode = SuspendAction() ;
2988   cdebug << ThreadNo() << " Errored_SuspendAction Resumed " << Name()
2989          << endl;
2990   if ( aReStartNode ) {
2991     _aReStartNode = NULL ;
2992     aReStartNode->SendEvent( _aReStartEvent ) ;
2993   }
2994   else {
2995     SendEvent( GraphExecutor::ResumeEvent ) ;
2996   }
2997   return 1 ;
2998 }
2999
3000 int GraphExecutor::InNode::SuspendedSuccessed_ResumeAction() {
3001   cdebug << ThreadNo() << " SuspendedSuccessed_ResumeAction " << Name() << endl;
3002 //  ResumeAction() ;
3003   _OutNode->PushEvent( this , GraphExecutor::ResumedSuccessedEvent ,
3004                        GraphExecutor::ResumedSuccessedState ) ; 
3005   SendEvent( ResumedSuccessedEvent ) ;
3006   return 1 ;
3007 }
3008
3009 int GraphExecutor::InNode::SuspendedErrored_ResumeAction() {
3010   cdebug << ThreadNo() << " SuspendedErrored_ResumeAction " << Name() << endl;
3011 //  ResumeAction() ;
3012   _OutNode->PushEvent( this , GraphExecutor::ResumedErroredEvent ,
3013                        GraphExecutor::ResumedErroredState ) ; 
3014
3015   _OutNode->NodeAborted( Name() ) ;
3016
3017   SendEvent( ResumedErroredEvent ) ;
3018   return 1 ;
3019 }
3020
3021 int GraphExecutor::InNode::Successed_KillAction() {
3022   KillAction() ;
3023   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
3024                        GraphExecutor::KilledSuccessedState ) ; 
3025   cdebug << ThreadNo() << " Successed_KillAction " << Name() << endl;
3026   return 1 ;
3027 }
3028
3029 int GraphExecutor::InNode::Errored_KillAction() {
3030   KillAction() ;
3031   _OutNode->PushEvent( this , GraphExecutor::KilledEvent ,
3032                        GraphExecutor::KilledErroredState ) ; 
3033
3034   _OutNode->NodeAborted( Name() ) ;
3035
3036   cdebug << ThreadNo() << " Errored_KillAction " << Name() << endl;
3037   return 1 ;
3038 }
3039
3040 int GraphExecutor::InNode::Successed_StopAction() {
3041   StopAction() ;
3042   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
3043                        GraphExecutor::StoppedSuccessedState ) ; 
3044   cdebug << ThreadNo() << " Successed_StopAction " << Name() << endl;
3045   return 1 ;
3046 }
3047
3048 int GraphExecutor::InNode::Errored_StopAction() {
3049   StopAction() ;
3050   _OutNode->PushEvent( this , GraphExecutor::StoppedEvent ,
3051                        GraphExecutor::StoppedErroredState ) ; 
3052
3053   _OutNode->NodeAborted( Name() ) ;
3054
3055   cdebug << ThreadNo() << " Errored_StopAction " << Name() << endl;
3056   return 1 ;
3057 }
3058
3059 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAction() {
3060   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction " << Name() << endl;
3061   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
3062                        GraphExecutor::ReStartedState ) ;
3063   int i ;
3064   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
3065     GetChangeNodeInPort( i )->PortState( SUPERV::ReadyState ) ;
3066   }
3067   SendEvent( ExecuteEvent ) ;
3068   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAction "  << Name() << endl;
3069   return 1 ;
3070 }
3071
3072 int GraphExecutor::InNode::SuspendedErrored_ReStartAction() {
3073   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction " << Name() << endl;
3074   _OutNode->PushEvent( this , GraphExecutor::ReStartedEvent ,
3075                        GraphExecutor::ReStartedState ) ; 
3076   int i ;
3077   for ( i = 0 ; i < GetNodeInPortsSize() ; i++ ) {
3078     GetChangeNodeInPort( i )->PortState( SUPERV::ReadyState ) ;
3079   }
3080   SendEvent( ExecuteEvent ) ;
3081   cdebug << ThreadNo() << " SuspendedErrored_ReStartAction "  << Name() << endl;
3082   return 1 ;
3083 }
3084
3085 int GraphExecutor::InNode::SuspendedSuccessed_ReStartAndSuspendAction() {
3086   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction " << Name()
3087          << endl;
3088   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
3089                        GraphExecutor::ReStartedState ) ; 
3090   State( GraphExecutor::DataWaitingState ) ;
3091   if ( !Suspend() ) {
3092     cdebug << "InNode::Suspend() Node " << Name() << endl ;
3093     return false ;
3094   }
3095   else if ( SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
3096     cdebug << "InNode::SendEvent( SomeDataReadyEvent ) Node "
3097            << Name() << endl ;
3098     return false ;
3099   }
3100   cdebug << ThreadNo() << " SuspendedSuccessed_ReStartAndSuspendAction "  << Name()
3101          << endl;
3102   return 1 ;
3103 }
3104
3105 int GraphExecutor::InNode::SuspendedErrored_ReStartAndSuspendAction() {
3106   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction " << Name()
3107          << endl;
3108   _OutNode->PushEvent( this , GraphExecutor::ReStartedAndSuspendEvent ,
3109                        GraphExecutor::ReStartedState ) ; 
3110   State( GraphExecutor::DataWaitingState ) ;
3111   if ( !Suspend() ) {
3112     cdebug << "InNode::Suspend() Node " << Name() << endl ;
3113     return false ;
3114   }
3115   else if ( SendEvent( GraphExecutor::SomeDataReadyEvent ) ) {
3116     cdebug << "InNode::SendEvent( SomeDataReadyEvent ) Node "
3117            << Name() << endl ;
3118     return false ;
3119   }
3120   cdebug << ThreadNo() << " SuspendedErrored_ReStartAndSuspendAction "  << Name()
3121          << endl;
3122   return 1 ;
3123 }
3124
3125 #define InParametersSetTrace 1
3126 void GraphExecutor::InNode::InParametersSet( bool & Err ,
3127                                              int  nInParams ,
3128                                              ServicesAnyData * InParametersList ) {
3129   int i ;
3130 #if InParametersSetTrace
3131   cdebug << pthread_self() << "/" << ThreadNo() << " InParametersSet " << Name() << endl ;
3132 #endif
3133   for ( i = 0 ; i < nInParams ; i++ ) {
3134     ServicesAnyData D = InParametersList[i];
3135     GraphBase::InPort * anInPort = GetChangeNodeInPort(i) ;
3136     GraphBase::OutPort * theOutPort = anInPort->GetOutPort() ;
3137     if ( anInPort->IsGate() && theOutPort == NULL ) {
3138 #if InParametersSetTrace
3139       cdebug << ThreadNo() << " ArgIn" << i << " " << D.Name << " "
3140              << anInPort->GetServicesParameter().Parametertype
3141              << " is inactive. " << anInPort->Kind() << endl ;
3142 #endif
3143     }
3144     else if ( anInPort->PortState() == SUPERV::ReadyState ) {
3145       if ( anInPort->IsGate() ) {
3146 //JR 21.02.2005 Debug Memory leak :        CORBA::Any * anAny = new CORBA::Any() ;
3147         CORBA::Any anAny = CORBA::Any() ;
3148 //JR 21.02.2005 Debug Memory leak :        *anAny <<= (long ) 0 ;
3149         anAny <<= (long ) 0 ;
3150         theOutPort->SetValue( anAny ) ;
3151 //        delete anAny ;
3152       }
3153       if ( !anInPort->IsDataStream() &&
3154            !anInPort->IsDataConnected() ) {
3155         anInPort->PortState( SUPERV::WaitingState ) ;
3156       }
3157 //JR 18.02.2005 Debug Memory leak : delete does not destroy that string ...
3158 //      D.Name = CORBA::string_dup( anInPort->GetServicesParameter().Parametername ) ;
3159       D.Name = anInPort->PortName() ;
3160 //JR 30.03.2005      const CORBA::Any * AnyPtr = theOutPort->Value() ;
3161       const CORBA::Any AnyRef = theOutPort->Value() ;
3162 #if InParametersSetTrace
3163       cdebug << ThreadNo() << " ArgIn" << i << " " << anInPort->Kind() << " "
3164              << anInPort->PortState() << " " << D.Name << " "
3165              << anInPort->GetServicesParameter().Parametertype << endl ;
3166 #endif
3167 //JR 30.03.2005      D.Value = * AnyPtr ; // CORBA::Any
3168       D.Value = AnyRef ; // CORBA::Any
3169 //JR 18.02.2005 Debug Memory leak :       string _Type = CORBA::string_dup( anInPort->GetServicesParameter().Parametertype ) ;
3170 //      const char * Type = _Type.c_str() ;
3171       const char * Type = anInPort->GetServicesParameter().Parametertype ;
3172       switch ( D.Value.type()->kind() ) { // { string , long , double , objref }
3173       case CORBA::tk_string:
3174         char * t;
3175         D.Value >>= t;
3176 #if InParametersSetTrace
3177         cdebug << t << " (string)" ;
3178 #endif
3179         if ( !strcmp( Type , "string" ) ) {
3180         }
3181         else if ( !strcmp( Type , "boolean" ) ) {
3182           bool b ;
3183           long d ;
3184           sscanf( t , "%ld" , &d ) ;
3185           b = (bool ) d ;
3186           D.Value <<=  (CORBA::Any::from_boolean ) b ;
3187 //          theOutPort->Value( D.Value ) ;
3188         }
3189         else if ( !strcmp( Type , "char" ) ) {
3190           unsigned char c ;
3191           long d ;
3192           sscanf( t , "%ld" , &d ) ;
3193           c = (short ) d ;
3194           D.Value <<=  (CORBA::Any::from_char ) c ;
3195 #if InParametersSetTrace
3196           cdebug << "string '" << t << "' --> " << d << " --> char " << c ;
3197 #endif
3198 //          theOutPort->Value( D.Value ) ;
3199         }
3200         else if ( !strcmp( Type , "short" ) ) {
3201           short s ;
3202           long d ;
3203           sscanf( t , "%ld" , &d ) ;
3204           s = (short ) d ;
3205           D.Value <<=  s ;
3206 #if InParametersSetTrace
3207           cdebug << "string '" << t << "' --> " << d << " --> short " << s ;
3208 #endif
3209 //          theOutPort->Value( D.Value ) ;
3210         }
3211         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
3212           long l ;
3213           sscanf( t , "%ld" , &l ) ;
3214           D.Value <<=  l ;
3215 #if InParametersSetTrace
3216           cdebug << "string '" << t << " --> long " << l ;
3217 #endif
3218 //          theOutPort->Value( D.Value ) ;
3219         }
3220         else if ( !strcmp( Type , "float" ) ) {
3221           double d ;
3222           sscanf( t , "%lf" , &d ) ;
3223           float f = d ;
3224           D.Value <<= f ;
3225 #if InParametersSetTrace
3226           cdebug << "string '" << t << "' --> " << setw(25) << setprecision(18) << d << " --> float " << " = "
3227                  << setw(25) << setprecision(18) << f ;
3228 #endif
3229 //          theOutPort->Value( D.Value ) ;
3230         }
3231         else if ( !strcmp( Type , "double" ) ) {
3232           double d ;
3233           sscanf( t , "%lf" , &d ) ;
3234           D.Value <<= d ;
3235 #if InParametersSetTrace
3236           cdebug << "string '" << t << " --> double " << setw(25) << setprecision(18) << d ;
3237 #endif
3238 //          theOutPort->Value( D.Value ) ;
3239         }
3240 //        else if ( !strcmp( Type , "objref" ) ) {
3241         else { // Default
3242           CORBA::Object_ptr ObjRef ;
3243           try {
3244             ObjRef = StringToObject( t ) ;
3245             D.Value <<= ObjRef ;
3246           }
3247           catch( ... ) {
3248             D.Value <<= CORBA::Object::_nil() ;
3249           }
3250 //          theOutPort->Value( D.Value ) ;
3251         }
3252 //        else {
3253 //          cdebug << " (other ERROR)" << endl ;
3254 //        }
3255 #if InParametersSetTrace
3256         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
3257 #endif
3258         break;
3259       case CORBA::tk_long:
3260 #if InParametersSetTrace
3261         cdebug << ThreadNo() << " " << Name() << " ArgIn" << i << " " << D.Name << " "
3262                << anInPort->GetServicesParameter().Parametertype << " " << anInPort->Kind()
3263                << " " ;
3264         theOutPort->StringValue( *GraphBase::Base::_fdebug ) ;
3265         cdebug << endl ;
3266 #endif
3267         long l;
3268         D.Value >>= l;
3269 #if InParametersSetTrace
3270         cdebug << l << " (long)" << endl ;
3271 #endif
3272         if ( !strcmp( Type , "string" ) ) {
3273           char t[40] ;
3274           sprintf( t , "%ld" , l ) ;
3275           D.Value <<= t ;
3276 //          theOutPort->Value( D.Value ) ;
3277         }
3278         else if ( !strcmp( Type , "boolean" ) ) {
3279           bool b ;
3280           b = (bool ) l ;
3281           D.Value <<=  (CORBA::Any::from_boolean ) b ;
3282 //          theOutPort->Value( D.Value ) ;
3283         }
3284         else if ( !strcmp( Type , "char" ) ) {
3285           unsigned char c ;
3286           c = (unsigned char ) l ;
3287           D.Value <<=  (CORBA::Any::from_char ) c ;
3288 //          theOutPort->Value( D.Value ) ;
3289         }
3290         else if ( !strcmp( Type , "short" ) ) {
3291           short s ;
3292           s = (short ) l ;
3293           D.Value <<=  s ;
3294 //          theOutPort->Value( D.Value ) ;
3295         }
3296         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
3297         }
3298         else if ( !strcmp( Type , "float" ) ) {
3299           float f ;
3300           f = (float ) l ;
3301           D.Value <<= f ;
3302 //          theOutPort->Value( D.Value ) ;
3303         }
3304         else if ( !strcmp( Type , "double" ) ) {
3305           double d ;
3306           d = (double ) l ;
3307           D.Value <<= d ;
3308 //          theOutPort->Value( D.Value ) ;
3309         }
3310 //        else if ( !strcmp( Type , "objref" ) ) {
3311         else { // Default
3312           D.Value <<= CORBA::Object::_nil() ;
3313 //          theOutPort->Value( D.Value ) ;
3314         }
3315 //        else {
3316 //          cdebug << " (other ERROR)" << endl ;
3317 //        }
3318 #if InParametersSetTrace
3319         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
3320 #endif
3321         break;
3322       case CORBA::tk_double:
3323         double d;
3324         D.Value >>= d;
3325 #if InParametersSetTrace
3326         cdebug << d << " (double)" << endl ;
3327 #endif
3328         if ( !strcmp( Type , "string" ) ) {
3329           char t[40] ;
3330           sprintf( t , "%lf" , d ) ;
3331           D.Value <<= t ;
3332 //          theOutPort->Value( D.Value ) ;
3333         }
3334         else if ( !strcmp( Type , "boolean" ) ) {
3335           bool b ;
3336           b = (bool ) d ;
3337           D.Value <<=  (CORBA::Any::from_boolean ) b ;
3338 //          theOutPort->Value( D.Value ) ;
3339         }
3340         else if ( !strcmp( Type , "char" ) ) {
3341           unsigned char c ;
3342           c = (unsigned char ) d ;
3343           D.Value <<=  (CORBA::Any::from_char ) c ;
3344 //          theOutPort->Value( D.Value ) ;
3345         }
3346         else if ( !strcmp( Type , "short" ) ) {
3347           short s ;
3348           s = (short ) d ;
3349           D.Value <<=  s ;
3350 //          theOutPort->Value( D.Value ) ;
3351         }
3352         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
3353           long l ;
3354           l = (long ) d ;
3355           D.Value <<= l ;
3356 //          theOutPort->Value( D.Value ) ;
3357         }
3358         else if ( !strcmp( Type , "float" ) ) {
3359           float f ;
3360           f = (float ) d ;
3361           D.Value <<= f ;
3362 //          theOutPort->Value( D.Value ) ;
3363         }
3364         else if ( !strcmp( Type , "double" ) ) {
3365         }
3366 //        else if ( !strcmp( Type , "objref" ) ) {
3367         else { // Default
3368           D.Value <<= CORBA::Object::_nil() ;
3369 //          theOutPort->Value( D.Value ) ;
3370         }
3371 //        else {
3372 //          cdebug << " (other ERROR)" << endl ;
3373 //        }
3374 #if InParametersSetTrace
3375         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
3376 #endif
3377         break;
3378       case CORBA::tk_objref:
3379         if ( !strcmp( Type , "string" ) ) {
3380           CORBA::Object_ptr ObjRef ;
3381           char * retstr ;
3382           try {
3383             D.Value >>= ObjRef ;
3384             retstr = ObjectToString( ObjRef ) ;
3385             D.Value <<= retstr ;
3386 //            theOutPort->Value( D.Value ) ;
3387           }
3388           catch( ... ) {
3389             if ( i != 0 ) {
3390               Err = true ;
3391             }
3392             cdebug << "ToString( object ) Catched ERROR" << endl ;
3393           }
3394         }
3395         else if ( !strcmp( Type , "boolean" ) ) {
3396           bool b = 0 ;
3397           D.Value <<=  (CORBA::Any::from_boolean ) b ;
3398 //          theOutPort->Value( D.Value ) ;
3399         }
3400         else if ( !strcmp( Type , "char" ) ) {
3401           unsigned char c = 0 ;
3402           D.Value <<=  (CORBA::Any::from_char ) c ;
3403 //          theOutPort->Value( D.Value ) ;
3404         }
3405         else if ( !strcmp( Type , "short" ) ) {
3406           short s = 0 ;
3407           D.Value <<=  s ;
3408 //          theOutPort->Value( D.Value ) ;
3409         }
3410         else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
3411           long l = 0 ;
3412           D.Value <<= l ;
3413 //          theOutPort->Value( D.Value ) ;
3414         }
3415         else if ( !strcmp( Type , "float" ) ) {
3416           float f = 0 ;
3417           D.Value <<= f ;
3418 //          theOutPort->Value( D.Value ) ;
3419         }
3420         else if ( !strcmp( Type , "double" ) ) {
3421           double d = 0 ;
3422           D.Value <<= d ;
3423 //          theOutPort->Value( D.Value ) ;
3424         }
3425 //        else if ( !strcmp( Type , "objref" ) ) {
3426         else { // Default
3427           CORBA::Object_ptr obj ;
3428           char * retstr ;
3429           try {
3430             D.Value >>= obj ;
3431             retstr = ObjectToString( obj ) ;
3432 #if InParametersSetTrace
3433             cdebug << retstr << endl ;
3434 #endif
3435           }
3436           catch( ... ) {
3437             if ( i != 0 ) {
3438               Err = true ;
3439             }
3440             cdebug << "ToString( object ) Catched ERROR" << endl ;
3441           }
3442         }
3443 //        else {
3444 //          cdebug << " (other ERROR)" << endl ;
3445 //        }
3446 #if InParametersSetTrace
3447         cdebug << " --> call_kind " << D.Value.type()->kind() << endl ;
3448 #endif
3449         break;
3450       default:
3451         cdebug << " (other ERROR) " << D.Value.type()->kind() << endl ;
3452       }
3453     }
3454     else {
3455       cdebug << ThreadNo() << " In" << i << " : wrong state ERROR State "
3456              << anInPort->PortState() << " NameState "
3457              << Automaton()->StateName( anInPort->PortState() ) << " PortName "
3458              << anInPort->PortName() << " Parametername "
3459              << anInPort->GetServicesParameter().Parametername << endl ;
3460       Err = true ;
3461     }
3462     InParametersList[i] = D ;
3463   }
3464 }
3465
3466 void GraphExecutor::InNode::InOutParametersSet( int nOutParams ,
3467                                                 ServicesAnyData * OutParametersList ) {
3468 #if InParametersSetTrace
3469   cdebug << pthread_self() << "/" << ThreadNo() << " InOutParametersSet " << Name() << endl ;
3470 #endif
3471   int i ;
3472   for ( i = 0 ; i < nOutParams ; i++ ) {
3473     ServicesAnyData D = OutParametersList[i] ;
3474
3475 //JR 18.02.2005 Debug Memory leak : delete does not destroy that string ...
3476 //    D.Name = CORBA::string_dup(GetChangeNodeOutPort(i)->GetServicesParameter().Parametername);
3477     D.Name = GetChangeNodeOutPort(i)->PortName() ;
3478 //JR 18.02.2005 Debug Memory leak :     string _Type = CORBA::string_dup(GetChangeNodeOutPort(i)->GetServicesParameter().Parametertype) ;
3479     const char * Type = GetChangeNodeOutPort(i)->GetServicesParameter().Parametertype ;
3480 #if InParametersSetTrace
3481     bool OutDone = GetChangeNodeOutPort(i)->PortDone() ;
3482     cdebug << ThreadNo() << " ArgOut" << i << " " << D.Name << " PortDone( " << OutDone << " ) Type : "
3483            << Type << endl ;
3484 #endif
3485     if ( !strcmp( Type , "string" ) ) {
3486 //      D.Value <<= (char *) NULL ;
3487       D.Value <<= "" ;
3488     }
3489     else if ( !strcmp( Type , "boolean" ) ) {
3490       bool b = 0 ;
3491       D.Value <<=  (CORBA::Any::from_boolean ) b ;
3492     }
3493     else if ( !strcmp( Type , "char" ) ) {
3494       unsigned char c = 0 ;
3495       D.Value <<=  (CORBA::Any::from_char ) c ;
3496     }
3497     else if ( !strcmp( Type , "short" ) ) {
3498       short s = 0 ;
3499       D.Value <<=  s ;
3500     }
3501     else if ( !strcmp( Type , "int" ) || !strcmp( Type , "long" ) ) {
3502       D.Value <<= (long ) 0 ;
3503     }
3504     else if ( !strcmp( Type , "float" ) ) {
3505       float f = 0 ;
3506       D.Value <<= f ;
3507     }
3508     else if ( !strcmp( Type , "double" ) ) {
3509       double d = 0 ;
3510       D.Value <<= d ;
3511     }
3512     else {
3513       D.Value <<= CORBA::Object::_nil() ;
3514     }
3515 #if InParametersSetTrace
3516     switch (D.Value.type()->kind()) { // { string , long , double , objref }
3517     case CORBA::tk_string:
3518       char * t;
3519       D.Value >>= t;
3520       cdebug << ThreadNo() << " " << t << "(string)" << endl ;
3521       break;
3522     case CORBA::tk_boolean:
3523       bool b ;
3524       D.Value >>= (CORBA::Any::to_boolean ) b;
3525       cdebug << ThreadNo() << " " << b << "(boolean)" << endl ;
3526       break;
3527     case CORBA::tk_char:
3528       unsigned char c ;
3529       D.Value >>= (CORBA::Any::to_char ) c;
3530       cdebug << ThreadNo() << " " << c << "(char)" << endl ;
3531       break;
3532     case CORBA::tk_short:
3533       short s;
3534       D.Value >>= s;
3535       cdebug << ThreadNo() << " " << s << "(short)" << endl ;
3536       break;
3537     case CORBA::tk_long:
3538       long l;
3539       D.Value >>= l;
3540       cdebug << ThreadNo() << " " << l << "(long)" << endl ;
3541       break;
3542     case CORBA::tk_float:
3543       float f;
3544       D.Value >>= f;
3545       cdebug << ThreadNo() << " " << f << "(float)" << endl ;
3546       break;
3547     case CORBA::tk_double:
3548       double d;
3549       D.Value >>= d;
3550       cdebug << ThreadNo() << " " << d << "(double)" << endl ;
3551       break;
3552     case CORBA::tk_objref:
3553       try {
3554         CORBA::Object_ptr obj ;
3555         char * retstr ;
3556         D.Value >>= obj ;
3557         retstr = ObjectToString( obj ) ;
3558         cdebug << ThreadNo() << retstr << endl ;
3559       }
3560       catch( ... ) {
3561         cdebug << "ToString( object ) Catched ERROR" << endl ;
3562       }
3563       break;
3564     default:
3565       cdebug << ThreadNo() << " " << "(other ERROR)" << endl ;
3566     }
3567 #endif
3568     OutParametersList[i] = D ;
3569   }
3570 }
3571
3572 #define OutParametersSetTrace 1
3573 bool GraphExecutor::InNode::OutParametersSet( bool Err ,
3574                                               SUPERV::GraphState PortState ,
3575                                               int nOutParams ,
3576                                               ServicesAnyData * OutParametersList ) {
3577   bool RetVal = true ;
3578   int i ;
3579   GraphBase::OutPort * aGateOutPort = NULL ;
3580   bool OrSwitch = false ;
3581   bool DefaultSwitch = false ;
3582 #if OutParametersSetTrace
3583   cdebug_in << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewPortState "
3584             << PortState << endl ;
3585 #endif
3586 //  cout << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewPortState " << PortState << endl ;
3587   if ( nOutParams && !IsMacroNode() ) {
3588     GraphBase::OutPort * anOutPort ;
3589     for ( i = 0 ; i < nOutParams ; i++ ) {
3590       anOutPort = GetChangeNodeOutPort(i) ;
3591       if ( Err ) {
3592         anOutPort->PortState( PortState ) ;
3593         anOutPort->PortDone( true ) ;
3594       }
3595       else {
3596 #if OutParametersSetTrace
3597         cdebug << ThreadNo() << "OutParametersSet " << "Out" << i << " " << Name() << " "
3598                << anOutPort->PortName() << " " << anOutPort->Kind() ;
3599 #endif
3600         ServicesAnyData D = OutParametersList[i] ;
3601         switch (D.Value.type()->kind()) { // { string , long , double , objref }
3602         case CORBA::tk_string: {
3603           char * t;
3604           D.Value >>= t;
3605 #if OutParametersSetTrace
3606           cdebug << ThreadNo() << " " << t << "(string)" << endl ;
3607 #endif
3608           break;
3609         }
3610         case CORBA::tk_boolean: {
3611           bool b ;
3612           D.Value >>= (CORBA::Any::to_boolean ) b;
3613           long l = (long ) b ;
3614           D.Value <<= l ;
3615 #if OutParametersSetTrace
3616           cdebug << ThreadNo() << " " << b << "(boolean)" << endl ;
3617 #endif
3618           break;
3619         }
3620         case CORBA::tk_char: {
3621           unsigned char c ;
3622           D.Value >>= (CORBA::Any::to_char ) c;
3623           long l = (long ) c ;
3624           D.Value <<= l ;
3625 #if OutParametersSetTrace
3626           cdebug << ThreadNo() << " " << c << "(char)" << endl ;
3627 #endif
3628           break;
3629         }
3630         case CORBA::tk_short: {
3631           short s;
3632           D.Value >>= s;
3633           long l = (long ) s ;
3634           D.Value <<= l ;
3635 #if OutParametersSetTrace
3636           cdebug << ThreadNo() << " " << s << "(short)" << endl ;
3637 #endif
3638           break;
3639         }
3640         case CORBA::tk_long: {
3641           long l;
3642           D.Value >>= l;
3643 #if OutParametersSetTrace
3644           cdebug << ThreadNo() << " " << l << "(long)" << endl ;
3645 #endif
3646           break;
3647         }
3648         case CORBA::tk_float: {
3649           float f;
3650           D.Value >>= f;
3651           double d = (double ) f ;
3652           D.Value <<= d ;
3653 #if OutParametersSetTrace
3654           cdebug << ThreadNo() << " " << f << "(float)" << endl ;
3655 #endif
3656           break;
3657         }
3658         case CORBA::tk_double: {
3659           double d;
3660           D.Value >>= d;
3661 #if OutParametersSetTrace
3662           cdebug << ThreadNo() << " " << d << "(double)" << endl ;
3663 #endif
3664           break;
3665         }
3666         case CORBA::tk_objref: {
3667           try {
3668             CORBA::Object_ptr obj ;
3669             D.Value >>= obj ;
3670 #if OutParametersSetTrace
3671             char * retstr ;
3672             retstr = ObjectToString( obj ) ;
3673             cdebug << ThreadNo() << retstr << endl ;
3674 #endif
3675           }
3676           catch( ... ) {
3677             cdebug << "ToString( object ) Catched ERROR" << endl ;
3678             RetVal = false ;
3679           }
3680           break;
3681         }
3682         default: {
3683           cdebug << ThreadNo() << " " << "(other ERROR)" << endl ;
3684           RetVal = false ;
3685         }
3686         }
3687         OutParametersList[i] = D ;
3688         if ( !anOutPort->IsDataStream() ) {
3689           if ( anOutPort->IsGate() ) {
3690             aGateOutPort = anOutPort ;
3691 #if OutParametersSetTrace
3692             cdebug << " Gate " ;
3693 #endif
3694             long l = 1;
3695             OutParametersList[i].Value <<= l;
3696             anOutPort->SetValue( OutParametersList[i].Value );
3697           }
3698           else if ( anOutPort->IsLoop() ) {
3699 #if OutParametersSetTrace
3700             cdebug << " Loop " ;
3701 #endif
3702             anOutPort->SetValue( OutParametersList[i].Value );
3703 // InLoop Port of EndLoopNode is ready :
3704             anOutPort->ChangeInPorts(0)->PortState( SUPERV::ReadyState ) ;
3705           }
3706           else if ( anOutPort->IsSwitch() ) {
3707 #if OutParametersSetTrace
3708             cdebug << " Switch " ;
3709 #endif
3710             anOutPort->SetValue( OutParametersList[i].Value );
3711             if ( anOutPort->InPortsSize() && anOutPort->ChangeInPorts( 0 )->IsGate() ) {
3712 //We have a SwitchBranch or the DefaultBranch .
3713 //JR 09.02.2005 : OrSwitch is the OR of all SwitchBranches (SwitchParameters) :
3714 //It controls that there is only one SwitchBranch activated
3715 //If it's final value is false ==> activation of the Default to GOTO to EndSwitchNode
3716 //DefaultSwitch is true if a SwitchPort is linked to the DefaultPort of the EndSwitchNode
3717               if ( OrSwitch && anOutPort->BoolValue() ) {
3718                 string anErrorMessage = string( "More than one SwitchBranch should be activated in SwitchNode " ) +
3719                                         string( Name() ) + string( "( " ) +
3720                                         string( anOutPort->PortName() ) + string( " )" ) ;
3721                 _OutNode->Graph()->SetMessages( anErrorMessage ) ;
3722                 cdebug << "Executor::InNodeThreads::OutParameters more than one SwitchBranch is true ERROR"
3723                        << endl ;
3724                 RetVal = false ;
3725               }
3726               else if ( anOutPort->BoolValue() ) {
3727 //JR 09.02.2005 Debug : case of a SwitchPort linked to the DefaultPort of the EndSwitchNode :
3728                 if ( !strcmp( anOutPort->ChangeInPorts( 0 )->NodeName() , GOTONode()->CoupledNodeName() ) ) {
3729                   DefaultSwitch = anOutPort->BoolValue() ;
3730                 }
3731                 else {
3732                   OrSwitch = OrSwitch | anOutPort->BoolValue() ;
3733                 }
3734 #if OutParametersSetTrace
3735                 cdebug << "InNodeThreads::OutParameters OrSwitch " << OrSwitch << "DefaultSwitch "
3736                        << DefaultSwitch << endl ;
3737 #endif
3738               }
3739             }
3740           }
3741           else {
3742 #if OutParametersSetTrace
3743             cdebug << " Param " ;
3744 #endif
3745             anOutPort->SetValue( OutParametersList[i].Value );
3746           }
3747           anOutPort->PortState( PortState ) ;
3748           anOutPort->PortDone( true ) ;
3749         }
3750 #if OutParametersSetTrace
3751         cdebug << "OutParametersSet OrSwitch " << OrSwitch << "DefaultSwitch "
3752                << DefaultSwitch << endl ;
3753 #endif
3754         int j ;
3755         for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
3756 #if OutParametersSetTrace
3757           cdebug << ThreadNo() << "OutParametersSet " << "Out" << i << " " << Name() << " "
3758                  << anOutPort->PortName() << " " << anOutPort->Kind() << " --> "
3759                  << anOutPort->ChangeInPorts( j )->NodeName() << "( "
3760                  << anOutPort->ChangeInPorts( j )->PortName() << anOutPort->ChangeInPorts( j )->Kind()
3761                  << " )" << endl ;
3762 #endif
3763           bool fromGOTO = false ;
3764           const char * ToNodeName = anOutPort->ChangeInPorts( j )->NodeName() ;
3765           if ( !strcmp( ToNodeName , _OutNode->Name() ) &&
3766                _OutNode->Graph()->GraphMacroLevel() != 0 ) {
3767 #if OutParametersSetTrace
3768             cdebug << "OutParametersSet ToNodeName " << _OutNode->Name() << " CoupledNode "
3769                    << _OutNode->Graph()->CoupledNodeName() << _OutNode->Graph()->CoupledNode()
3770                    << endl ;
3771             cdebug << " GraphExecutor " << _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor() << endl ;
3772 #endif
3773             _OutNode->Graph()->CoupledNode()->GraphEditor()->Executor()->OutputOfAny( _OutNode->Graph()->CoupledNodeName() ,
3774                                                                             anOutPort->ChangeInPorts( j )->PortName() ,
3775 //JR 30.03.2005                                                                            *anOutPort->Value() ) ;
3776                                                                             anOutPort->Value() ) ;
3777           }
3778           else {
3779             GraphBase::ComputingNode * ToNode = _OutNode->Graph()->GetChangeGraphNode( ToNodeName ) ;
3780             if ( ToNode ) {
3781 //              cout << "OutParametersSet ToNodeName " << ToNodeName << endl ;
3782 //              cdebug << "OutParametersSet ToNodeName " << ToNodeName << " " << ToNode->Name() << endl ;
3783               GraphBase::OutPort * aGOTOPort = ToNode->GetChangeNodeInGate()->GetOutPort() ;
3784               if ( aGOTOPort ) {
3785                 fromGOTO = aGOTOPort->IsGOTO() ;
3786               }
3787               if ( anOutPort->ChangeInPorts( j )->IsEndSwitch() || fromGOTO ) {
3788 #if OutParametersSetTrace
3789                 cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
3790                        << anOutPort->ChangeInPorts( j )->PortName() << ","
3791                        << anOutPort->ChangeInPorts( j )->Kind() << ") CHANGED from "
3792                        << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
3793                        << "("
3794                        << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
3795                        << " to " << anOutPort->ChangeInPorts( j )->GetOutPort()->Kind()
3796                        << ") : Done " << anOutPort->PortDone() << " State "
3797                        << Automaton()->StateName( anOutPort->ChangeInPorts( j )->PortState() ) << endl ;
3798 #endif
3799                 anOutPort->ChangeInPorts( j )->ChangeOutPort( anOutPort ) ;
3800               }
3801               else {
3802 #if OutParametersSetTrace
3803                 cdebug << anOutPort->ChangeInPorts( j )->NodeName() << "("
3804                        << anOutPort->ChangeInPorts( j )->PortName() << ","
3805                        << anOutPort->ChangeInPorts( j )->Kind() << ") NOT changed from "
3806                        << anOutPort->ChangeInPorts( j )->GetOutPort()->NodeName()
3807                        << "("
3808                        << anOutPort->ChangeInPorts( j )->GetOutPort()->PortName()
3809                        << " " << anOutPort->ChangeInPorts( j )->GetOutPort()->Kind()
3810                        << ") " << endl ;
3811 #endif
3812               }
3813             }
3814           }
3815         }
3816 #if OutParametersSetTrace
3817         switch ( anOutPort->Value().type()->kind() ) {
3818         case CORBA::tk_string:
3819           char * t;
3820           (anOutPort->Value()) >>= t;
3821           cdebug << ThreadNo() << " Out" << i << " : " << t << "(string)" << endl ;
3822           break;
3823         case CORBA::tk_boolean:
3824           bool b ;
3825           (anOutPort->Value()) >>= (CORBA::Any::to_boolean ) b;
3826           cdebug << ThreadNo() << " Out" << i << " : " << b << "(boolean)" << endl ;
3827           break;
3828         case CORBA::tk_char:
3829           unsigned char c ;
3830           (anOutPort->Value()) >>= (CORBA::Any::to_char ) c;
3831           cdebug << ThreadNo() << " Out" << i << " : " << c << "(char)" << endl ;
3832           break;
3833         case CORBA::tk_short:
3834           short s;
3835           (anOutPort->Value()) >>= s;
3836           cdebug << ThreadNo() << " Out" << i << " : " << s << "(short)" << endl ;
3837           break;
3838         case CORBA::tk_long:
3839           long l;
3840           (anOutPort->Value()) >>= l;
3841           cdebug << ThreadNo() << " Out" << i << " : " << l << "(long)" << endl ;
3842           break;
3843         case CORBA::tk_float:
3844           float f;
3845           (anOutPort->Value()) >>= f;
3846           cdebug << ThreadNo() << " Out" << i << " : " << f << "(float)" << endl ;
3847           break;
3848         case CORBA::tk_double:
3849           double d;
3850           (anOutPort->Value()) >>= d;
3851           cdebug << ThreadNo() << " Out" << i << " : " << d << "(double)" << endl ;
3852           break;
3853         case CORBA::tk_objref:
3854           CORBA::Object_ptr obj ;
3855           char * retstr ;
3856           try {
3857 //JR 02.08.2005 Debug SEGV            anOutPort->Value() >>= obj ;
3858             CORBA::Any anAny ;
3859             anAny = anOutPort->Value() ;
3860             anAny >>= obj ;
3861             retstr = ObjectToString( obj );
3862             cdebug << ThreadNo() << " Out" << i << " : " << "ToString( object ) "
3863                    << retstr << endl ;
3864           }
3865           catch ( ... ) {
3866             cdebug << ThreadNo() << " Out" << i << " : " << "ToString( object ) "
3867                    << "Catched ERROR" << endl ;
3868             RetVal = false ;
3869           }
3870           break;
3871         default:
3872           cdebug << ThreadNo() << " Out" << i << " : " << "(other ERROR)" << endl ;
3873           RetVal = false ;
3874         }
3875 #endif
3876       }
3877     } // End of : for ( i = 0 ; i < nOutParams ; i++ ) {
3878 #if OutParametersSetTrace
3879     cdebug << ThreadNo() << "OutParametersSet End of loop with " << nOutParams
3880            << " OutParams. aGateOutPort " << (void *) aGateOutPort << " IsSwitchNode "
3881            << IsSwitchNode() << " OrSwitch " << OrSwitch << " DefaultSwitch " << DefaultSwitch
3882            << endl ;
3883 #endif
3884
3885 //In SwitchNodes :
3886     if ( IsSwitchNode() && aGateOutPort ) {
3887 //JR 09.02.2005 : OrSwitch is the OR of all SwitchBranches :
3888 //It controls that there is only one SwitchBranch activated
3889 //If it's final value is false ==> activation of the Default in order to GOTO to EndSwitchNode
3890 //DefaultSwitch is true if a SwitchPort (SwitchBranch) is linked to the DefaultPort of the EndSwitchNode
3891       if ( !OrSwitch && !DefaultSwitch ) {
3892         if ( aGateOutPort->InPortsSize() && aGateOutPort->ChangeInPorts( 0 ) ) {
3893 //Dynamic activation of the Default OutPort :
3894 #if OutParametersSetTrace
3895           cdebug << ThreadNo() << " " << "OutGate " << Name() << " Open of "
3896                  << aGateOutPort->PortName() << " " << aGateOutPort->Kind() << " WITH DefaultPort"
3897                  << endl ;
3898 #endif
3899           long l = 1;
3900           OutParametersList[0].Value <<= l ;
3901           aGateOutPort->SetValue( OutParametersList[0].Value ) ;
3902         }
3903         else {
3904 //The Default OutPort is not linked ==> error
3905           string anErrorMessage = string( "DefaultPort of SwitchNode " ) +
3906                                   string( Name() ) + " is not connected." ;
3907           _OutNode->Graph()->SetMessages( anErrorMessage ) ;
3908 #if OutParametersSetTrace
3909           cdebug << ThreadNo() << " " << "OutGate " << Name() << " "
3910                  << aGateOutPort->PortName() << " " << aGateOutPort->Kind() << " NOT CONNECTED ERROR"
3911                  << endl ;
3912 #endif
3913           RetVal = false ;
3914         }
3915       }
3916 //JR 07.04.2005 Debug : reset only if it is not a default switch (SwitchBranch or
3917 //                      SwitchParameter of SwitchNode connected to the DefaultInPort of
3918 //                      EndSwitchNode)
3919 //      else {
3920       else if ( !DefaultSwitch ) {
3921 #if OutParametersSetTrace
3922         cdebug << ThreadNo() << " " << "OutGate " << Name() << " Close of "
3923                << aGateOutPort->PortName() << " " << aGateOutPort->Kind() << " NO DefaultPort"
3924                << " OrSwitch " << OrSwitch << " DefaultSwitch " << DefaultSwitch << endl ;
3925 #endif
3926         long l = 0;
3927         OutParametersList[0].Value <<= l ;
3928         aGateOutPort->SetValue( OutParametersList[0].Value ) ;
3929       }
3930       if ( RetVal ) {
3931 // The OutPort field of InPorts of EndSwitchNode may be updated from each OutPort of that SwitchNode :
3932         GraphBase::EndOfSwitchNode * anEndSwitchNode = (GraphBase::EndOfSwitchNode * ) CoupledNode() ;
3933         int i ;
3934 //PAL8518
3935 //JR 16.02.2005 Debug : At first Change InPorts of EndSwitchNode that have the same name as an OutPort of
3936 // the SwitchNode even if it is the DefaultPort : GraphSwitchCheckDefault1.xml
3937 //STEP A : InPorts of EndSwitchNode that have the same name as an OutPort of the SwitchNode
3938         for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
3939           GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i );
3940           GraphBase::InPort * anInPort = NULL ;
3941           anInPort = anEndSwitchNode->GetChangeInPort( anOutPort->PortName() ) ;
3942           if ( anInPort ) {
3943 #if OutParametersSetTrace
3944             cdebug << "OutParametersSet " << Name() << " " << anInPort->NodeName()
3945                    << "( " << anInPort->PortName() << " , " << anInPort->Kind() << " ) with same name " ;
3946             if ( anInPort->GetOutPort() ) {
3947               cdebug << "linked from " << anInPort->GetOutPort()->NodeName()
3948                      << "( " << anInPort->GetOutPort()->PortName() << " ) " ;
3949             }
3950             else {
3951               cdebug << "NOT linked " ;
3952             }
3953             cdebug << "CHANGED TO linked from " << anOutPort->NodeName() << "( "
3954                    << anOutPort->PortName() << " )" << endl ;
3955 #endif
3956             anInPort->ChangeOutPort( anOutPort ) ;
3957           }
3958         }
3959 //STEP B : InPorts of EndSwitchNode directly connected from an OutPort of the SwitchNode
3960         for ( i = 0 ; i < GetNodeOutPortsSize() ; i++ ) {
3961           GraphBase::OutPort * anOutPort = GetChangeNodeOutPort( i );
3962           GraphBase::InPort * anInPort ;
3963           int j ;
3964           for ( j = 0 ; j < anOutPort->InPortsSize() ; j++ ) {
3965             anInPort = anOutPort->ChangeInPorts( j ) ;
3966 //Update the OutPort field in the Inports directly connected of the EndSwitchNode :
3967             if ( !strcmp( anInPort->NodeName() , anEndSwitchNode->Name() ) ) {
3968 #if OutParametersSetTrace
3969               cdebug << "OutParametersSet " << Name() << " " << anInPort->NodeName()
3970                      << "( " << anInPort->PortName() << " , " << anInPort->Kind()
3971                      << " ) directly connected " ;
3972               if ( anInPort->GetOutPort() ) {
3973                 cdebug << "linked from " << anInPort->GetOutPort()->NodeName()
3974                        << "( " << anInPort->GetOutPort()->PortName() << " ) " ;
3975               }
3976               else {
3977                 cdebug << "NOT linked " ;
3978               }
3979               cdebug << "CHANGED TO linked from " << anOutPort->NodeName() << "( "
3980                      << anOutPort->PortName() << " )" << endl ;
3981 #endif
3982               anInPort->ChangeOutPort( anOutPort ) ;
3983             }
3984           }
3985         }
3986 //STEP C : If it is not the DefaultBranch, explore the SwitchBranch and all NOTSwitchBranch[es]
3987 //Change recursively InPorts of EndSwitchNode linked to that Branch (or that SwitchNode)
3988         if ( OrSwitch ) {
3989           for ( i = 0 ; i <  LinkedNodesSize() ; i++ ) {
3990             GraphBase::ComputingNode * aNode = (GraphBase::ComputingNode * ) LinkedNodes( i ) ;
3991             if ( aNode != anEndSwitchNode && !aNode->IsGOTONode() &&
3992                  !aNode->IsDataFlowNode() && !aNode->IsDataStreamNode()  ) {
3993               const GraphBase::InPort * anInGate = aNode->GetNodeInGate() ;
3994               GraphExecutor::InNode * anInNode = (GraphExecutor::InNode * ) aNode->GetInNode() ;
3995 //STEP C1 : SwitchBranch :
3996               if ( anInGate->GetOutPort() ) {
3997                 if ( anInGate->GetOutPort()->BoolValue() ) {
3998 #if OutParametersSetTrace
3999                   cdebug << "OutParametersSet " << Name() << " SWITCHBranch " << aNode->Name() << endl ;
4000 #endif
4001                   int j ;
4002                   for ( j = 0 ; j < aNode->GetNodeOutPortsSize() ; j++ ) {
4003                     GraphBase::OutPort * anOutPort = aNode->GetChangeNodeOutPort( j );
4004                     anInNode->SetOutPortsOfInportsOfEndSwitch( anOutPort , anEndSwitchNode->Name() ) ;
4005                   }
4006                 }
4007               }
4008 //STEP C2 : NOTSwitchBranch :
4009               else {
4010 #if OutParametersSetTrace
4011                 cdebug << "OutParametersSet " << Name() << " NOTSWITCHBranch " << aNode->Name() << endl ;
4012 #endif
4013                 int j ;
4014                 for ( j = 0 ; j < aNode->GetNodeOutPortsSize() ; j++ ) {
4015                   GraphBase::OutPort * anOutPort = aNode->GetChangeNodeOutPort( j );
4016                   anInNode->SetOutPortsOfInportsOfEndSwitch( anOutPort , anEndSwitchNode->Name() ) ;
4017                 }
4018               }
4019             }
4020           }
4021         }
4022       }
4023     }
4024   }
4025 #if OutParametersSetTrace
4026   cdebug_out << "OutParametersSet " << Name() << " nOutParams " << nOutParams << " NewPortState "
4027              << PortState << " RetVal " << RetVal << endl ;
4028 #endif
4029   return RetVal ;
4030 }
4031
4032
4033 void GraphExecutor::InNode::SetOutPortsOfInportsOfEndSwitch( GraphBase::OutPort * anOutPort ,
4034                                                              const char * anEndSwitchNodeName ) {
4035 #if OutParametersSetTrace
4036   cdebug_in << "SetOutPortsOfInportsOfEndSwitch " << Name() << " " << anOutPort->NodeName() << "( "
4037             << anOutPort->PortName() << " ) with " << anOutPort->InPortsSize() << " links." << endl ;
4038 #endif
4039   GraphBase::InPort * anInPort ;
4040   int i ;
4041   for ( i = 0 ; i < anOutPort->InPortsSize() ; i++ ) {
4042     anInPort = anOutPort->ChangeInPorts( i ) ;
4043     if ( !anInPort->IsDataStream() ) {
4044 //Update the OutPort field in the Inports of the EndSwitchNode :
4045       if ( !strcmp( anInPort->NodeName() , anEndSwitchNodeName ) ) {
4046 #if OutParametersSetTrace
4047         cdebug << "SetOutPortsOfInportsOfEndSwitch " << Name() << " " << anInPort->NodeName()
4048                << "( " << anInPort->PortName() << " , " << anInPort->Kind() << " ) " ;
4049         if ( anInPort->GetOutPort() ) {
4050           cdebug << "linked from " << anInPort->GetOutPort()->NodeName()
4051                  << "( " << anInPort->GetOutPort()->PortName() << " ) " ;
4052         }
4053         else {
4054           cdebug << "NOT linked ERROR " ;
4055         }
4056         cdebug << "CHANGED TO linked from "
4057                << anOutPort->NodeName() << "( "
4058                << anOutPort->PortName() << " )" << endl ;
4059 #endif
4060         anInPort->ChangeOutPort( anOutPort ) ;
4061       }
4062       else {
4063 #if OutParametersSetTrace
4064         cdebug << "SetOutPortsOfInportsOfEndSwitch " << Name() << " " << anInPort->NodeName()
4065                << "( " << anInPort->PortName() << " , " << anInPort->Kind() << " ) " << endl ;
4066 #endif
4067         GraphBase::ComputingNode * aComputingNode ;
4068         aComputingNode = _OutNode->Graph()->GetChangeGraphNode( anInPort->NodeName() ) ;
4069         if ( aComputingNode && !aComputingNode->IsGOTONode() &&
4070              !( IsEndLoopNode() && GOTONode()->CoupledNode() == aComputingNode ) ) {
4071           GraphExecutor::InNode * aNode ;
4072           aNode = (GraphExecutor::InNode * ) aComputingNode->GetInNode() ;
4073           if ( aNode ) {
4074             int j ;
4075             for ( j = 0 ; j < aNode->GetNodeOutPortsSize() ; j++ ) {
4076               GraphBase::OutPort * anOutPort = aNode->GetChangeNodeOutPort( j ) ;
4077               aNode->SetOutPortsOfInportsOfEndSwitch( anOutPort , anEndSwitchNodeName ) ;
4078             }
4079           }
4080         }
4081       }
4082     }
4083   }
4084 #if OutParametersSetTrace
4085   cdebug_out << "SetOutPortsOfInportsOfEndSwitch " << Name() << " OutPort " << anOutPort->PortName()
4086              << endl ;
4087 #endif
4088 }
4089