Salome HOME
9e5a35771b36918566e356d204008ba9fb6e15fe
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_PyDynInvoke.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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : DataFlowExecutor_PyDynInvoke.cxx
23 //  Author : Jean Rahuel, CEA
24 //  Module : SUPERV
25
26 using namespace std;
27
28 #include <stdarg.h>
29 #include <map>
30
31 #include "DataFlowExecutor_InNode.hxx"
32 #include "DataFlowExecutor_OutNode.hxx"
33
34 using namespace CORBA ;
35
36 extern GraphExecutor::FiniteStateMachine * theAutomaton ;
37
38 //static PyObject * MyPyObjSignal = NULL ;
39 static PyObject * MyPyObjRef = NULL ;
40 static PyObject * MyPyObjIor = NULL ;
41 static PyObject * MyPyRunMethod = NULL ;
42
43 static PyMethodDef MethodPyRunMethod[] = {
44   { "RunMethod", PyRunMethod, METH_VARARGS },
45   { NULL,        NULL }
46 };
47
48 bool GraphExecutor::InNode::InitPython() {
49   cdebug_in << "InitPython" << endl ;
50   
51   Automaton()->PyLock() ;
52 //  PyObject * Module = Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
53   if ( !Automaton()->PyInitModule() ) {
54     Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
55     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
56     //_OutNode->SuperVisionContainer()->ActivatePythonExecution( "InitPyRunMethod" , MethodPyRunMethod ) ;
57   }
58 //  PyObject * Dictionnary = PyModule_GetDict( Module ) ;
59 //  InitPyDynInvokeError = PyErr_NewException( "InitPyDynInvokeError" , NULL , NULL ) ;
60 //  PyDict_SetItemString( Dictionnary , InitPyDynInvokeError ) ;
61   cdebug << ThreadNo() << "Py_Initialized() " << endl ;
62
63 #if 0
64 //JR : Python documentation says that there is no sense to set a handler of synchronous
65 // signals as SIGSEGV and SIGFPE !!!
66   if ( Automaton()->PyFunction( "PyObjSignal" ) == NULL ) {
67     string aPyFunc ;
68     aPyFunc = "import signal\n" ;
69     aPyFunc += "import InitPyRunMethod\n" ;
70     aPyFunc += "import sys\n" ;
71     aPyFunc += "import CORBA\n" ;
72     aPyFunc += "import omniORB\n" ;
73     aPyFunc += "def PySignalHandler( aSignal , aStackFrame ) :\n" ;
74     aPyFunc += "    print 'PySignalHandler(aSignal =',aSignal,',aStackFrame= ',aStackFrame,')'\n" ;
75     aPyFunc += "InitPyRunMethod.RunMethod( PySignalHandler )\n" ;
76     aPyFunc += "PrevHandler = signal.signal( signal.SIGSEGV , PySignalHandler )\n" ;
77     aPyFunc += "print 'PyObjSignal PrevHandler of SIGSEGV :', PrevHandler\n" ;
78     aPyFunc += "print 'PyObjSignal actual handler of SIGSEGV :', signal.getsignal( signal.SIGSEGV  )\n" ;
79 //    if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
80     if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
81       cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
82       Automaton()->PyUnLock() ;
83       return false ;
84     }
85     MyPyObjSignal = MyPyRunMethod ;
86     Automaton()->PyFunction( "PyObjSignal" , MyPyObjSignal ) ;
87   }
88   else {
89     MyPyObjSignal = Automaton()->PyFunction( "PyObjSignal" ) ;
90   }
91 #endif
92
93 // PyObjRef convert an IOR (string) to an Python ObjectReference
94   if ( Automaton()->PyFunction( "PyObjRef" ) == NULL ) {
95     string aPyFunc ;
96     aPyFunc = "import InitPyRunMethod\n" ;
97     aPyFunc += "import sys\n" ;
98     aPyFunc += "import CORBA\n" ;
99     aPyFunc += "import omniORB\n" ;
100     aPyFunc += "def PyObjRef( IORObjStr ) :\n" ;
101     aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
102     aPyFunc += "    objref = orb.string_to_object( IORObjStr )\n" ;
103     aPyFunc += "    return objref\n" ;
104     aPyFunc += "InitPyRunMethod.RunMethod( PyObjRef )\n" ;
105     if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
106     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
107     //if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
108       cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
109       Automaton()->PyUnLock() ;
110       return false ;
111     }
112     MyPyObjRef = MyPyRunMethod ;
113     Automaton()->PyFunction( "PyObjRef" , MyPyObjRef ) ;
114   }
115   else {
116     MyPyObjRef = Automaton()->PyFunction( "PyObjRef" ) ;
117   }
118
119 // PyObjRef convert an Python ObjectReference to an IOR (string)
120   if ( Automaton()->PyFunction( "PyObjIor" ) == NULL ) {
121     string aPyFunc ;
122     aPyFunc = "import InitPyRunMethod\n" ;
123     aPyFunc += "import sys\n" ;
124     aPyFunc += "import CORBA\n" ;
125     aPyFunc += "import omniORB\n" ;
126     aPyFunc += "def PyObjIor( ObjRef ) :\n" ;
127     aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
128     aPyFunc += "    objIor = orb.object_to_string( ObjRef )\n" ;
129     aPyFunc += "    return objIor\n" ;
130     aPyFunc += "InitPyRunMethod.RunMethod( PyObjIor )\n" ;
131     if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
132     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL
133     //if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
134       cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
135       Automaton()->PyUnLock() ;
136       return false ;
137     }
138     MyPyObjIor = MyPyRunMethod ;
139     Automaton()->PyFunction( "PyObjIor" , MyPyObjIor ) ;
140   }
141   else {
142     MyPyObjIor = Automaton()->PyFunction( "PyObjIor" ) ;
143   }
144   Automaton()->PyUnLock() ;
145
146   cdebug_out << "InitPython" << endl ;
147   
148   return true ;
149 }
150
151 void GraphExecutor::InNode::RemovePyDynInvoke( char * PyFuncName ) {
152 //  Automaton()->PyLock() ; // Already done ...
153   if ( Automaton()->ErasePyFunction( PyFuncName ) ) {
154     cdebug << "InNode::RemovePyDynInvoke( " << PyFuncName << " ) success" << endl ;
155   }
156   else {
157     cdebug << "InNode::RemovePyDynInvoke( " << PyFuncName << " ) ERROR failed" << endl ;
158   }
159 //  Automaton()->PyUnLock() ;
160 }
161
162 PyObject * GraphExecutor::InNode::InitPyDynInvoke( char * PyFuncName ,
163                                                    const SUPERV::ListOfStrings * aPythonFunction ,
164                                                    bool & Err ) {
165   bool RetVal = true ;
166   Err = false ;
167   string aPyFunc ;
168   PyObject * thePyRunMethod = NULL ;
169
170   cdebug_in << "InitPyDynInvoke '" << PyFuncName << "' length " << (*aPythonFunction).length() << endl ;
171
172   if ( strlen( PyFuncName ) ) {
173     Automaton()->PyLock() ;
174     thePyRunMethod = Automaton()->PyFunction( PyFuncName ) ;
175     if ( (*aPythonFunction).length() ) {
176       if ( thePyRunMethod == NULL ) {
177         unsigned int i ;
178         aPyFunc += "import InitPyRunMethod\n" ;
179         for ( i = 0 ; i < (*aPythonFunction).length() ; i++ ) {
180           aPyFunc += (*aPythonFunction)[ i ] ;
181           aPyFunc += "\n" ;
182         }
183         aPyFunc += "InitPyRunMethod.RunMethod( " ;
184         aPyFunc += PyFuncName ;
185         aPyFunc += " )\n" ;
186         /*cdebug *///cout<< "InitPyDynInvoke PyRun_SimpleString " << endl << aPyFunc << endl ;
187 //        if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
188         if ( PyRunSimpleString( (char *) aPyFunc.c_str() ) ) {
189           cdebug << ThreadNo() << " " << Name() << " PyRunSimpleString ERROR " << endl << aPyFunc << endl ;
190           PyFuncRunned( false ) ;
191           RetVal = false ;
192           Err = true ;
193         }
194         else {
195           PyFuncRunned( true ) ;
196           thePyRunMethod = MyPyRunMethod ;
197           
198           Automaton()->PyFunction( PyFuncName , thePyRunMethod ) ;
199           cdebug << ThreadNo() << "PyRunSimpleString( " << (*aPythonFunction)[ 0 ] << " ) " << endl ;
200         }
201       }
202       if ( RetVal ) {
203         Automaton()->PyUnLock() ;
204         cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod " << thePyRunMethod << " "
205                    << thePyRunMethod->ob_refcnt << endl ;
206         return thePyRunMethod ;
207       }
208     }
209     else if ( thePyRunMethod ) {
210       Automaton()->PyUnLock() ;
211       cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod " << thePyRunMethod << " "
212                  << thePyRunMethod->ob_refcnt << endl ;
213       return thePyRunMethod ;
214     }
215     Automaton()->PyUnLock() ;
216   }
217
218   cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod Null Err " << Err << endl ;
219   
220   return NULL ;
221 }
222
223 extern "C" PyObject * PyRunMethod( PyObject * dummy , PyObject * Args ) {
224   PyObject * Result = NULL ;
225   PyObject * Temp = NULL ;
226   if ( PyArg_ParseTuple( Args , "O:set_callback" , & Temp ) ) {
227 //    cout << "PyArg_ParsedTuple" << endl ;
228     if ( !PyCallable_Check( Temp ) ) {
229 //      PyErr_SetString( PyExc_TypeError , "PyRunMethod must be callable" ) ;
230 //      cout << "PyRunMethod must be callable" << endl ;
231       return NULL ;
232     }
233     Py_XINCREF( Temp ) ;
234     Py_XDECREF( MyPyRunMethod ) ;
235     MyPyRunMethod = Temp ;
236     Py_INCREF( Py_None ) ;
237     Result = Py_None ;
238   }
239   return Result ;
240 }
241
242 #define PyDynInvokeTrace 1
243 bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
244                                          const char *method , 
245                                          ServicesAnyData * InParametersList , int nInParams ,
246                                          ServicesAnyData * OutParametersList , int nOutParams ) {
247   int i ;
248
249   bool RetVal = true ;
250
251   const char * sname;
252
253 #if PyDynInvokeTrace
254   cdebug_in << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke Node " << Name()
255             << " method " << method
256             << " InParametersList " << InParametersList
257             << " OutParametersList " << OutParametersList 
258             << " " << nInParams << " InArgs " << nOutParams
259             << " OutArgs MyPyRunMethod " ;
260 #endif
261   if ( MyPyRunMethod ) {
262 #if PyDynInvokeTrace
263     cdebug << MyPyRunMethod << " " << MyPyRunMethod->ob_refcnt << endl ;
264 #endif
265   }
266   else {
267 #if PyDynInvokeTrace
268     cdebug << " NULL" << endl ;
269 #endif
270     return false ;
271   }
272
273   CORBA::Any data ;
274
275   PyObject * ArgsList = NULL ;
276   PyObject * ArgValue = NULL ;
277   PyObject * Result = NULL ;
278   PyObject * MyPyObjRefList = NULL ;
279   PyObject * ResultObj = NULL ;
280   PyObject * MyPyObjIorList = NULL ;
281   PyObject * ResultIor = NULL ;
282
283   CORBA::Object_ptr ObjRef ;
284
285   char * IORObjRef ;
286
287   if ( !PyCallable_Check( MyPyRunMethod ) ) {
288     Result = NULL ;
289     RetVal = false ;
290   }
291   else {
292     ArgsList = PyTuple_New( nInParams ) ;
293
294     for ( i = 0 ; i < nInParams ; i++ ) {
295       data = InParametersList[i].Value ;
296       sname = InParametersList[i].Name.c_str() ;
297       switch ( data.type()->kind() ) {
298       case CORBA::tk_string : {
299         char * t ;
300         data >>= t ;
301         PyObject * ArgValue = Py_BuildValue( "s" , t ) ;
302         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
303 #if PyDynInvokeTrace
304         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << t << " (string) "
305                << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
306                << ArgValue->ob_refcnt << endl ;
307 #endif
308         break ;
309       }
310       case CORBA::tk_boolean : {
311         bool b ;
312         data >>= (CORBA::Any::to_boolean ) b ;
313         PyObject * ArgValue = Py_BuildValue( "b" , b ) ;
314         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
315 #if PyDynInvokeTrace
316         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << b
317                << " (boolean) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
318                << ArgValue->ob_refcnt << endl ;
319 #endif
320         break ;
321       }
322       case CORBA::tk_char : {
323         unsigned char c ;
324         data >>= (CORBA::Any::to_char ) c ;
325         PyObject * ArgValue = Py_BuildValue( "c" , c ) ;
326         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
327 #if PyDynInvokeTrace
328         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << c
329                << " (char) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
330                << ArgValue->ob_refcnt << endl ;
331 #endif
332         break ;
333       }
334       case CORBA::tk_short : {
335         short s ;
336         data >>= s ;
337         PyObject * ArgValue = Py_BuildValue( "h" , s ) ;
338         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
339 #if PyDynInvokeTrace
340         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << s
341                << " (short) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
342                << ArgValue->ob_refcnt << endl ;
343 #endif
344         break ;
345       }
346       case CORBA::tk_long : {
347         long l ;
348         data >>= l ;
349         PyObject * ArgValue = Py_BuildValue( "l" , l ) ;
350 #if PyDynInvokeTrace
351         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << l
352                << " ArgValue->ob_refcnt" << ArgValue->ob_refcnt << endl ;
353 #endif
354         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
355 #if PyDynInvokeTrace
356         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << l
357                << " (long) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
358                << ArgValue->ob_refcnt << endl ;
359 #endif
360         break ;
361       }
362       case CORBA::tk_float : {
363         float f ;
364         data >>= f ;
365         PyObject * ArgValue = Py_BuildValue( "f" , f ) ;
366         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
367 #if PyDynInvokeTrace
368         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << f
369                << " (float) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
370                << ArgValue->ob_refcnt << endl ;
371 #endif
372         break ;
373       }
374       case CORBA::tk_double : {
375         double d ;
376         data >>= d ;
377         PyObject * ArgValue = Py_BuildValue( "d" , d ) ;
378         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
379 #if PyDynInvokeTrace
380         cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << d
381                << " (double) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
382                << ArgValue->ob_refcnt << endl ;
383 #endif
384         break ;
385       }
386       case CORBA::tk_objref : {
387         MyPyObjRefList = PyTuple_New( 1 ) ;
388         PyObject * ObjValue ;
389 #if OMNIORB_VERSION >= 4
390         data >>= (CORBA::Any::to_object ) ObjRef ;
391 #else
392         data >>= ObjRef ;
393 #endif
394         IORObjRef = ObjectToString( ObjRef ) ;
395         ObjValue = Py_BuildValue( "s" , IORObjRef ) ;
396         PyTuple_SetItem( MyPyObjRefList , 0 , ObjValue ) ;
397 #if PyDynInvokeTrace
398         cdebug << "ArgIn" << i << " : " << sname << " " << method << " " << " Value " << IORObjRef << " (objref) "
399                << MyPyObjRef->ob_refcnt << "/" << MyPyObjRefList->ob_refcnt << endl ;
400 #endif
401 //        ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
402         ResultObj = PyEvalCallObject( "PyObjRef" , MyPyObjRef , MyPyObjRefList ) ;
403 #if PyDynInvokeTrace
404         cdebug << "ObjValue->ob_refcnt" << ObjValue->ob_refcnt << endl ;
405 #endif
406         ArgValue = Py_BuildValue( "O" , ResultObj ) ;
407         PyTuple_SetItem( ArgsList , i , ArgValue ) ;
408 #if PyDynInvokeTrace
409         if ( ArgValue )
410           cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value  (objref) ArgsList->ob_refcnt"
411                  << ArgsList->ob_refcnt << " ArgValue->ob_refcnt" << ArgValue->ob_refcnt << endl ;
412         else
413           cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value  (objref) ArgsList->ob_refcnt"
414                  << ArgsList->ob_refcnt << " ArgValue is NULL" << endl ;
415         cdebug << "MyPyObjRefList->ob_refcnt " << MyPyObjRefList->ob_refcnt-1 << endl ;
416 #endif
417         Py_DECREF( MyPyObjRefList ) ;
418         if ( CORBA::is_nil( ObjRef ) ) {
419           ResultObj = NULL ;
420         }
421         else {
422 #if PyDynInvokeTrace
423           if ( ResultObj )
424             cdebug << "ResultObj->ob_refcnt " << ResultObj->ob_refcnt-1 << endl ;
425           else
426             cdebug << "ResultObj is NULL" << endl ;
427 #endif
428           if ( ResultObj )
429             Py_DECREF( ResultObj ) ;
430         }
431         break ;
432       }
433       default : {
434         cdebug << "ArgIn" << i << " : " << sname << " Value " << "(other ERROR)" << endl ;
435       }
436       }
437     }
438
439 //    Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
440     Result = PyEvalCallObject( method , MyPyRunMethod , ArgsList ) ;
441
442 #if PyDynInvokeTrace
443     cdebug << "ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
444 #endif
445
446     if ( Result == NULL ) {
447       cdebug_out << "GraphExecutor::InNode::PyDynInvoke Node " << Name() << " " << method << " Error Result == NULL"
448                  << endl ;
449       RetVal = false ;
450     }
451     else {
452       for ( i = 0 ; i < nOutParams ; i++ ) {
453         data = OutParametersList[i].Value ;
454         sname = OutParametersList[i].Name.c_str() ;
455         switch ( data.type()->kind() ) {
456         case CORBA::tk_string : {
457           char * t = "" ;
458           PyObject * ArgValue ;
459           if ( PyTuple_Check( Result ) ) {
460             ArgValue = PyTuple_GetItem( Result , i ) ;
461           }
462           else {
463             ArgValue = Result ;
464           }
465           if ( !PyString_Check( ArgValue ) ) {
466             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (string)" << endl ;
467             RetVal = false ;
468           }
469           else {
470             t = PyString_AsString( ArgValue ) ;
471           }
472           data <<= t ;
473 #if PyDynInvokeTrace
474           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << t << " (string)"
475                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
476                  << ArgValue->ob_refcnt << endl ;
477 #endif
478           break ;
479         }
480         case CORBA::tk_boolean : {
481           bool b = false ;
482           PyObject * ArgValue ;
483           if ( PyTuple_Check( Result ) ) {
484             ArgValue = PyTuple_GetItem( Result , i ) ;
485           }
486           else {
487             ArgValue = Result ;
488           }
489           if ( !PyInt_Check( ArgValue ) ) {
490             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (boolean)" << endl ;
491             RetVal = false ;
492           }
493           else {
494             b = PyInt_AsLong( ArgValue ) ;
495           }
496           data <<= (CORBA::Any::from_boolean ) b ;
497 #if PyDynInvokeTrace
498           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << b << " (boolean)"
499                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
500                  << ArgValue->ob_refcnt << endl ;
501 #endif
502           break ;
503         }
504         case CORBA::tk_char : {
505           unsigned char c = 0 ;
506           PyObject * ArgValue ;
507           if ( PyTuple_Check( Result ) ) {
508             ArgValue = PyTuple_GetItem( Result , i ) ;
509           }
510           else {
511             ArgValue = Result ;
512           }
513 //JR 04.04.2005 Debug          if ( !PyInt_Check( ArgValue ) ) {
514 //Difficult to understand that behavior ... Python char type is a string of length 1 !
515 //                                          or type is int ...
516           if ( !PyString_Check( ArgValue ) && !PyInt_Check( ArgValue ) ) {
517             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (char)" << endl ;
518             RetVal = false ;
519           }
520           else {
521             c = PyInt_AsLong( ArgValue ) ;
522           }
523           data <<= (CORBA::Any::from_char ) c ;
524 #if PyDynInvokeTrace
525           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << c << " (char)"
526                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
527                  << ArgValue->ob_refcnt << endl ;
528 #endif
529           break ;
530         }
531         case CORBA::tk_short : {
532           short s = 0 ;
533           PyObject * ArgValue ;
534           if ( PyTuple_Check( Result ) ) {
535             ArgValue = PyTuple_GetItem( Result , i ) ;
536           }
537           else {
538             ArgValue = Result ;
539           }
540           if ( !PyInt_Check( ArgValue ) ) {
541             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (short)" << endl ;
542             RetVal = false ;
543           }
544           else {
545             s = PyInt_AsLong( ArgValue ) ;
546           }
547           data <<= s ;
548 #if PyDynInvokeTrace
549           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << s << " (short)"
550                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
551                  << ArgValue->ob_refcnt << endl ;
552 #endif
553           break ;
554         }
555         case CORBA::tk_long : {
556           long l = 0 ;
557           PyObject * ArgValue ;
558           if ( PyTuple_Check( Result ) ) {
559             ArgValue = PyTuple_GetItem( Result , i ) ;
560           }
561           else {
562             ArgValue = Result ;
563           }
564           if ( PyLong_Check( ArgValue ) ) {
565             l = PyLong_AsLong( ArgValue ) ;
566           }
567           else if ( PyInt_Check( ArgValue ) ) {
568             l = PyInt_AsLong( ArgValue ) ;
569           }
570           else {
571             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (CORBA::tk_long)" << endl ;
572             RetVal = false ;
573           }
574           data <<= l ;
575 #if PyDynInvokeTrace
576           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << l << " (long)"
577                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
578                  << ArgValue->ob_refcnt << endl ;
579 #endif
580           break ;
581         }
582         case CORBA::tk_float : {
583           float f = 0 ;
584           PyObject * ArgValue ;
585           if ( PyTuple_Check( Result ) ) {
586             ArgValue = PyTuple_GetItem( Result , i ) ;
587           }
588           else {
589             ArgValue = Result ;
590           }
591           if ( !PyFloat_Check( ArgValue ) ) {
592             // mkr : bug PAL12454
593             if ( PyLong_Check( ArgValue ) ) {
594               cdebug << "ArgOut" << i << " : " << sname << " " << method << " OK (long)" << endl ;
595               long l = PyLong_AsLong( ArgValue );
596               f = (float) l;
597             }
598             else if ( PyInt_Check( ArgValue ) ) {
599               cdebug << "ArgOut" << i << " : " << sname << " " << method << " OK (int)" << endl ;
600               long l = PyInt_AsLong( ArgValue );
601               f = (float) l;
602             }
603             else {
604               cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (float)" << endl ;
605               RetVal = false ;
606             }
607           }
608           else {
609             f = PyFloat_AsDouble( ArgValue ) ;
610           }
611 #ifdef REDHAT // mkr : debug for PAL12255
612           data <<= f ;
613 #else
614           data.replace(CORBA::TypeCode::PR_float_tc(), (void*)(&f));
615 #endif
616 #if PyDynInvokeTrace
617           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << f << " (float)"
618                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
619                  << ArgValue->ob_refcnt << endl ;
620 #endif
621           break ;
622         }
623         case CORBA::tk_double : {
624           double d = 0 ;
625           PyObject * ArgValue ;
626           if ( PyTuple_Check( Result ) ) {
627             ArgValue = PyTuple_GetItem( Result , i ) ;
628           }
629           else {
630             ArgValue = Result ;
631           }
632           if ( !PyFloat_Check( ArgValue ) ) {
633             // mkr : bug PAL12454
634             if ( PyLong_Check( ArgValue ) ) {
635               cdebug << "ArgOut" << i << " : " << sname << " " << method << " OK (long)" << endl ;
636               long l = PyLong_AsLong( ArgValue );
637               d = (double) l;
638             }
639             else if ( PyInt_Check( ArgValue ) ) {
640               cdebug << "ArgOut" << i << " : " << sname << " " << method << " OK (int)" << endl ;
641               long l = PyInt_AsLong( ArgValue );
642               d = (double) l;
643             }
644             else {
645               cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (float)" << endl ;
646               RetVal = false ;
647             }
648           }
649           else {
650             d = PyFloat_AsDouble( ArgValue ) ;
651           }
652 #ifdef REDHAT // mkr : debug for PAL12255
653           data <<= d ;
654 #else
655           data.replace(CORBA::TypeCode::PR_double_tc(), (void*)(&d));
656 #endif
657 #if PyDynInvokeTrace
658           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << d << " (double)"
659                  << " Result->ob_refcnt" << Result->ob_refcnt << " ArgValue->ob_refcnt"
660                  << ArgValue->ob_refcnt << endl ;
661 #endif
662           break ;
663         }
664         case CORBA::tk_objref : {
665           PyObject * ObjIor ;
666           MyPyObjIorList = PyTuple_New( 1 ) ;
667           if ( PyTuple_Check( Result ) ) {
668             ObjIor = PyTuple_GetItem( Result , i ) ;
669           }
670           else {
671             ObjIor = Result ;
672           }
673 #if PyDynInvokeTrace
674           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(object reference) "
675                  << " Result->ob_refcnt" << Result->ob_refcnt << " ObjIor->ob_refcnt"
676                  << ObjIor->ob_refcnt << endl ;
677 #endif
678           Py_INCREF( ObjIor ) ;
679 //          PyObject_Print( ObjIor , stdout , 0 ) ;
680           PyTuple_SetItem( MyPyObjIorList , 0 , ObjIor ) ;
681 //          ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
682           ResultIor = PyEvalCallObject( "PyObjIor" , MyPyObjIor , MyPyObjIorList ) ;
683 #if PyDynInvokeTrace
684           cdebug << "ObjIor->ob_refcnt " << ObjIor->ob_refcnt-1 << endl ;
685 #endif
686           Py_DECREF( ObjIor ) ;
687 #if PyDynInvokeTrace
688           cdebug << "MyPyObjIorList->ob_refcnt " << MyPyObjIorList->ob_refcnt-1 << endl ;
689 #endif
690           Py_DECREF( MyPyObjIorList ) ;
691 #if PyDynInvokeTrace
692           cdebug << "MyPyObjIor->ob_refcnt " << MyPyObjIor->ob_refcnt << endl ;
693 #endif
694           if ( ResultIor ) {
695             char * IOR = NULL ;
696             IOR = PyString_AsString( ResultIor ) ;
697             ObjRef = StringToObject( IOR ) ;
698 //JR 05.08.2005 BUG OMNIORB4 ? : that line does run with SALOME_3 (OMNIOrb4) for
699 //                               object references ... (It's Ok with OMNIOrb3)
700 //                               IOR and ObjRef and IORObjRef are Ok
701 //                               BUT data contains a nil reference !!!
702 #if !omniORB_4_0_5
703             data <<= ObjRef ;
704 #else
705             SUPERV::SuperG_var mySuperVisionComponent ;
706             mySuperVisionComponent = theAutomaton->SuperVisionComponent() ;
707             if ( CORBA::is_nil( mySuperVisionComponent ) ) {
708               Engines::Container_var myContainer ;
709               Engines::Component_var myObjComponent ;
710               _OutNode->Graph()->StartComponent( ThreadNo() , "SuperVisionContainer" ,
711                                                  "SUPERV" ,
712                                                  myContainer , myObjComponent ) ;
713               mySuperVisionComponent = SUPERV::SuperG::_narrow( myObjComponent ) ;
714               theAutomaton->SuperVisionComponent( mySuperVisionComponent ) ;
715             }
716 //JR 24.08.2005 BUG OMNIORB4 ? : That does not run also ==> Comments
717 //            CORBA::Object_ptr ObjRef1 ;
718 //            ObjRef1 = mySuperVisionComponent->ToObject( ObjRef ) ;
719 //            data <<= ObjRef1 ;
720 //JR 24.08.2005 BUG OMNIORB4 ? : BUT THAT RUNS WITH THE "IDENTITY METHOD ToObject of SUPERV.idl :
721 //                               Object ToObject( in Object anObject ) ;
722 //CODE of that method !!! :
723 //CORBA::Object_ptr SuperV_Impl::ToObject( CORBA::Object_ptr anObjectRef ) {
724 //  beginService( "SuperV_Impl::ToObject" );
725 //  CORBA::Object_ptr anObject ;
726 //  anObject = CORBA::Object::_duplicate( anObjectRef ) ;
727 //  endService( "SuperV_Impl::ToObject" );
728 //  return anObject ;
729 //}
730 //BUT THAT RUNS ONLY IF WE USE Dynamic invocation of CORBA (DynInvoke)
731             ServicesAnyData anInParametersList ;
732             anInParametersList.Name = "anObjRef" ;
733             anInParametersList.Value <<= ObjRef ;
734             DynInvoke( mySuperVisionComponent , "ToObject" ,
735                        &anInParametersList , 1 , &OutParametersList[i] , 1 ) ;
736             data = OutParametersList[i].Value ;
737 #endif
738             IORObjRef = ObjectToString( ObjRef ) ;
739 #if PyDynInvokeTrace
740             cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value IORPy "
741                    << IOR << " IORObjRef " << IORObjRef << " (objref) " << endl ;
742 #endif
743             if ( CORBA::is_nil( ObjRef ) ) {
744 #if PyDynInvokeTrace
745               cdebug << "ObjRef ERROR(nil reference) ResultIor->ob_refcnt "
746                      << ResultIor->ob_refcnt-1 << endl ;
747 #endif
748               ResultIor = NULL ;
749             }
750             else {
751 #if PyDynInvokeTrace
752               cdebug << "ObjRef NOT(nil reference)ResultIor->ob_refcnt "
753                      << ResultIor->ob_refcnt-1 << endl ;
754 #endif
755               Py_DECREF( ResultIor ) ;
756             }
757           }
758           else {
759             cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error ResultIor == NULL Node "
760                        << Name() << " method " << method << " " << endl ;
761             RetVal = false ;
762           }
763           break ;
764         }
765         default : {
766           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(other ERROR)" << endl ;
767             RetVal = false ;
768         }
769         }
770 //JR 05.08.2005 BUG OMNIORB4 ? : that line does run with SALOME_3 (OMNIOrb4) for
771 //                               object references ...
772         OutParametersList[i].Value = data ;
773 //        if ( data.type()->kind() == CORBA::tk_objref ) {
774 //          IORObjRef = ObjectToString( ObjRef ) ;
775 //#if PyDynInvokeTrace
776 //          cdebug << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke Node " << Name()
777 //                 << "ArgOut" << i << " : " << sname << " " << method << " ObjRef "
778 //                 << IORObjRef << " (objref) " << endl ;
779 //          Engines::Component_var theObjComponent ;
780 //          theObjComponent = Engines::Component::_narrow( ObjRef ) ;
781 //          DynInvoke( theObjComponent , "ping" , NULL , 0 , NULL , 0 ) ;
782 //#endif
783 //          Engines::Container_var myContainer ;
784 //          Engines::Component_var myObjComponent ;
785 //          _OutNode->Graph()->StartComponent( ThreadNo() , "SuperVisionContainer" ,
786 //                                             "SUPERV" ,
787 //                                              myContainer , myObjComponent ) ;
788 //          SUPERV::SuperG_var mySuperVisionComponent ;
789 //          mySuperVisionComponent = SUPERV::SuperG::_narrow( myObjComponent ) ;
790 //          CORBA::Object_ptr ObjRef1 ;
791 //          ObjRef1 = mySuperVisionComponent->ToObject( IORObjRef ) ;
792 //#if PyDynInvokeTrace
793 //          IORObjRef = ObjectToString( ObjRef1 ) ;
794 //          cdebug << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke Node " << Name()
795 //                 << "ArgOut" << i << " : " << sname << " " << method << " ToObject "
796 //                 << IORObjRef << " (objref) " << endl ;
797 //#endif
798
799 //          ServicesAnyData anInParametersList ;
800 //          anInParametersList.Name = "anIORObjRef" ;
801 //          anInParametersList.Value <<= IORObjRef ;
802 //          DynInvoke( mySuperVisionComponent , "ToObject" ,
803 //                     &anInParametersList , 1 , &OutParametersList[i] , 1 ) ;
804 //#if PyDynInvokeTrace
805 //          OutParametersList[i].Value >>= ObjRef1 ;
806 //          IORObjRef = ObjectToString( ObjRef1 ) ;
807 //          cdebug << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke Node " << Name()
808 //                 << "ArgOut" << i << " : " << sname << " " << method
809 //                 << " DynInvoke(ToObject) " << IORObjRef << " (objref) " << endl ;
810 //#endif
811 //        }
812       }
813
814 #if PyDynInvokeTrace
815       cdebug << "InNode::PyDynInvoke Result->ob_refcnt " << Result->ob_refcnt-1 << endl ;
816 #endif
817       Py_DECREF( Result ) ;
818     }
819
820 #if PyDynInvokeTrace
821     cdebug << "InNode::PyDynInvoke ArgsList->ob_refcnt " << ArgsList->ob_refcnt-1 << endl ;
822 #endif
823     Py_DECREF( ArgsList ) ;
824   }
825
826 #if 0
827   {
828     int i ;
829     for ( i = 0 ; i < nInParams ; i++ ) { // Without Gates
830       cdebug << "InParametersList[" << i << "] : "
831              << InParametersList[i].Name << " "
832              << AnyValue( InParametersList[i].Value ) << endl ;
833     }
834     for ( i = 0 ; i < nOutParams ; i++ ) { // Without Gates
835       cdebug << "OutParametersList[" << i << "] : "
836              << OutParametersList[i].Name << " "
837              << AnyValue( OutParametersList[i].Value ) << endl ;
838     }
839   }
840 #endif
841
842 #if PyDynInvokeTrace
843   cdebug_out << "GraphExecutor::InNode::PyDynInvoke Node " << Name() << " method " << method << " " << RetVal
844              << endl ;
845 #endif
846
847   return RetVal ;
848
849 }
850
851 bool GraphExecutor::InNode::PyRunSimpleString( char* thePyString )
852 {
853   const bool ErrorValue = true;
854   bool aRet;
855   try {
856 #if PyDynInvokeTrace
857     MESSAGE( pthread_self() << "Python method beginning : " << thePyString );
858     cdebug_in << pthread_self() << "Python method beginning : " << thePyString << endl ;
859 #endif
860     aRet = PyRun_SimpleString( thePyString );
861     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
862     //aRet = _OutNode->SuperVisionContainer()->ActivatePythonExecution( thePyString ) ;
863 #if PyDynInvokeTrace
864     MESSAGE( pthread_self() << "Python method finished." );
865     cdebug_out << pthread_self() << "Python method finished." << endl ;
866 #endif
867   } catch( ... ) {
868     MESSAGE( pthread_self() << "ERROR: Exception caught running Python method." );
869     cdebug_out << pthread_self() << "ERROR: Exception caught running Python method."
870                << endl ;
871     MESSAGE( "       Python was reinitialized.  Previous Python definitions are lost" );
872     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
873     Py_Finalize();
874     Py_Initialize();
875     Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod );
876     _OutNode->PyInitialized( false );
877     aRet = ErrorValue;
878   }
879   return aRet;
880 }
881
882 PyObject * GraphExecutor::InNode::PyEvalCallObject( const char *method ,
883                                                     PyObject * MyPyRunMethod ,
884                                                     PyObject * ArgsList ) {
885 //  cdebug_in << "Executor::InNode::PyEvalCallObject " << Name() << endl ;
886   PyObject * Result = NULL ;
887   try {
888 //    MESSAGE( pthread_self() << "PyEval_CallObject " << Name() << " method beginning : " << method );
889 //    cdebug << pthread_self() << "PyEval_CallObject " << Name() << " method beginning : " << method << endl ;
890     Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
891     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
892     //Result = _OutNode->SuperVisionContainer()->ActivatePythonExecution( MyPyRunMethod , ArgsList ) ;
893 //    MESSAGE( pthread_self() << "PyEval_CallObject method finished. Result " << Result );
894 //    cdebug << pthread_self() << "PyEval_CallObject method finished. Result " << Result << endl ;
895 //    cdebug_out << "Executor::InNode::PyEvalCallObject " << Name() << endl ;
896   } catch( ... ) {
897     MESSAGE( pthread_self() << "ERROR: Exception caught PyEval_CallObject " << Name()
898              << " Python method " << method << ". Result "  << Result );
899     cdebug << pthread_self() << "ERROR: Exception caught PyEval_CallObject " << Name()
900            << " Python method " << method << ". Result " << Result << endl ;
901     MESSAGE( "       Python was reinitialized.  Previous Python definitions are lost Py_IsInitialized " << Py_IsInitialized() );
902 //JR ===> fatal error in python : no current thread
903     // asv : 20.01.05 : changes involved with switching to old (HEAD) KERNEL    
904     Py_Finalize();
905     Py_Initialize();
906     Automaton()->PyInitModule( false ) ;
907     Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod );
908     _OutNode->PyInitialized( false );
909
910     if ( Result == NULL ) {
911       Kill() ; // Reset of _ThreadId
912     }
913 //    cdebug << "Executor::InNode::PyEvalCallObject ERROR catched " << Name()
914 //           << " Py_IsInitialized " << Py_IsInitialized() << endl ;
915   }
916 //  cdebug_out << "Executor::InNode::PyEvalCallObject " << Name() << endl ;
917   return Result ;
918 }