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