X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2FPythonNode.cxx;h=7973b2cf810f8a6134ff0a5eebe6c30821915d21;hb=fc862e1622f24ad78a1b544794f310de2b516929;hp=b82e20d70d4af39f0e1bfd64507fdd8718ff18d4;hpb=49d5f6f8af85a2d6398b05b9aa35552ffdfb74d4;p=modules%2Fyacs.git diff --git a/src/runtime/PythonNode.cxx b/src/runtime/PythonNode.cxx index b82e20d70..7973b2cf8 100644 --- a/src/runtime/PythonNode.cxx +++ b/src/runtime/PythonNode.cxx @@ -54,65 +54,63 @@ const char PythonNode::KIND[]="Python"; PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father) { _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(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(); + AutoGIL agil; DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); Py_DECREF(_context); - PyGILState_Release(gstate); } 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() @@ -133,9 +131,11 @@ void PythonNode::loadLocal() void PythonNode::loadRemote() { DEBTRACE( "---------------PyNode::loadRemote function---------------" ); + bool isContAlreadyStarted(false); if(_container) { - if(!_container->isAlreadyStarted(this)) + isContAlreadyStarted=_container->isAlreadyStarted(this); + if(!isContAlreadyStarted) { try { @@ -173,10 +173,24 @@ void PythonNode::loadRemote() throw Exception("Unrecognized type of container ! Salome one is expected for PythonNode !"); if(CORBA::is_nil(objContainer)) throw Exception("Container corba pointer is NULL for PythonNode !"); - + bool isInitializeRequested(false); try { - _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str()); + if(containerCast0 || !isContAlreadyStarted) + { + _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str()); + } + else + { + Engines::PyScriptNode_var dftPyScript(objContainer->getDefaultPyScriptNode()); + if(CORBA::is_nil(dftPyScript)) + { + isInitializeRequested=true; + _pynode = objContainer->createPyScriptNode(getName().c_str(),getScript().c_str()); + } + else + _pynode = dftPyScript; + } } catch( const SALOME::SALOME_Exception& ex ) { @@ -187,58 +201,73 @@ void PythonNode::loadRemote() 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); + if(CORBA::is_nil(_pynode)) + throw Exception("In PythonNode the ref in NULL ! "); - _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); + /// + { + AutoGIL agil; + 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); + 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); + 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); + 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(); + _errorDetails=msg; + throw Exception(msg); + } + } + DEBTRACE( "---------------End PyNode::loadRemote function---------------" ); + } } void PythonNode::execute() @@ -254,47 +283,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; @@ -331,178 +358,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); - DEBTRACE( "-----------------PythonNode::outputs-----------------" ); - int nres=1; - if(finalResult == Py_None) - nres=0; - else if(PyTuple_Check(finalResult)) - nres=PyTuple_Size(finalResult); + 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()); + } - 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); - } + DEBTRACE( "-----------------PythonNode::outputs-----------------" ); + int nres=1; + if(finalResult == Py_None) + nres=0; + else if(PyTuple_Check(finalResult)) + nres=PyTuple_Size(finalResult); - 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(); + { + 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 ); + 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 ); + int ier=PyDict_SetItemString(_context,p->getName().c_str(),ob); + DEBTRACE( "after PyDict_SetItemString:ob refcnt: " << ob->ob_refcnt ); + } - std::ostringstream stream; - stream << "/tmp/PythonNode_"; - stream << getpid(); + DEBTRACE( "---------------End PyNode::inputs---------------" ); - 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); + //calculation + DEBTRACE( "----------------PyNode::calculation---------------" ); + DEBTRACE( _script ); + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - 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); + std::ostringstream stream; + stream << "/tmp/PythonNode_"; + stream << getpid(); - 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); + 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() << " ++++++++++++++++++++" ); } @@ -571,18 +591,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) @@ -590,28 +610,29 @@ 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); + { + AutoGIL agil; + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + if(_pyfunc)DEBTRACE( "_pyfunc refcnt: " << _pyfunc->ob_refcnt ); + Py_DECREF(_context); + } if(!CORBA::is_nil(_pynode)) { _pynode->UnRegister(); @@ -622,24 +643,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() @@ -654,9 +674,11 @@ void PyFuncNode::load() void PyFuncNode::loadRemote() { DEBTRACE( "---------------PyfuncNode::loadRemote function---------------" ); + bool isContAlreadyStarted(false); if(_container) { - if(!_container->isAlreadyStarted(this)) + isContAlreadyStarted=_container->isAlreadyStarted(this); + if(!isContAlreadyStarted) { try { @@ -696,7 +718,18 @@ void PyFuncNode::loadRemote() try { - _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); + if(containerCast0 || !isContAlreadyStarted) + { + _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); + } + else + { + Engines::PyNode_var dftPyScript(objContainer->getDefaultPyNode()); + if(CORBA::is_nil(dftPyScript)) + _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); + else + _pynode = dftPyScript; + } } catch( const SALOME::SALOME_Exception& ex ) { @@ -707,6 +740,9 @@ void PyFuncNode::loadRemote() throw Exception(msg); } + if(CORBA::is_nil(_pynode)) + throw Exception("In PyFuncNode the ref in NULL ! "); + { AutoGIL agil; const char picklizeScript[]="import cPickle\n" @@ -770,65 +806,61 @@ void PyFuncNode::loadLocal() } #endif - PyGILState_STATE gstate = PyGILState_Ensure(); - DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); + { + AutoGIL agil; + DEBTRACE( "_context refcnt: " << _context->ob_refcnt ); - std::ostringstream stream; - stream << "/tmp/PythonNode_"; - stream << getpid(); + 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); + 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() @@ -844,40 +876,39 @@ 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); + Engines::pickledArgs_var serializationInputCorba(new Engines::pickledArgs);; { AutoGIL agil; - + PyObject *ob(0); //=========================================================================== // Get inputs in input ports, build a Python tuple and pickle it //=========================================================================== - args = PyTuple_New(getNumberOfInputPorts()); - std::list::iterator iter2; - for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); ++iter2) + 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); - pos++; } #ifdef _DEVDEBUG_ PyObject_Print(args,stderr,Py_PRINT_RAW); std::cerr << endl; #endif 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"); - } - Engines::pickledArgs_var serializationInputCorba=new Engines::pickledArgs; - serializationInputCorba->length(len); - for(int i=0; i < len ; i++) - serializationInputCorba[i]=serializationInputC[i]; + serializationInputCorba->length(len); + for(int i=0; i < len ; i++) + serializationInputCorba[i]=serializationInputC[i]; + Py_DECREF(serializationInput); + } //=========================================================================== // Execute in remote Python node @@ -908,9 +939,9 @@ void PyFuncNode::executeRemote() { AutoGIL agil; - PyObject* resultPython=PyString_FromStringAndSize(resultCorbaC,resultCorba->length()); + PyObject *resultPython(PyString_FromStringAndSize(resultCorbaC,resultCorba->length())); delete [] resultCorbaC; - args = PyTuple_New(1); + PyObject *args(PyTuple_New(1)),*ob(0); PyTuple_SetItem(args,0,resultPython); PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args); Py_DECREF(args); @@ -930,11 +961,10 @@ void PyFuncNode::executeRemote() throw Exception(msg); } - pos=0; - std::list::iterator iter; try { - for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); ++iter) + int pos(0); + for(std::list::iterator iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++, pos++) { OutputPyPort *p=(OutputPyPort *)*iter; DEBTRACE( "port name: " << p->getName() ); @@ -946,7 +976,6 @@ void PyFuncNode::executeRemote() ob=finalResult; DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); p->put(ob); - pos++; } Py_DECREF(finalResult); } @@ -968,117 +997,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() << " ++++++++++++++++++++" ); }