Salome HOME
[EDF27816] : management of proxy from/to Foreach
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 6 Jun 2023 15:53:51 +0000 (17:53 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 6 Jun 2023 15:53:51 +0000 (17:53 +0200)
src/runtime/PythonNode.cxx
src/runtime/PythonNode.hxx
src/runtime/TypeConversions.cxx

index 77cb39fc1efa5dde6feba3878e573f785fb4108a..0b7b65e60a64c075441d41dbd1c52f8e721085c8 100644 (file)
@@ -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++;
index abf6b3d86edc9065d092e66aa03a96e6bcbe44ae..1c83f75820675c939acc526cbfccb75a54758305 100644 (file)
@@ -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:
index 1944e2f46eb72337cf3b77d27adc13d866c8acfc..23701e50eb7c7a7e8352d3c1968d178071f8593a 100644 (file)
@@ -33,6 +33,7 @@
 #include "TypeCode.hxx"
 #include "Cstr2d.hxx"
 #include "SALOME_GenericObj.hh"
+#include "PythonNode.hxx"
 
 #include <iostream>
 #include <iomanip>
@@ -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)