X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2FPythonNode.cxx;h=72df372bfd25ab52161f5a1aa3f94d0422448265;hb=36258ae9ce33e2ddf2ee6c421f5f4dee2d5bf3e2;hp=bd33fbd14b6b1b952222d363c2a4368afe037f65;hpb=ab310dc68c4114bae2a1744fbd424029b2aa68fe;p=modules%2Fyacs.git diff --git a/src/runtime/PythonNode.cxx b/src/runtime/PythonNode.cxx index bd33fbd14..72df372bf 100644 --- a/src/runtime/PythonNode.cxx +++ b/src/runtime/PythonNode.cxx @@ -21,8 +21,11 @@ #include "PythonNode.hxx" #include "PythonPorts.hxx" #include "TypeCode.hxx" +#include "AutoGIL.hxx" #include "Container.hxx" #include "SalomeContainer.hxx" +#include "SalomeHPContainer.hxx" +#include "SalomeContainerTmpForHP.hxx" #include "ConversionException.hxx" #include "PyStdout.hxx" @@ -48,68 +51,232 @@ using namespace std; const char PythonNode::IMPL_NAME[]="Python"; const char PythonNode::KIND[]="Python"; -PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father) +const char PythonNode::SCRIPT_FOR_SERIALIZATION[]="import cPickle\n" + "def pickleForDistPyth2009(kws):\n" + " return cPickle.dumps(((),kws),-1)\n" + "\n" + "def unPickleForDistPyth2009(st):\n" + " args=cPickle.loads(st)\n" + " return args\n"; + +const char PyFuncNode::SCRIPT_FOR_SERIALIZATION[]="import cPickle\n" + "def pickleForDistPyth2009(*args,**kws):\n" + " return cPickle.dumps((args,kws),-1)\n" + "\n" + "def unPickleForDistPyth2009(st):\n" + " args=cPickle.loads(st)\n" + " return args\n"; + +PythonEntry::PythonEntry():_context(0),_pyfuncSer(0),_pyfuncUnser(0) { - _implementation=IMPL_NAME; - PyGILState_STATE gstate=PyGILState_Ensure(); - _context=PyDict_New(); - if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) +} + +PythonEntry::~PythonEntry() +{ + AutoGIL agil; + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + Py_XDECREF(_pyfuncUnser); + Py_XDECREF(_pyfuncSer); + Py_XDECREF(_context); +} + +void PythonEntry::commonRemoteLoad(InlineNode *reqNode) +{ + DEBTRACE( "---------------PythonEntry::CommonRemoteLoad function---------------" ); + Container *container(reqNode->getContainer()); + bool isContAlreadyStarted(false); + if(container) + { + isContAlreadyStarted=container->isAlreadyStarted(reqNode); + if(!isContAlreadyStarted) + { + try + { + container->start(reqNode); + } + catch(Exception& e) + { + reqNode->setErrorDetails(e.what()); + throw e; + } + } + } + else + { + std::string what("PythonEntry::CommonRemoteLoad : a load operation requested on \""); + what+=reqNode->getName(); what+="\" with no container specified."; + reqNode->setErrorDetails(what); + throw Exception(what); + } + Engines::Container_var objContainer=Engines::Container::_nil(); + if(!container) + throw Exception("No container specified !"); + SalomeContainer *containerCast0(dynamic_cast(container)); + SalomeHPContainer *containerCast1(dynamic_cast(container)); + if(containerCast0) + objContainer=containerCast0->getContainerPtr(reqNode); + else if(containerCast1) { - stringstream msg; - msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; - PyGILState_Release(gstate); - _errorDetails=msg.str(); - throw Exception(msg.str()); + YACS::BASES::AutoCppPtr tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,reqNode)); + objContainer=tmpCont->getContainerPtr(reqNode); } - PyGILState_Release(gstate); + else + throw Exception("Unrecognized type of container ! Salome one is expected for PythonNode/PyFuncNode !"); + if(CORBA::is_nil(objContainer)) + throw Exception("Container corba pointer is NULL for PythonNode !"); + bool isInitializeRequested(false); + try + { + if(containerCast0) + { + createRemoteAdaptedPyInterpretor(objContainer); + } + else + { + Engines::PyNodeBase_var dftPyScript(retrieveDftRemotePyInterpretorIfAny(objContainer)); + if(CORBA::is_nil(dftPyScript)) + { + isInitializeRequested=true; + createRemoteAdaptedPyInterpretor(objContainer); + } + else + assignRemotePyInterpretor(dftPyScript); + } + } + catch( const SALOME::SALOME_Exception& ex ) + { + std::string msg="Exception on remote python node creation "; + msg += '\n'; + msg += ex.details.text.in(); + reqNode->setErrorDetails(msg); + throw Exception(msg); + } + Engines::PyNodeBase_var pynode(getRemoteInterpreterHandle()); + if(CORBA::is_nil(pynode)) + throw Exception("In PythonNode the ref in NULL ! "); + /// + { + AutoGIL agil; + const char *picklizeScript(getSerializationScript()); + PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context); + if(res == NULL) + { + std::string errorDetails; + PyObject* new_stderr = newPyStdOut(errorDetails); + reqNode->setErrorDetails(errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during load"); + } + Py_DECREF(res); + _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009"); + _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009"); + if(_pyfuncSer == NULL) + { + std::string errorDetails; + PyObject *new_stderr(newPyStdOut(errorDetails)); + reqNode->setErrorDetails(errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during load"); + } + if(_pyfuncUnser == NULL) + { + std::string errorDetails; + PyObject *new_stderr(newPyStdOut(errorDetails)); + reqNode->setErrorDetails(errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during load"); + } + if(isInitializeRequested) + {//This one is called only once at initialization in the container if an init-script is specified. + try + { + std::string zeInitScriptKey(container->getProperty(HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)); + if(!zeInitScriptKey.empty()) + pynode->executeAnotherPieceOfCode(zeInitScriptKey.c_str()); + } + catch( const SALOME::SALOME_Exception& ex ) + { + std::string msg="Exception on PythonNode::loadRemote python invocation of initializisation py script !"; + msg += '\n'; + msg += ex.details.text.in(); + reqNode->setErrorDetails(msg); + throw Exception(msg); + } + } + DEBTRACE( "---------------End PyNode::loadRemote function---------------" ); + } +} + +PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father) +{ + _implementation=IMPL_NAME; + { + AutoGIL agil; + _context=PyDict_New(); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; + _errorDetails=msg.str(); + throw Exception(msg.str()); + } + } } PythonNode::PythonNode(const std::string& name):InlineNode(name) { _implementation=IMPL_NAME; - PyGILState_STATE gstate = PyGILState_Ensure(); - _context=PyDict_New(); - if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) - { - stringstream msg; - msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; - PyGILState_Release(gstate); - _errorDetails=msg.str(); - throw Exception(msg.str()); - } - PyGILState_Release(gstate); + { + AutoGIL agil; + _context=PyDict_New(); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; + _errorDetails=msg.str(); + throw Exception(msg.str()); + } + } } PythonNode::~PythonNode() { - PyGILState_STATE gstate = PyGILState_Ensure(); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - Py_DECREF(_context); - PyGILState_Release(gstate); + if(!CORBA::is_nil(_pynode)) + { + _pynode->UnRegister(); + } } void PythonNode::checkBasicConsistency() const throw(YACS::Exception) { DEBTRACE("checkBasicConsistency"); InlineNode::checkBasicConsistency(); - - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject* res; - res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input); - if(res == NULL) - { - std::string error=""; - PyObject* new_stderr = newPyStdOut(error); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - PyGILState_Release(gstate); - throw Exception(error); - } - else - Py_XDECREF(res); - PyGILState_Release(gstate); + { + AutoGIL agil; + PyObject* res; + res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input); + if(res == NULL) + { + std::string error=""; + PyObject* new_stderr = newPyStdOut(error); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception(error); + } + else + Py_XDECREF(res); + } } void PythonNode::load() @@ -129,97 +296,7 @@ void PythonNode::loadLocal() void PythonNode::loadRemote() { - DEBTRACE( "---------------PyNode::loadRemote function---------------" ); - if(_container) - { - if(!_container->isAlreadyStarted(this)) - { - try - { - _container->start(this); - } - catch(Exception& e) - { - _errorDetails=e.what(); - throw e; - } - } - } - else - { - std::string what("PyNode::loadRemote : a load operation requested on \""); - what+=_name; what+="\" with no container specified."; - _errorDetails=what; - throw Exception(what); - } - - Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this); - - try - { - _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str()); - } - catch( const SALOME::SALOME_Exception& ex ) - { - std::string msg="Exception on remote python node creation "; - msg += '\n'; - msg += ex.details.text.in(); - _errorDetails=msg; - throw Exception(msg); - } - - PyGILState_STATE gstate = PyGILState_Ensure(); - const char picklizeScript[]="import cPickle\n" - "def pickleForDistPyth2009(kws):\n" - " return cPickle.dumps(((),kws),-1)\n" - "\n" - "def unPickleForDistPyth2009(st):\n" - " args=cPickle.loads(st)\n" - " return args\n"; - PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context); - if(res == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during load"); - } - Py_DECREF(res); - - _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009"); - _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009"); - if(_pyfuncSer == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during load"); - } - if(_pyfuncUnser == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during load"); - } - DEBTRACE( "---------------End PyNode::loadRemote function---------------" ); - PyGILState_Release(gstate); - + commonRemoteLoad(this); } void PythonNode::execute() @@ -235,47 +312,45 @@ void PythonNode::executeRemote() DEBTRACE( "++++++++++++++ PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" ); if(!_pyfuncSer) throw Exception("DistributedPythonNode badly loaded"); - PyGILState_STATE gstate = PyGILState_Ensure(); - - //=========================================================================== - // Get inputs in input ports, build a Python dict and pickle it - //=========================================================================== - PyObject* ob; - PyObject* args = PyDict_New(); - std::list::iterator iter2; - int pos=0; - for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2) - { - InputPyPort *p=(InputPyPort *)*iter2; - ob=p->getPyObj(); - PyDict_SetItemString(args,p->getName().c_str(),ob); - pos++; - } + Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs); + { + AutoGIL agil; + PyObject *args(0),*ob(0); + //=========================================================================== + // Get inputs in input ports, build a Python dict and pickle it + //=========================================================================== + args = PyDict_New(); + std::list::iterator iter2; + int pos(0); + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2) + { + InputPyPort *p=(InputPyPort *)*iter2; + ob=p->getPyObj(); + PyDict_SetItemString(args,p->getName().c_str(),ob); + pos++; + } #ifdef _DEVDEBUG_ - PyObject_Print(args,stderr,Py_PRINT_RAW); - std::cerr << endl; + PyObject_Print(args,stderr,Py_PRINT_RAW); + std::cerr << endl; #endif - PyObject *serializationInput=PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL); - //The pickled string may contain NULL characters so use PyString_AsStringAndSize - char* serializationInputC; - Py_ssize_t len; - if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len)) - { - PyGILState_Release(gstate); - throw Exception("DistributedPythonNode problem in python pickle"); - } - PyGILState_Release(gstate); - - Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs; - serializationInputCorba->length(len); - for(int i=0; i < len ; i++) - serializationInputCorba[i]=serializationInputC[i]; + PyObject *serializationInput(PyObject_CallFunctionObjArgs(_pyfuncSer,args,NULL)); + Py_DECREF(args); + //The pickled string may contain NULL characters so use PyString_AsStringAndSize + char *serializationInputC(0); + Py_ssize_t len; + if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len)) + throw Exception("DistributedPythonNode problem in python pickle"); + serializationInputCorba->length(len); + for(int i=0; i < len ; i++) + serializationInputCorba[i]=serializationInputC[i]; + Py_DECREF(serializationInput); + } //get the list of output argument names std::list::iterator iter; Engines::listofstring myseq; myseq.length(getNumberOfOutputPorts()); - pos=0; + int pos=0; for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter) { OutputPyPort *p=(OutputPyPort *)*iter; @@ -312,178 +387,171 @@ void PythonNode::executeRemote() for(int i=0;ilength();i++) resultCorbaC[i]=resultCorba[i]; - gstate = PyGILState_Ensure(); - - 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); - - if (finalResult == NULL) { - std::stringstream msg; - msg << "Conversion with pickle of output ports failed !"; - msg << " : " << __FILE__ << ":" << __LINE__; - PyGILState_Release(gstate); - _errorDetails=msg.str(); - throw YACS::ENGINE::ConversionException(msg.str()); - } + AutoGIL agil; + PyObject *args(0),*ob(0); + 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); + + if (finalResult == NULL) + { + std::stringstream msg; + msg << "Conversion with pickle of output ports failed !"; + msg << " : " << __FILE__ << ":" << __LINE__; + _errorDetails=msg.str(); + throw YACS::ENGINE::ConversionException(msg.str()); + } - DEBTRACE( "-----------------PythonNode::outputs-----------------" ); - int nres=1; - if(finalResult == Py_None) - nres=0; - else if(PyTuple_Check(finalResult)) - nres=PyTuple_Size(finalResult); + 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); - PyGILState_Release(gstate); - _errorDetails=msg; - throw Exception(msg); - } - - pos=0; - try - { - for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter) + if(getNumberOfOutputPorts() != nres) { - 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++; + std::string msg="Number of output arguments : Mismatch between definition and execution"; + Py_DECREF(finalResult); + _errorDetails=msg; + throw Exception(msg); } - Py_DECREF(finalResult); - } - catch(ConversionException& ex) - { - Py_DECREF(finalResult); - PyGILState_Release(gstate); - _errorDetails=ex.what(); - throw; - } - - PyGILState_Release(gstate); + pos=0; + 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 PyNode::executeRemote: " << getName() << " ++++++++++++++++++++" ); } void PythonNode::executeLocal() { DEBTRACE( "++++++++++++++ PyNode::executeLocal: " << getName() << " ++++++++++++++++++++" ); - PyGILState_STATE gstate = PyGILState_Ensure(); - - DEBTRACE( "---------------PyNode::inputs---------------" ); - list::iterator iter2; - for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) - { - InputPyPort *p=(InputPyPort *)*iter2; - DEBTRACE( "port name: " << p->getName() ); - DEBTRACE( "port kind: " << p->edGetType()->kind() ); - PyObject* ob=p->getPyObj(); - DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + { + AutoGIL agil; + + DEBTRACE( "---------------PyNode::inputs---------------" ); + list::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputPyPort *p=(InputPyPort *)*iter2; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + PyObject* ob=p->getPyObj(); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); #ifdef _DEVDEBUG_ - PyObject_Print(ob,stderr,Py_PRINT_RAW); - cerr << endl; + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; #endif - int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob); - DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt ); - } - - DEBTRACE( "---------------End PyNode::inputs---------------" ); - - //calculation - DEBTRACE( "----------------PyNode::calculation---------------" ); - DEBTRACE( _script ); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - - std::ostringstream stream; - stream << "/tmp/PythonNode_"; - stream << getpid(); - - PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input); - if(code == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - PyGILState_Release(gstate); - throw Exception("Error during execution"); - } - PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context); - - Py_DECREF(code); - Py_XDECREF(res); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - fflush(stdout); - fflush(stderr); - if(PyErr_Occurred ()) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - ofstream errorfile(stream.str().c_str()); - if (errorfile.is_open()) - { - errorfile << _script; - errorfile.close(); - } - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during execution"); - } - - DEBTRACE( "-----------------PyNode::outputs-----------------" ); - list::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() ); - PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str()); - if(ob==NULL){ - PyGILState_Release(gstate); - std::string msg="Error during execution: there is no variable "; - msg=msg+p->getName()+" in node context"; - _errorDetails=msg; - throw Exception(msg); + int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob); + DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt ); + } + + DEBTRACE( "---------------End PyNode::inputs---------------" ); + + //calculation + DEBTRACE( "----------------PyNode::calculation---------------" ); + DEBTRACE( _script ); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + + std::ostringstream stream; + stream << "/tmp/PythonNode_"; + stream << getpid(); + + PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input); + if(code == NULL) + { + _errorDetails=""; + PyObject* new_stderr = newPyStdOut(_errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during execution"); + } + PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context); + + Py_DECREF(code); + Py_XDECREF(res); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + fflush(stdout); + fflush(stderr); + if(PyErr_Occurred ()) + { + _errorDetails=""; + PyObject* new_stderr = newPyStdOut(_errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + ofstream errorfile(stream.str().c_str()); + if (errorfile.is_open()) + { + errorfile << _script; + errorfile.close(); } - DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt ); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during execution"); + } + + DEBTRACE( "-----------------PyNode::outputs-----------------" ); + list::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() ); + PyObject *ob=PyDict_GetItemString(_context,p->getName().c_str()); + if(ob==NULL) + { + std::string msg="Error during execution: there is no variable "; + msg=msg+p->getName()+" in node context"; + _errorDetails=msg; + throw Exception(msg); + } + DEBTRACE( "PyNode::outputs::ob refcnt: " << ob->ob_refcnt ); #ifdef _DEVDEBUG_ - PyObject_Print(ob,stderr,Py_PRINT_RAW); - cerr << endl; + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; #endif - p->put(ob); - } + p->put(ob); + } } - catch(ConversionException& ex) + catch(ConversionException& ex) { - PyGILState_Release(gstate); - _errorDetails=ex.what(); - throw; + _errorDetails=ex.what(); + throw; } - DEBTRACE( "-----------------End PyNode::outputs-----------------" ); - PyGILState_Release(gstate); + DEBTRACE( "-----------------End PyNode::outputs-----------------" ); + } DEBTRACE( "++++++++++++++ End PyNode::execute: " << getName() << " ++++++++++++++++++++" ); } @@ -525,6 +593,33 @@ Node *PythonNode::simpleClone(ComposedNode *father, bool editionOnly) const return new PythonNode(*this,father); } +void PythonNode::createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer) +{ + if(!CORBA::is_nil(_pynode)) + _pynode->UnRegister(); + _pynode=objContainer->createPyScriptNode(getName().c_str(),getScript().c_str()); +} + +Engines::PyNodeBase_var PythonNode::retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const +{ + Engines::PyScriptNode_var ret(objContainer->getDefaultPyScriptNode()); + if(!CORBA::is_nil(ret)) + { + ret->Register(); + } + return Engines::PyNodeBase::_narrow(ret); +} + +void PythonNode::assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp) +{ + _pynode=Engines::PyScriptNode::_narrow(remoteInterp); +} + +Engines::PyNodeBase_var PythonNode::getRemoteInterpreterHandle() +{ + return Engines::PyNodeBase::_narrow(_pynode); +} + //! Create a new node of same type with a given name PythonNode* PythonNode::cloneNode(const std::string& name) { @@ -552,18 +647,18 @@ PythonNode* PythonNode::cloneNode(const std::string& name) PyFuncNode::PyFuncNode(const PyFuncNode& other, ComposedNode *father):InlineFuncNode(other,father),_pyfunc(0) { _implementation = PythonNode::IMPL_NAME; - PyGILState_STATE gstate = PyGILState_Ensure(); - _context=PyDict_New(); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) - { - stringstream msg; - msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; - _errorDetails=msg.str(); - PyGILState_Release(gstate); - throw Exception(msg.str()); - } - PyGILState_Release(gstate); + { + AutoGIL agil; + _context=PyDict_New(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; + _errorDetails=msg.str(); + throw Exception(msg.str()); + } + } } PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0) @@ -571,28 +666,22 @@ PyFuncNode::PyFuncNode(const std::string& name): InlineFuncNode(name),_pyfunc(0) _implementation = PythonNode::IMPL_NAME; DEBTRACE( "PyFuncNode::PyFuncNode " << name ); - PyGILState_STATE gstate = PyGILState_Ensure(); - _context=PyDict_New(); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) - { - stringstream msg; - msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; - _errorDetails=msg.str(); - PyGILState_Release(gstate); - throw Exception(msg.str()); - } - PyGILState_Release(gstate); + { + AutoGIL agil; + _context=PyDict_New(); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Not possible to set builtins" << __FILE__ << ":" << __LINE__; + _errorDetails=msg.str(); + throw Exception(msg.str()); + } + } } PyFuncNode::~PyFuncNode() { - DEBTRACE( getName() ); - PyGILState_STATE gstate = PyGILState_Ensure(); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); - Py_DECREF(_context); - PyGILState_Release(gstate); if(!CORBA::is_nil(_pynode)) { _pynode->UnRegister(); @@ -603,24 +692,23 @@ void PyFuncNode::checkBasicConsistency() const throw(YACS::Exception) { DEBTRACE("checkBasicConsistency"); InlineFuncNode::checkBasicConsistency(); - - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject* res; - res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input); - if(res == NULL) - { - std::string error=""; - PyObject* new_stderr = newPyStdOut(error); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - PyGILState_Release(gstate); - throw Exception(error); - } - else - Py_XDECREF(res); - PyGILState_Release(gstate); + { + AutoGIL agil; + PyObject* res; + res=Py_CompileString(_script.c_str(),getName().c_str(),Py_file_input); + if(res == NULL) + { + std::string error=""; + PyObject* new_stderr = newPyStdOut(error); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception(error); + } + else + Py_XDECREF(res); + } } void PyFuncNode::load() @@ -634,95 +722,7 @@ void PyFuncNode::load() void PyFuncNode::loadRemote() { - DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" ); - if(_container) - { - if(!_container->isAlreadyStarted(this)) - { - try - { - _container->start(this); - } - catch(Exception& e) - { - _errorDetails=e.what(); - throw e; - } - } - } - else - { - std::string what("PyFuncNode::loadRemote : a load operation requested on \""); - what+=_name; what+="\" with no container specified."; - _errorDetails=what; - throw Exception(what); - } - - Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(this); - try - { - _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); - } - catch( const SALOME::SALOME_Exception& ex ) - { - std::string msg="Exception on remote python node creation "; - msg += '\n'; - msg += ex.details.text.in(); - _errorDetails=msg; - throw Exception(msg); - } - - PyGILState_STATE gstate = PyGILState_Ensure(); - const char picklizeScript[]="import cPickle\n" - "def pickleForDistPyth2009(*args,**kws):\n" - " return cPickle.dumps((args,kws),-1)\n" - "\n" - "def unPickleForDistPyth2009(st):\n" - " args=cPickle.loads(st)\n" - " return args\n"; - PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context); - if(res == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during load"); - } - Py_DECREF(res); - - _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009"); - _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009"); - if(_pyfuncSer == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during load"); - } - if(_pyfuncUnser == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during load"); - } - DEBTRACE( "---------------End PyfuncNode::loadRemote function---------------" ); - PyGILState_Release(gstate); + commonRemoteLoad(this); } void PyFuncNode::loadLocal() @@ -740,65 +740,61 @@ void PyFuncNode::loadLocal() } #endif - PyGILState_STATE gstate = PyGILState_Ensure(); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - - std::ostringstream stream; - stream << "/tmp/PythonNode_"; - stream << getpid(); - - PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input); - if(code == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - PyGILState_Release(gstate); - throw Exception("Error during execution"); - } - PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context); - Py_DECREF(code); - Py_XDECREF(res); - - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - if(PyErr_Occurred ()) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - ofstream errorfile(stream.str().c_str()); - if (errorfile.is_open()) - { - errorfile << _script; - errorfile.close(); - } - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); + { + AutoGIL agil; + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + + std::ostringstream stream; + stream << "/tmp/PythonNode_"; + stream << getpid(); + + PyObject* code=Py_CompileString(_script.c_str(), stream.str().c_str(), Py_file_input); + if(code == NULL) + { + _errorDetails=""; + PyObject* new_stderr = newPyStdOut(_errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during execution"); + } + PyObject *res = PyEval_EvalCode((PyCodeObject *)code, _context, _context); + Py_DECREF(code); + Py_XDECREF(res); - PyGILState_Release(gstate); - throw Exception("Error during execution"); - return; - } - _pyfunc=PyDict_GetItemString(_context,_fname.c_str()); - DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); - if(_pyfunc == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); - - PyGILState_Release(gstate); - throw Exception("Error during execution"); - } - DEBTRACE( "---------------End PyFuncNode::load function---------------" ); - PyGILState_Release(gstate); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if(PyErr_Occurred ()) + { + _errorDetails=""; + PyObject* new_stderr = newPyStdOut(_errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + ofstream errorfile(stream.str().c_str()); + if (errorfile.is_open()) + { + errorfile << _script; + errorfile.close(); + } + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during execution"); + return; + } + _pyfunc=PyDict_GetItemString(_context,_fname.c_str()); + DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + if(_pyfunc == NULL) + { + _errorDetails=""; + PyObject* new_stderr = newPyStdOut(_errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during execution"); + } + DEBTRACE( "---------------End PyFuncNode::load function---------------" ); + } } void PyFuncNode::execute() @@ -814,42 +810,39 @@ void PyFuncNode::executeRemote() DEBTRACE( "++++++++++++++ PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" ); if(!_pyfuncSer) throw Exception("DistributedPythonNode badly loaded"); - PyGILState_STATE gstate = PyGILState_Ensure(); - - //=========================================================================== - // Get inputs in input ports, build a Python tuple and pickle it - //=========================================================================== - PyObject* ob; - PyObject* args = PyTuple_New(getNumberOfInputPorts()); - std::list::iterator iter2; - int pos=0; - for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2) - { - InputPyPort *p=(InputPyPort *)*iter2; - ob=p->getPyObj(); - Py_INCREF(ob); - PyTuple_SetItem(args,pos,ob); - pos++; - } + Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);; + { + AutoGIL agil; + PyObject *ob(0); + //=========================================================================== + // Get inputs in input ports, build a Python tuple and pickle it + //=========================================================================== + PyObject *args(PyTuple_New(getNumberOfInputPorts())); + int pos(0); + for(std::list::iterator iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++,pos++) + { + InputPyPort *p=(InputPyPort *)*iter2; + ob=p->getPyObj(); + Py_INCREF(ob); + PyTuple_SetItem(args,pos,ob); + } #ifdef _DEVDEBUG_ - PyObject_Print(args,stderr,Py_PRINT_RAW); - std::cerr << endl; + 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 - char* serializationInputC; - Py_ssize_t len; - if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len)) - { - PyGILState_Release(gstate); - throw Exception("DistributedPythonNode problem in python pickle"); - } - PyGILState_Release(gstate); - - Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs; - serializationInputCorba->length(len); - for(int i=0; i < len ; i++) - serializationInputCorba[i]=serializationInputC[i]; + PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args); + Py_DECREF(args); + //The pickled string may contain NULL characters so use PyString_AsStringAndSize + char *serializationInputC(0); + Py_ssize_t len; + if (PyString_AsStringAndSize(serializationInput, &serializationInputC, &len)) + throw Exception("DistributedPythonNode problem in python pickle"); + + serializationInputCorba->length(len); + for(int i=0; i < len ; i++) + serializationInputCorba[i]=serializationInputC[i]; + Py_DECREF(serializationInput); + } //=========================================================================== // Execute in remote Python node @@ -877,60 +870,56 @@ void PyFuncNode::executeRemote() for(int i=0;ilength();i++) resultCorbaC[i]=resultCorba[i]; - gstate = PyGILState_Ensure(); - - 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); - PyGILState_Release(gstate); - _errorDetails=msg; - throw Exception(msg); - } - - pos=0; - std::list::iterator iter; - try - { - for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter) + { + AutoGIL agil; + + PyObject *resultPython(PyString_FromStringAndSize(resultCorbaC,resultCorba->length())); + delete [] resultCorbaC; + PyObject *args(PyTuple_New(1)),*ob(0); + 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) { - 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++; + std::string msg="Number of output arguments : Mismatch between definition and execution"; + Py_DECREF(finalResult); + _errorDetails=msg; + throw Exception(msg); } - Py_DECREF(finalResult); - } - catch(ConversionException& ex) - { - Py_DECREF(finalResult); - PyGILState_Release(gstate); - _errorDetails=ex.what(); - throw; - } - PyGILState_Release(gstate); + try + { + int pos(0); + for(std::list::iterator iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++, pos++) + { + 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); + } + Py_DECREF(finalResult); + } + catch(ConversionException& ex) + { + Py_DECREF(finalResult); + _errorDetails=ex.what(); + throw; + } + } DEBTRACE( "++++++++++++++ ENDOF PyFuncNode::executeRemote: " << getName() << " ++++++++++++++++++++" ); } @@ -942,117 +931,112 @@ void PyFuncNode::executeLocal() int pos=0; PyObject* ob; if(!_pyfunc)throw Exception("PyFuncNode badly loaded"); - PyGILState_STATE gstate = PyGILState_Ensure(); - - DEBTRACE( "---------------PyFuncNode::inputs---------------" ); - PyObject* args = PyTuple_New(getNumberOfInputPorts()) ; - list::iterator iter2; - for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) - { - InputPyPort *p=(InputPyPort *)*iter2; - DEBTRACE( "port name: " << p->getName() ); - DEBTRACE( "port kind: " << p->edGetType()->kind() ); - ob=p->getPyObj(); + { + AutoGIL agil; + DEBTRACE( "---------------PyFuncNode::inputs---------------" ); + PyObject* args = PyTuple_New(getNumberOfInputPorts()) ; + list::iterator iter2; + for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + { + InputPyPort *p=(InputPyPort *)*iter2; + DEBTRACE( "port name: " << p->getName() ); + DEBTRACE( "port kind: " << p->edGetType()->kind() ); + ob=p->getPyObj(); #ifdef _DEVDEBUG_ - PyObject_Print(ob,stderr,Py_PRINT_RAW); - cerr << endl; + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; #endif - DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); - Py_INCREF(ob); - PyTuple_SetItem(args,pos,ob); - DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); - pos++; - } - DEBTRACE( "---------------End PyFuncNode::inputs---------------" ); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + Py_INCREF(ob); + PyTuple_SetItem(args,pos,ob); + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + pos++; + } + DEBTRACE( "---------------End PyFuncNode::inputs---------------" ); - DEBTRACE( "----------------PyFuncNode::calculation---------------" ); + DEBTRACE( "----------------PyFuncNode::calculation---------------" ); #ifdef _DEVDEBUG_ - PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW); - cerr << endl; - PyObject_Print(args,stderr,Py_PRINT_RAW); - cerr << endl; + PyObject_Print(_pyfunc,stderr,Py_PRINT_RAW); + cerr << endl; + PyObject_Print(args,stderr,Py_PRINT_RAW); + cerr << endl; #endif - DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); - PyObject* result = PyObject_CallObject( _pyfunc , args ) ; - DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); - Py_DECREF(args); - fflush(stdout); - fflush(stderr); - if(result == NULL) - { - _errorDetails=""; - PyObject* new_stderr = newPyStdOut(_errorDetails); - PySys_SetObject((char*)"stderr", new_stderr); - std::ostringstream stream; - stream << "/tmp/PythonNode_"; - stream << getpid(); - ofstream errorfile(stream.str().c_str()); - if (errorfile.is_open()) + DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + PyObject* result = PyObject_CallObject( _pyfunc , args ) ; + DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + Py_DECREF(args); + fflush(stdout); + fflush(stderr); + if(result == NULL) { - errorfile << _script; - errorfile.close(); + _errorDetails=""; + PyObject* new_stderr = newPyStdOut(_errorDetails); + PySys_SetObject((char*)"stderr", new_stderr); + std::ostringstream stream; + stream << "/tmp/PythonNode_"; + stream << getpid(); + ofstream errorfile(stream.str().c_str()); + if (errorfile.is_open()) + { + errorfile << _script; + errorfile.close(); + } + PyErr_Print(); + PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); + Py_DECREF(new_stderr); + throw Exception("Error during execution"); } - PyErr_Print(); - PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__")); - Py_DECREF(new_stderr); + DEBTRACE( "----------------End PyFuncNode::calculation---------------" ); - PyGILState_Release(gstate); - throw Exception("Error during execution"); - } - DEBTRACE( "----------------End PyFuncNode::calculation---------------" ); - - DEBTRACE( "-----------------PyFuncNode::outputs-----------------" ); - int nres=1; - if(result == Py_None) - nres=0; - else if(PyTuple_Check(result)) - nres=PyTuple_Size(result); + DEBTRACE( "-----------------PyFuncNode::outputs-----------------" ); + int nres=1; + if(result == Py_None) + nres=0; + else if(PyTuple_Check(result)) + nres=PyTuple_Size(result); - if(getNumberOfOutputPorts() != nres) - { - std::string msg="Number of output arguments : Mismatch between definition and execution"; - Py_DECREF(result); - PyGILState_Release(gstate); - _errorDetails=msg; - throw Exception(msg); - } + if(getNumberOfOutputPorts() != nres) + { + std::string msg="Number of output arguments : Mismatch between definition and execution"; + Py_DECREF(result); + _errorDetails=msg; + throw Exception(msg); + } - pos=0; + pos=0; #ifdef _DEVDEBUG_ - PyObject_Print(result,stderr,Py_PRINT_RAW); - cerr << endl; + PyObject_Print(result,stderr,Py_PRINT_RAW); + cerr << endl; #endif - list::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(result))ob=PyTuple_GetItem(result,pos) ; - else ob=result; - DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); + list::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(result))ob=PyTuple_GetItem(result,pos) ; + else ob=result; + DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); #ifdef _DEVDEBUG_ - PyObject_Print(ob,stderr,Py_PRINT_RAW); - cerr << endl; + PyObject_Print(ob,stderr,Py_PRINT_RAW); + cerr << endl; #endif - p->put(ob); - pos++; - } - } - catch(ConversionException& ex) - { + p->put(ob); + pos++; + } + } + catch(ConversionException& ex) + { + Py_DECREF(result); + _errorDetails=ex.what(); + throw; + } + DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" ); Py_DECREF(result); - PyGILState_Release(gstate); - _errorDetails=ex.what(); - throw; - } - DEBTRACE( "-----------------End PyFuncNode::outputs-----------------" ); - - Py_DECREF(result); - PyGILState_Release(gstate); + } DEBTRACE( "++++++++++++++ End PyFuncNode::execute: " << getName() << " ++++++++++++++++++++" ); } @@ -1061,6 +1045,33 @@ Node *PyFuncNode::simpleClone(ComposedNode *father, bool editionOnly) const return new PyFuncNode(*this,father); } +void PyFuncNode::createRemoteAdaptedPyInterpretor(Engines::Container_ptr objContainer) +{ + if(!CORBA::is_nil(_pynode)) + _pynode->UnRegister(); + _pynode=objContainer->createPyNode(getName().c_str(),getScript().c_str()); +} + +Engines::PyNodeBase_var PyFuncNode::retrieveDftRemotePyInterpretorIfAny(Engines::Container_ptr objContainer) const +{ + Engines::PyNode_var ret(objContainer->getDefaultPyNode()); + if(!CORBA::is_nil(ret)) + { + ret->Register(); + } + return Engines::PyNodeBase::_narrow(ret); +} + +void PyFuncNode::assignRemotePyInterpretor(Engines::PyNodeBase_var remoteInterp) +{ + _pynode=Engines::PyNode::_narrow(remoteInterp); +} + +Engines::PyNodeBase_var PyFuncNode::getRemoteInterpreterHandle() +{ + return Engines::PyNodeBase::_narrow(_pynode); +} + //! Create a new node of same type with a given name PyFuncNode* PyFuncNode::cloneNode(const std::string& name) {