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