X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2FDistributedPythonNode.cxx;h=6696f3a2b23d5417901cf420d2a4470c293d13ba;hb=22868d035fb80bab64e0231d8dfffdf7afc240c3;hp=7150a6bd98d728b4b32fd3d230ec54525bbb7926;hpb=b797825313f7af9fd691d137c7c6df4950e7de2c;p=modules%2Fyacs.git diff --git a/src/runtime/DistributedPythonNode.cxx b/src/runtime/DistributedPythonNode.cxx old mode 100755 new mode 100644 index 7150a6bd9..6696f3a2b --- a/src/runtime/DistributedPythonNode.cxx +++ b/src/runtime/DistributedPythonNode.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2006-2014 CEA/DEN, EDF R&D +// Copyright (C) 2006-2023 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -21,6 +21,9 @@ #include "RuntimeSALOME.hxx" #include "SalomeContainer.hxx" #include "PythonNode.hxx" +#include "SalomeHPContainer.hxx" +#include "SalomeContainerTmpForHP.hxx" +#include "PythonCppUtils.hxx" #include "PythonPorts.hxx" #include "YacsTrace.hxx" @@ -50,168 +53,216 @@ DistributedPythonNode::DistributedPythonNode(const DistributedPythonNode& other, DistributedPythonNode::~DistributedPythonNode() { - PyGILState_STATE gstate = PyGILState_Ensure(); + AutoGIL agil; Py_DECREF(_context); - PyGILState_Release(gstate); } void DistributedPythonNode::load() { + bool isContAlreadyStarted(false); + if(_container) + isContAlreadyStarted=_container->isAlreadyStarted(this); ServerNode::load(); - PyGILState_STATE gstate = PyGILState_Ensure(); - if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + AutoGIL agil; + if( PyDict_SetItemString( _context, "__builtins__", getSALOMERuntime()->getBuiltins() )) + { + stringstream msg; + msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; + _errorDetails=msg.str(); + throw Exception(msg.str()); + } + const char picklizeScript[]="import pickle\ndef pickleForDistPyth2009(*args,**kws):\n return pickle.dumps((args,kws),-1)\n\ndef unPickleForDistPyth2009(st):\n args=pickle.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 execution"); + return; + } + 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 execution"); + } + 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 execution"); + } + + 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(this); + else if(containerCast1) + { + YACS::BASES::AutoCppPtr tmpCont(SalomeContainerTmpForHP::BuildFrom(containerCast1,this)); + objContainer=tmpCont->getContainerPtr(this); + } + else + throw Exception("Unrecognized type of container ! Salome one is expected !"); + if(CORBA::is_nil(objContainer)) + throw Exception("Container corba pointer is NULL !"); + + try { - stringstream msg; - msg << "Impossible to set builtins" << __FILE__ << ":" << __LINE__; - PyGILState_Release(gstate); - _errorDetails=msg.str(); - throw Exception(msg.str()); + if(containerCast0 || !isContAlreadyStarted) + { + _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); + } + else + { + Engines::PyNode_var dftPyScript(objContainer->getDefaultPyNode(getName().c_str())); + if(CORBA::is_nil(dftPyScript)) + _pynode = objContainer->createPyNode(getName().c_str(),getScript().c_str()); + else + _pynode = dftPyScript; + } } - const char picklizeScript[]="import cPickle\ndef pickleForDistPyth2009(*args,**kws):\n return cPickle.dumps((args,kws),-1)\n\ndef unPickleForDistPyth2009(st):\n args=cPickle.loads(st)\n return args\n"; - PyObject *res=PyRun_String(picklizeScript,Py_file_input,_context,_context); - if(res == NULL) + catch( const SALOME::SALOME_Exception& ex ) { - _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"); - return; + std::string msg="Exception on remote python node creation "; + msg += '\n'; + msg += ex.details.text.in(); + _errorDetails=msg; + throw Exception(msg); } - 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 execution"); - } - 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); + if(CORBA::is_nil(_pynode)) + throw Exception("In DistributedPythonNode the ref in NULL ! "); - PyGILState_Release(gstate); - throw Exception("Error during execution"); - } - DEBTRACE( "---------------End PyfuncSerNode::load function---------------" ); - PyGILState_Release(gstate); + + DEBTRACE( "---------------End PyfuncSerNode::load function---------------" ); + } } void DistributedPythonNode::execute() { YACSTRACE(1,"+++++++++++++++++ DistributedPythonNode::execute: " << getName() << " " << getFname() << " +++++++++++++++++" ); + ////// + PyObject* ob; + if(!_pyfuncSer) + throw Exception("DistributedPythonNode badly loaded"); + Engines::pickledArgs *serializationInputCorba(0); + PyObject *args(0); { - Engines::Container_var objContainer=((SalomeContainer*)_container)->getContainerPtr(0); - Engines::PyNode_var pn=objContainer->createPyNode(getName().c_str(),getScript().c_str()); - ////// - int pos=0; - PyObject* ob; - if(!_pyfuncSer) - throw Exception("DistributedPythonNode badly loaded"); - PyGILState_STATE gstate = PyGILState_Ensure(); - + AutoGIL agil; + DEBTRACE( "---------------DistributedPythonNode::inputs---------------" ); - PyObject* args = PyTuple_New(getNumberOfInputPorts()) ; - list::iterator iter2; - for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++) + args = PyTuple_New(getNumberOfInputPorts()) ; + int pos=0; + for(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++; } PyObject *serializationInput=PyObject_CallObject(_pyfuncSer,args); - std::string serializationInputC=PyString_AsString(serializationInput); - Engines::pickledArgs *serializationInputCorba=new Engines::pickledArgs; - int len=serializationInputC.length(); - serializationInputCorba->length(serializationInputC.length()); - for(int i=0;ilength(len+1); + for(int i=0;iexecute(getFname().c_str(),*serializationInputCorba); - } - catch(...) - { - std::string msg="Exception on remote python invocation"; - PyGILState_Release(gstate); - _errorDetails=msg; - throw Exception(msg); - } - DEBTRACE( "-----------------DistributedPythonNode end of remote python invocation-----------------" ); - // - delete serializationInputCorba; - char *resultCorbaC=new char[resultCorba->length()+1]; - resultCorbaC[resultCorba->length()]='\0'; - for(int i=0;ilength();i++) - resultCorbaC[i]=(*resultCorba)[i]; - delete resultCorba; + Py_DECREF(serializationInput); + } + //serializationInputCorba[serializationInputC.length()]='\0'; + DEBTRACE( "-----------------DistributedPythonNode starting remote python invocation-----------------" ); + Engines::pickledArgs *resultCorba; + try + { + resultCorba=_pynode->execute(getFname().c_str(),*serializationInputCorba); + } + catch(...) + { + std::string msg="Exception on remote python invocation"; + _errorDetails=msg; + throw Exception(msg); + } + DEBTRACE( "-----------------DistributedPythonNode end of remote python invocation-----------------" ); + // + delete serializationInputCorba; + char *resultCorbaC=new char[resultCorba->length()+1]; + resultCorbaC[resultCorba->length()]='\0'; + for(int i=0;ilength();i++) + resultCorbaC[i]=(*resultCorba)[i]; + int lenResCorba=resultCorba->length(); + delete resultCorba; + { + AutoGIL agil; args = PyTuple_New(1); - PyObject* resultPython=PyString_FromString(resultCorbaC); + //PyObject* resultPython=PyBytes_FromString(resultCorbaC); + PyObject* resultPython=PyBytes_FromStringAndSize(resultCorbaC,lenResCorba); delete [] resultCorbaC; PyTuple_SetItem(args,0,resultPython); PyObject *finalResult=PyObject_CallObject(_pyfuncUnser,args); DEBTRACE( "-----------------DistributedPythonNode::outputs-----------------" ); + 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()); + } 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; - list::iterator iter; try - { - for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++) + { + int pos(0); + for(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 kind: " << p->typeName() ); 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++; } - } + } catch(ConversionException& ex) - { + { Py_DECREF(finalResult); - PyGILState_Release(gstate); _errorDetails=ex.what(); throw; - } - PyGILState_Release(gstate); + } } DEBTRACE( "++++++++++++++ End DistributedPythonNode::execute: " << getName() << " ++++++++++++++++++++" ); } @@ -237,9 +288,8 @@ ServerNode *DistributedPythonNode::createNode(const std::string& name) const void DistributedPythonNode::initMySelf() { _implementation = DistributedPythonNode::IMPL_NAME; - PyGILState_STATE gstate=PyGILState_Ensure(); + AutoGIL agil; _context=PyDict_New(); - PyGILState_Release(gstate); } void DistributedPythonNode::dealException(CORBA::Exception *exc, const char *method, const char *ref)