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