+{
+ if(_mode=="remote")
+ executeRemote();
+ else
+ executeLocal();
+}
+
+void PyFuncNode::executeRemote()
+{
+ DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
+ if(!_pyfuncSer)
+ throw Exception("DistributedPythonNode badly loaded");
+ Py_ssize_t len;
+ char *serializationInputC(0);
+ PyObject *args(0),*ob(0);
+ int pos(0);
+ {
+ AutoGIL agil;
+
+ //===========================================================================
+ // Get inputs in input ports, build a Python tuple and pickle it
+ //===========================================================================
+ args = PyTuple_New(getNumberOfInputPorts());
+ std::list<InputPort *>::iterator iter2;
+ for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2)
+ {
+ InputPyPort *p=(InputPyPort *)*iter2;
+ ob=p->getPyObj();
+ Py_INCREF(ob);
+ PyTuple_SetItem(args,pos,ob);
+ pos++;
+ }
+#ifdef _DEVDEBUG_
+ PyObject_Print(args,stderr,Py_PRINT_RAW);
+ std::cerr << endl;
+#endif
+ PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args);
+ //The pickled string may contain NULL characters so use PyString_AsStringAndSize
+ if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len))
+ throw Exception("DistributedPythonNode problem in python pickle");
+ }
+
+ Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs;
+ serializationInputCorba->length(len);
+ for(int i=0; i < len ; i++)
+ serializationInputCorba[i]=serializationInputC[i];
+
+ //===========================================================================
+ // Execute in remote Python node
+ //===========================================================================
+ DEBTRACE( "-----------------starting remote python invocation-----------------" );
+ Engines::pickledArgs_var resultCorba;
+ try
+ {
+ resultCorba=_pynode->execute(getFname().c_str(),serializationInputCorba);
+ }
+ catch( const SALOME::SALOME_Exception& ex )
+ {
+ std::string msg="Exception on remote python invocation";
+ msg += '\n';
+ msg += ex.details.text.in();
+ _errorDetails=msg;
+ throw Exception(msg);
+ }
+ DEBTRACE( "-----------------end of remote python invocation-----------------" );
+ //===========================================================================
+ // Get results, unpickle and put them in output ports
+ //===========================================================================
+ char *resultCorbaC=new char[resultCorba->length()+1];
+ resultCorbaC[resultCorba->length()]='\0';
+ for(int i=0;i<resultCorba->length();i++)
+ resultCorbaC[i]=resultCorba[i];
+
+ {
+ AutoGIL agil;
+
+ PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length());
+ delete [] resultCorbaC;
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args,0,resultPython);
+ PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args);
+ Py_DECREF(args);
+
+ DEBTRACE( "-----------------PythonNode::outputs-----------------" );
+ int nres=1;
+ if(finalResult == Py_None)
+ nres=0;
+ else if(PyTuple_Check(finalResult))
+ nres=PyTuple_Size(finalResult);
+
+ if(getNumberOfOutputPorts() != nres)
+ {
+ std::string msg="Number of output arguments : Mismatch between definition and execution";
+ Py_DECREF(finalResult);
+ _errorDetails=msg;
+ throw Exception(msg);
+ }
+
+ pos=0;
+ std::list<OutputPort *>::iterator iter;
+ try
+ {
+ for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter)
+ {
+ OutputPyPort *p=(OutputPyPort *)*iter;
+ DEBTRACE( "port name: " << p->getName() );
+ DEBTRACE( "port kind: " << p->edGetType()->kind() );
+ DEBTRACE( "port pos : " << pos );
+ if(PyTuple_Check(finalResult))
+ ob=PyTuple_GetItem(finalResult,pos) ;
+ else
+ ob=finalResult;
+ DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
+ p->put(ob);
+ pos++;
+ }
+ Py_DECREF(finalResult);
+ }
+ catch(ConversionException& ex)
+ {
+ Py_DECREF(finalResult);
+ _errorDetails=ex.what();
+ throw;
+ }
+ }
+
+ DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" );
+}
+
+void PyFuncNode::executeLocal()