Salome HOME
[EDF27816] Management of double foreach and management of proxyfile lifecycle
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 12 Jun 2023 12:15:52 +0000 (14:15 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 22 Aug 2023 09:42:41 +0000 (11:42 +0200)
src/runtime/PythonNode.cxx
src/runtime/PythonNode.hxx
src/runtime/PythonPorts.cxx
src/runtime/TypeConversions.cxx

index d124da6a3cb3d6bdd88c7fa0d9a5ab1e57535638..ec172ff4ba0e885da7e2ad193a194b4d1ba0b1c5 100644 (file)
@@ -328,6 +328,13 @@ bool PythonEntry::hasImposedResource()const
   return !_imposedResource.empty() && !_imposedContainer.empty();
 }
 
+bool PythonEntry::IsProxy( PyObject *ob )
+{
+  if(!_pyClsBigObject)
+    return false;
+  return PyObject_IsInstance( ob, _pyClsBigObject) == 1;
+}
+
 bool PythonEntry::GetDestroyStatus( PyObject *ob )
 {
   if(!_pyClsBigObject)
@@ -718,7 +725,7 @@ void PythonNode::executeLocal()
   DEBTRACE( "++++++++++++++ PyNode::executeLocal: " << getName() << " ++++++++++++++++++++" );
   {
     AutoGIL agil;
-    std::ostringstream unpxy; unpxy << "from SALOME_PyNode import UnProxyObjectSimple" << std::endl;
+    std::ostringstream unpxy; unpxy << "from SALOME_PyNode import UnProxyObjectSimpleLocal" << std::endl;
     DEBTRACE( "---------------PyNode::inputs---------------" );
     list<InputPort *>::iterator iter2;
     for(iter2 = _setOfInputPort.begin(); iter2 != _setOfInputPort.end(); iter2++)
@@ -727,8 +734,8 @@ void PythonNode::executeLocal()
         DEBTRACE( "port name: " << p->getName() );
         DEBTRACE( "port kind: " << p->edGetType()->kind() );
         PyObject* ob=p->getPyObj();
-        DEBTRACE( "ob refcnt: " << ob->ob_refcnt );
-        unpxy << p->getName() << " = UnProxyObjectSimple( " << p->getName() << " )" << std::endl;
+        DEBTRACE( "ob refcnt: " << ob->ob_refcnt ); 
+        unpxy << p->getName() << " = UnProxyObjectSimpleLocal( " << p->getName() << " )" << std::endl;
 #ifdef _DEVDEBUG_
         PyObject_Print(ob,stderr,Py_PRINT_RAW);
         cerr << endl;
index 7749f65498495567abedb1ea13a6215d7830befe..d83997cde3a257b07385da8baf77f41665dfa524 100644 (file)
@@ -35,10 +35,12 @@ namespace YACS
     class YACSRUNTIMESALOME_EXPORT PythonEntry
     {
     public:
+      static bool IsProxy( PyObject *ob );
       /*! 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 );
+      static void IfProxyDoSomething( PyObject *ob, const char *meth );
     protected:
       PythonEntry();
       ~PythonEntry();
@@ -56,7 +58,6 @@ 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;
index e4af89859e5ea3fd0b1cab6189195bab5363cda8..f1e8a1232ca0ce6e54d8ff28999aed9863416f4b 100644 (file)
@@ -32,7 +32,7 @@
 using namespace YACS::ENGINE;
 using namespace std;
 
-void releasePyObj(PyObject* data)
+static void RegisterReleasePyObj(PyObject* data, const char *method1)
 {
   if(!data)
     return ;
@@ -44,7 +44,7 @@ void releasePyObj(PyObject* data)
         {
           if(PyLong_AS_LONG(result))
             {
-              PyObject* o=PyObject_CallMethod(data, (char*)"Destroy", (char*)"");
+              PyObject* o=PyObject_CallMethod(data, (char*)method1, (char*)"");
               if(o)
                 Py_XDECREF( o);
               else
@@ -71,40 +71,14 @@ void releasePyObj(PyObject* data)
     }
 }
 
+void releasePyObj(PyObject* data)
+{
+  RegisterReleasePyObj(data,"Destroy");
+}
+
 void registerPyObj(PyObject* data)
 {
-  if (PyObject_HasAttrString(data, (char*)"_is_a"))
-    {
-      PyObject *result = PyObject_CallMethod(data, (char*)"_is_a", (char*)"s",(char*)"IDL:SALOME/GenericObj:1.0");
-      if(result && PyLong_Check(result))
-        {
-          if(PyLong_AS_LONG(result))
-            {
-              PyObject* o= PyObject_CallMethod(data, (char*)"Register", (char*)"") ;
-              if(o)
-                Py_XDECREF( o);
-              else
-                {
-#ifdef _DEVDEBUG_
-                  PyErr_Print();
-#else
-                  PyErr_Clear();
-#endif
-                  throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");      
-                }
-            }
-          Py_XDECREF(result); 
-        }
-      if(!result)
-        {
-#ifdef _DEVDEBUG_
-          PyErr_Print();
-#else
-          PyErr_Clear();
-#endif
-          throw ConversionException("Corba object does not exist: you have perhaps forgotten to call Register on a GenericObj");      
-        }
-    }
+  RegisterReleasePyObj(data,"Register");
 }
 
 InputPyPort::InputPyPort(const std::string& name, Node *node, TypeCode * type)
index 87524ed74d78507e3eb6922b572b7e6f614e25e0..1d194dfdc91d6b3ce87e7a495270b215a42b7507 100644 (file)
@@ -791,7 +791,10 @@ namespace YACS
               PyObject* mod=PyImport_ImportModule("pickle");
               PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
               if( somthingToDo )
+              {
                 YACS::ENGINE::PythonEntry::UnlinkOnDestructorIfProxy(o);
+                YACS::ENGINE::PythonEntry::IfProxyDoSomething(o,"incrRef");
+              }
               DEBTRACE(PyObject_Repr(pickled) );
               Py_DECREF(mod);
               if(pickled==NULL)
@@ -863,6 +866,12 @@ namespace YACS
           for(int i=0;i<length;i++)
             {
               PyObject *item=PySequence_ITEM(o,i);
+              bool somthingToDo = YACS::ENGINE::PythonEntry::IsProxy(item);
+              if( somthingToDo )
+              {
+                YACS::ENGINE::PythonEntry::UnlinkOnDestructorIfProxy(item);
+                YACS::ENGINE::PythonEntry::IfProxyDoSomething(item,"incrRef");
+              }
 #ifdef _DEVDEBUG_
               std::cerr <<"item[" << i << "]=";
               PyObject_Print(item,stderr,Py_PRINT_RAW);
@@ -988,6 +997,12 @@ namespace YACS
               PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
               DEBTRACE(PyObject_Repr(ob));
               Py_DECREF(mod);
+              bool somthingToDo = YACS::ENGINE::PythonEntry::IsProxy(ob);
+              if( somthingToDo )
+              {
+                // no incrRef here because the incrRef has been done before dumps that construct o.
+                YACS::ENGINE::PythonEntry::UnlinkOnDestructorIfProxy(ob);
+              }
               if(ob==NULL)
                 {
                   PyErr_Print();