1 // SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
3 // Copyright (C) 2003 CEA/DEN, EDF R&D
7 // File : DataFlowExecutor_PyDynInvoke.cxx
8 // Author : Jean Rahuel, CEA
17 #include "DataFlowExecutor_InNode.hxx"
19 using namespace CORBA ;
21 static PyObject * MyPyObjRef = NULL ;
22 static PyObject * MyPyObjIor = NULL ;
23 static PyObject * MyPyRunMethod = NULL ;
25 static PyMethodDef MethodPyRunMethod[] = {
26 { "RunMethod", PyRunMethod, METH_VARARGS },
30 bool GraphExecutor::InNode::InitPython() {
31 cdebug_in << "InitPython" << endl ;
33 Automaton()->PyLock() ;
34 // PyObject * Module = Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
35 if ( !Automaton()->PyInitModule() ) {
36 Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
38 // PyObject * Dictionnary = PyModule_GetDict( Module ) ;
39 // InitPyDynInvokeError = PyErr_NewException( "InitPyDynInvokeError" , NULL , NULL ) ;
40 // PyDict_SetItemString( Dictionnary , InitPyDynInvokeError ) ;
41 cdebug << ThreadNo() << "Py_Initialized() " << endl ;
43 if ( Automaton()->PyFunction( "PyObjRef" ) == NULL ) {
45 // aPyFunc = "print 'InitPyRunMethod'\n" ;
46 aPyFunc = "import InitPyRunMethod\n" ;
47 // aPyFunc += "print 'sys'\n" ;
48 aPyFunc += "import sys\n" ;
49 // aPyFunc += "print 'CORBA'\n" ;
50 aPyFunc += "import CORBA\n" ;
51 // aPyFunc += "print 'omniORB'\n" ;
52 aPyFunc += "import omniORB\n" ;
53 // aPyFunc += "print 'PyObjRef'\n" ;
54 aPyFunc += "def PyObjRef( IORObjStr ) :\n" ;
55 // aPyFunc += " print 'PyObjRef',IORObjStr\n" ;
56 aPyFunc += " orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
57 // aPyFunc += " print 'PyObjRef orb',orb\n" ;
58 aPyFunc += " objref = orb.string_to_object( IORObjStr )\n" ;
59 // aPyFunc += " print 'PyObjRef IORObjStr objref',IORObjStr,objref\n" ;
60 aPyFunc += " return objref\n" ;
61 aPyFunc += "InitPyRunMethod.RunMethod( PyObjRef )\n" ;
62 if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
63 cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
64 Automaton()->PyUnLock() ;
67 MyPyObjRef = MyPyRunMethod ;
68 Automaton()->PyFunction( "PyObjRef" , MyPyObjRef ) ;
71 MyPyObjRef = Automaton()->PyFunction( "PyObjRef" ) ;
74 if ( Automaton()->PyFunction( "PyObjIor" ) == NULL ) {
76 aPyFunc = "import InitPyRunMethod\n" ;
77 aPyFunc += "import sys\n" ;
78 aPyFunc += "import CORBA\n" ;
79 aPyFunc += "import omniORB\n" ;
80 aPyFunc += "def PyObjIor( ObjRef ) :\n" ;
81 // aPyFunc += " print 'PyObjIor',ObjRef\n" ;
82 aPyFunc += " orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
83 // aPyFunc += " print 'PyObjIor orb',orb\n" ;
84 aPyFunc += " objIor = orb.object_to_string( ObjRef )\n" ;
85 // aPyFunc += " print 'PyObjIor ObjRef objIor',ObjRef,objIor\n" ;
86 aPyFunc += " return objIor\n" ;
87 aPyFunc += "InitPyRunMethod.RunMethod( PyObjIor )\n" ;
88 if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
89 cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
90 Automaton()->PyUnLock() ;
93 MyPyObjIor = MyPyRunMethod ;
94 Automaton()->PyFunction( "PyObjIor" , MyPyObjIor ) ;
97 MyPyObjIor = Automaton()->PyFunction( "PyObjIor" ) ;
99 Automaton()->PyUnLock() ;
101 cdebug_out << "InitPython" << endl ;
106 PyObject * GraphExecutor::InNode::InitPyDynInvoke( char * PyFuncName ,
107 const SUPERV::ListOfStrings * aPythonFunction ) {
110 PyObject * thePyRunMethod = NULL ;
112 cdebug_in << "InitPyDynInvoke '" << PyFuncName << "' length " << (*aPythonFunction).length() << endl ;
114 if ( strlen( PyFuncName ) ) {
115 Automaton()->PyLock() ;
116 thePyRunMethod = Automaton()->PyFunction( PyFuncName ) ;
117 if ( (*aPythonFunction).length() ) {
118 if ( thePyRunMethod == NULL ) {
120 aPyFunc += "import InitPyRunMethod\n" ;
121 for ( i = 0 ; i < (*aPythonFunction).length() ; i++ ) {
122 aPyFunc += (*aPythonFunction)[ i ] ;
125 aPyFunc += "InitPyRunMethod.RunMethod( " ;
126 aPyFunc += PyFuncName ;
128 /*cdebug *///cout<< "InitPyDynInvoke PyRun_SimpleString " << endl << aPyFunc << endl ;
129 if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
130 cdebug << ThreadNo() << " " << Name() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
134 PyFuncRunned( true ) ;
135 thePyRunMethod = MyPyRunMethod ;
137 Automaton()->PyFunction( PyFuncName , thePyRunMethod ) ;
138 cdebug << ThreadNo() << "PyRun_SimpleString( " << (*aPythonFunction)[ 0 ] << " ) " << endl ;
142 Automaton()->PyUnLock() ;
143 cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod " << thePyRunMethod << " "
144 << thePyRunMethod->ob_refcnt << endl ;
145 return thePyRunMethod ;
148 else if ( thePyRunMethod ) {
149 Automaton()->PyUnLock() ;
150 cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod " << thePyRunMethod << " "
151 << thePyRunMethod->ob_refcnt << endl ;
152 return thePyRunMethod ;
154 Automaton()->PyUnLock() ;
157 cdebug_out << "InitPyDynInvoke '" << PyFuncName << "' thePyRunMethod Null" << endl ;
162 extern "C" PyObject * PyRunMethod( PyObject * dummy , PyObject * Args ) {
163 PyObject * Result = NULL ;
164 PyObject * Temp = NULL ;
165 if ( PyArg_ParseTuple( Args , "O:set_callback" , & Temp ) ) {
166 // cout << "PyArg_ParsedTuple" << endl ;
167 if ( !PyCallable_Check( Temp ) ) {
168 // PyErr_SetString( PyExc_TypeError , "PyRunMethod must be callable" ) ;
169 // cout << "PyRunMethod must be callable" << endl ;
173 Py_XDECREF( MyPyRunMethod ) ;
174 MyPyRunMethod = Temp ;
175 Py_INCREF( Py_None ) ;
181 bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
183 ServicesAnyData * inParams , int nInParams ,
184 ServicesAnyData * outParams , int nOutParams ) {
189 int n_in = nInParams ;
190 int n_out = nOutParams ;
193 cdebug_in << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke Node " << Name() << " method " << method
194 << " " << n_in << " InArgs " << n_out << " OutArgs MyPyRunMethod " ;
195 if ( MyPyRunMethod ) {
196 cdebug << MyPyRunMethod << " " << MyPyRunMethod->ob_refcnt << endl ;
199 cdebug << " NULL" << endl ;
205 PyObject * ArgsList = NULL ;
206 PyObject * ArgValue = NULL ;
207 PyObject * Result = NULL ;
208 PyObject * MyPyObjRefList = NULL ;
209 PyObject * ResultObj = NULL ;
210 PyObject * MyPyObjIorList = NULL ;
211 PyObject * ResultIor = NULL ;
213 CORBA::Object_ptr ObjRef ;
216 if ( !PyCallable_Check( MyPyRunMethod ) ) {
221 ArgsList = PyTuple_New( n_in ) ;
223 for ( i = 0 ; i < n_in ; i++ ) {
224 data = inParams[i].Value ;
225 sname = inParams[i].Name.c_str() ;
226 switch ( data.type()->kind() ) {
227 case CORBA::tk_string : {
230 ArgValue = Py_BuildValue( "s" , t ) ;
231 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
232 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << t << " (string) "
233 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
234 << ArgValue->ob_refcnt << endl ;
237 case CORBA::tk_boolean : {
239 data >>= (CORBA::Any::to_boolean ) b ;
240 ArgValue = Py_BuildValue( "b" , b ) ;
241 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
242 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << b
243 << " (boolean) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
244 << ArgValue->ob_refcnt << endl ;
247 case CORBA::tk_char : {
249 data >>= (CORBA::Any::to_char ) c ;
250 ArgValue = Py_BuildValue( "c" , c ) ;
251 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
252 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << c
253 << " (char) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
254 << ArgValue->ob_refcnt << endl ;
257 case CORBA::tk_short : {
260 ArgValue = Py_BuildValue( "h" , s ) ;
261 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
262 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << s
263 << " (short) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
264 << ArgValue->ob_refcnt << endl ;
267 case CORBA::tk_long : {
270 ArgValue = Py_BuildValue( "l" , l ) ;
271 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
272 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << l
273 << " (long) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
274 << ArgValue->ob_refcnt << endl ;
277 case CORBA::tk_float : {
280 ArgValue = Py_BuildValue( "f" , f ) ;
281 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
282 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << f
283 << " (float) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
284 << ArgValue->ob_refcnt << endl ;
287 case CORBA::tk_double : {
290 ArgValue = Py_BuildValue( "d" , d ) ;
291 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
292 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << d
293 << " (double) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
294 << ArgValue->ob_refcnt << endl ;
297 case CORBA::tk_objref : {
298 MyPyObjRefList = PyTuple_New( 1 ) ;
299 PyObject * ObjValue ;
301 IORObjRef = ObjectToString( ObjRef ) ;
302 ObjValue = Py_BuildValue( "s" , IORObjRef ) ;
303 PyTuple_SetItem( MyPyObjRefList , 0 , ObjValue ) ;
304 cdebug << "ArgIn" << i << " : " << sname << " " << method << " " << " Value " << IORObjRef << " (objref) "
305 << MyPyObjRef->ob_refcnt << "/" << MyPyObjRefList->ob_refcnt << endl ;
306 ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
307 cdebug << "ObjValue->ob_refcnt" << ObjValue->ob_refcnt << endl ;
308 ArgValue = Py_BuildValue( "O" , ResultObj ) ;
309 PyTuple_SetItem( ArgsList , i , ArgValue ) ;
310 cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value (objref) ArgsList->ob_refcnt"
311 << ArgsList->ob_refcnt << " ArgValue->ob_refcnt" << ArgValue->ob_refcnt << endl ;
312 cdebug << "MyPyObjRefList->ob_refcnt " << MyPyObjRefList->ob_refcnt-1 << endl ;
313 Py_DECREF( MyPyObjRefList ) ;
314 if ( CORBA::is_nil( ObjRef ) ) {
318 cdebug << "ResultObj->ob_refcnt " << ResultObj->ob_refcnt-1 << endl ;
319 Py_DECREF( ResultObj ) ;
324 cdebug << "ArgIn" << i << " : " << sname << " Value " << "(other ERROR)" << endl ;
329 Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
331 cdebug << "ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
333 if ( Result == NULL ) {
334 cdebug_out << "GraphExecutor::InNode::PyDynInvoke Node " << Name() << " " << method << " Error Result == NULL"
339 for ( i = 0 ; i < n_out ; i++ ) {
340 data = outParams[i].Value ;
341 sname = outParams[i].Name.c_str() ;
342 switch ( data.type()->kind() ) {
343 case CORBA::tk_string : {
345 if ( PyTuple_Check( Result ) ) {
346 ArgValue = PyTuple_GetItem( Result , i ) ;
351 if ( !PyString_Check( ArgValue ) ) {
352 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (string)" << endl ;
355 t = PyString_AsString( ArgValue ) ;
358 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << t << " (string)"
359 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
360 << ArgValue->ob_refcnt << endl ;
363 case CORBA::tk_boolean : {
365 if ( PyTuple_Check( Result ) ) {
366 ArgValue = PyTuple_GetItem( Result , i ) ;
371 if ( !PyInt_Check( ArgValue ) ) {
372 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (boolean)" << endl ;
375 b = PyInt_AsLong( ArgValue ) ;
377 data <<= (CORBA::Any::from_boolean ) b ;
378 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << b << " (boolean)"
379 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
380 << ArgValue->ob_refcnt << endl ;
383 case CORBA::tk_char : {
384 unsigned char c = 0 ;
385 if ( PyTuple_Check( Result ) ) {
386 ArgValue = PyTuple_GetItem( Result , i ) ;
391 if ( !PyInt_Check( ArgValue ) ) {
392 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (char)" << endl ;
395 c = PyInt_AsLong( ArgValue ) ;
397 data <<= (CORBA::Any::from_char ) c ;
398 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << c << " (char)"
399 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
400 << ArgValue->ob_refcnt << endl ;
403 case CORBA::tk_short : {
405 if ( PyTuple_Check( Result ) ) {
406 ArgValue = PyTuple_GetItem( Result , i ) ;
411 if ( !PyInt_Check( ArgValue ) ) {
412 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (short)" << endl ;
415 s = PyInt_AsLong( ArgValue ) ;
418 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << s << " (short)"
419 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
420 << ArgValue->ob_refcnt << endl ;
423 case CORBA::tk_long : {
425 if ( PyTuple_Check( Result ) ) {
426 ArgValue = PyTuple_GetItem( Result , i ) ;
431 if ( PyLong_Check( ArgValue ) ) {
432 l = PyLong_AsLong( ArgValue ) ;
434 else if ( PyInt_Check( ArgValue ) ) {
435 l = PyInt_AsLong( ArgValue ) ;
438 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (CORBA::tk_long)" << endl ;
441 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << l << " (long)"
442 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
443 << ArgValue->ob_refcnt << endl ;
446 case CORBA::tk_float : {
448 if ( PyTuple_Check( Result ) ) {
449 ArgValue = PyTuple_GetItem( Result , i ) ;
454 if ( !PyFloat_Check( ArgValue ) ) {
455 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (float)" << endl ;
458 f = PyFloat_AsDouble( ArgValue ) ;
461 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << f << " (float)"
462 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
463 << ArgValue->ob_refcnt << endl ;
466 case CORBA::tk_double : {
468 if ( PyTuple_Check( Result ) ) {
469 ArgValue = PyTuple_GetItem( Result , i ) ;
474 if ( !PyFloat_Check( ArgValue ) ) {
475 cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (double)" << endl ;
478 d = PyFloat_AsDouble( ArgValue ) ;
481 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << d << " (double)"
482 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
483 << ArgValue->ob_refcnt << endl ;
486 case CORBA::tk_objref : {
488 MyPyObjIorList = PyTuple_New( 1 ) ;
489 if ( PyTuple_Check( Result ) ) {
490 ObjIor = PyTuple_GetItem( Result , i ) ;
495 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(object reference) "
496 << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ObjIor->ob_refcnt"
497 << ObjIor->ob_refcnt << endl ;
498 Py_INCREF( ObjIor ) ;
499 // PyObject_Print( ObjIor , stdout , 0 ) ;
500 PyTuple_SetItem( MyPyObjIorList , 0 , ObjIor ) ;
501 ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
502 cdebug << "ObjIor->ob_refcnt " << ObjIor->ob_refcnt-1 << endl ;
503 Py_DECREF( ObjIor ) ;
504 cdebug << "MyPyObjIorList->ob_refcnt " << MyPyObjIorList->ob_refcnt-1 << endl ;
505 Py_DECREF( MyPyObjIorList ) ;
506 cdebug << "MyPyObjIor->ob_refcnt " << MyPyObjIor->ob_refcnt << endl ;
509 IOR = PyString_AsString( ResultIor ) ;
510 ObjRef = StringToObject( IOR ) ;
512 IORObjRef = ObjectToString( ObjRef ) ;
513 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << IORObjRef << " (objref) "
515 if ( CORBA::is_nil( ObjRef ) ) {
519 cdebug << "ResultIor->ob_refcnt " << ResultIor->ob_refcnt-1 << endl ;
520 Py_DECREF( ResultIor ) ;
524 cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error ResultIor == NULL Node "
525 << Name() << " method " << method << " " << endl ;
531 cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(other ERROR)" << endl ;
534 outParams[i].Value = data ;
537 cdebug << "Result->ob_refcnt" << Result->ob_refcnt-1 << endl ;
538 Py_DECREF( Result ) ;
541 cdebug << "GraphExecutor::InNode::PyDynInvoke ArgsList->ob_refcnt"
542 << ArgsList->ob_refcnt-1 << endl ;
543 Py_DECREF( ArgsList ) ;
546 cdebug_out << "GraphExecutor::InNode::PyDynInvoke Node " << Name() << " method " << method << " " << RetVal