From 4dae3b5416a884361d80462dc4d6ccb59a6f2503 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Tue, 6 Jun 2023 17:53:51 +0200 Subject: [PATCH] [EDF27816] : management of proxy from/to Foreach --- src/runtime/PythonNode.cxx | 55 ++++++++++++++++++++++++++++----- src/runtime/PythonNode.hxx | 8 ++++- src/runtime/TypeConversions.cxx | 6 ++++ 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/runtime/PythonNode.cxx b/src/runtime/PythonNode.cxx index 77cb39fc1..0b7b65e60 100644 --- a/src/runtime/PythonNode.cxx +++ b/src/runtime/PythonNode.cxx @@ -56,6 +56,8 @@ const char PythonEntry::SCRIPT_FOR_SIMPLE_SERIALIZATION[]="import pickle\n" " return pickle.dumps(val,-1)\n" "\n"; +PyObject *PythonEntry::_pyClsBigObject = nullptr; + const char PythonNode::IMPL_NAME[]="Python"; const char PythonNode::KIND[]="Python"; @@ -80,7 +82,7 @@ const char PyFuncNode::SCRIPT_FOR_SERIALIZATION[]="import pickle\n" " return args\n"; static char SCRIPT_FOR_BIGOBJECT[]="import SALOME_PyNode\n" - "BigObjectOnDisk = SALOME_PyNode.BigObjectOnDisk\n"; + "BigObjectOnDiskBase = SALOME_PyNode.BigObjectOnDiskBase\n"; // pickle.load concurrency issue : see https://bugs.python.org/issue12680 #if PY_VERSION_HEX < 0x03070000 @@ -219,7 +221,11 @@ void PythonEntry::loadRemoteContext(InlineNode *reqNode, Engines::Container_ptr _pyfuncSer=PyDict_GetItemString(_context,"pickleForDistPyth2009"); _pyfuncUnser=PyDict_GetItemString(_context,"unPickleForDistPyth2009"); _pyfuncSimpleSer=PyDict_GetItemString(_context,"pickleForVarSimplePyth2009"); - _pyClsBigObject=PyDict_GetItemString(_context,"BigObjectOnDisk"); + if(! _pyClsBigObject ) + { + _pyClsBigObject=PyDict_GetItemString(_context,"BigObjectOnDiskBase"); + Py_INCREF(_pyClsBigObject); + } if(_pyfuncSer == NULL) { std::string errorDetails; @@ -322,6 +328,44 @@ bool PythonEntry::hasImposedResource()const return !_imposedResource.empty() && !_imposedContainer.empty(); } +bool PythonEntry::GetDestroyStatus( PyObject *ob ) +{ + if(!_pyClsBigObject) + return false; + if( PyObject_IsInstance( ob, _pyClsBigObject) == 1 ) + { + AutoPyRef unlinkOnDestructor = PyObject_GetAttrString(ob,"getDestroyStatus"); + AutoPyRef tmp = PyObject_CallFunctionObjArgs(unlinkOnDestructor,nullptr); + if( PyBool_Check(tmp.get()) ) + { + return tmp.get() == Py_True; + } + return false; + } + return false; +} + +void PythonEntry::IfProxyDoSomething( PyObject *ob, const char *meth ) +{ + if(!_pyClsBigObject) + return ; + if( PyObject_IsInstance( ob, _pyClsBigObject) == 1 ) + { + AutoPyRef unlinkOnDestructor = PyObject_GetAttrString(ob,meth); + AutoPyRef tmp = PyObject_CallFunctionObjArgs(unlinkOnDestructor,nullptr); + } +} + +void PythonEntry::DoNotTouchFileIfProxy( PyObject *ob ) +{ + IfProxyDoSomething(ob,"doNotTouchFile"); +} + +void PythonEntry::UnlinkOnDestructorIfProxy( PyObject *ob ) +{ + IfProxyDoSomething(ob,"unlinkOnDestructor"); +} + PythonNode::PythonNode(const PythonNode& other, ComposedNode *father):InlineNode(other,father),_autoSqueeze(other._autoSqueeze) { _pynode = Engines::PyScriptNode::_nil(); @@ -605,12 +649,7 @@ void PythonNode::executeRemote() _errorDetails=msg.str(); throw YACS::ENGINE::ConversionException(msg.str()); } - - if( PyObject_IsInstance( ob, _pyClsBigObject) == 1 ) - { - AutoPyRef unlinkOnDestructor = PyObject_GetAttrString(ob,"unlinkOnDestructor"); - AutoPyRef tmp = PyObject_CallFunctionObjArgs(unlinkOnDestructor,nullptr); - } + UnlinkOnDestructorIfProxy(ob); p->put( ob ); } pos++; diff --git a/src/runtime/PythonNode.hxx b/src/runtime/PythonNode.hxx index abf6b3d86..1c83f7582 100644 --- a/src/runtime/PythonNode.hxx +++ b/src/runtime/PythonNode.hxx @@ -34,6 +34,11 @@ namespace YACS { class YACSRUNTIMESALOME_EXPORT PythonEntry { + public: + /*! return true only if ob is a proxy and destroy flag set to true*/ + static bool GetDestroyStatus( PyObject *ob ); + static void DoNotTouchFileIfProxy( PyObject *ob ); + static void UnlinkOnDestructorIfProxy( PyObject *ob ); protected: PythonEntry(); ~PythonEntry(); @@ -51,12 +56,13 @@ namespace YACS void loadRemoteContext(InlineNode *reqNode, Engines::Container_ptr objContainer, bool isInitializeRequested); static std::string GetContainerLog(const std::string& mode, Container *container, const Task *askingTask); virtual bool hasImposedResource()const; + static void IfProxyDoSomething( PyObject *ob, const char *meth ); protected: PyObject *_context; PyObject *_pyfuncSer; PyObject *_pyfuncUnser; PyObject *_pyfuncSimpleSer; - PyObject *_pyClsBigObject; + static PyObject *_pyClsBigObject; std::string _imposedResource; std::string _imposedContainer; public: diff --git a/src/runtime/TypeConversions.cxx b/src/runtime/TypeConversions.cxx index 1944e2f46..23701e50e 100644 --- a/src/runtime/TypeConversions.cxx +++ b/src/runtime/TypeConversions.cxx @@ -33,6 +33,7 @@ #include "TypeCode.hxx" #include "Cstr2d.hxx" #include "SALOME_GenericObj.hh" +#include "PythonNode.hxx" #include #include @@ -785,9 +786,14 @@ namespace YACS } if(strncmp(t->id(),"python",6)==0) { + bool somthingToDo = YACS::ENGINE::PythonEntry::GetDestroyStatus(o); + if( somthingToDo ) + YACS::ENGINE::PythonEntry::DoNotTouchFileIfProxy(o); // It's a native Python object pickle it PyObject* mod=PyImport_ImportModule("pickle"); PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol); + if( somthingToDo ) + YACS::ENGINE::PythonEntry::UnlinkOnDestructorIfProxy(o); DEBTRACE(PyObject_Repr(pickled) ); Py_DECREF(mod); if(pickled==NULL) -- 2.39.2