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