]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
Fix bug of concurrency between consumer/producer. Rare occurence.
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 30 Oct 2015 09:32:43 +0000 (10:32 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 30 Oct 2015 09:32:43 +0000 (10:32 +0100)
The case that raised bug.
0 - Consumer does t=dss.waitForKeyInVar(...).
1 - Producer push all the values and finish and call dss.moveRdExtInitToRdExt.
2 - Consumer does t.waitFor() -> Crash var has been destroyed by 1.

src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx
src/SALOMESDS/SALOMESDS_Transaction.cxx
src/SALOMESDS/SALOMESDS_Transaction.hxx

index 409fdf623b67b4e845d19854020fb6f562c5cd36..4467adffa4dc8995a877e066e46601e079e2007c 100644 (file)
@@ -374,29 +374,35 @@ void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const s
     {
       PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
       PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
+      newVar->incrNbClients();
       CORBA::Object_var obj(newVar->activate());
       SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
       p.first=obj2; p.second=newVar;
       varc0->decrRef();
     }
+  else
+    varc1->incrNbClients();
 }
 
-void DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName)
+void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName)
 {
   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
   std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
   PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
   PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
   if(!varc0 && !varc1)
-    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt : var is not a RdExtInit !");
+    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
   if(varc0)
     {
-      PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
-      PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
-      CORBA::Object_var obj(newVar->activate());
-      SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
-      p.first=obj2; p.second=newVar;
-      varc0->decrRef();
+      if(varc0->decrNbClients())
+        {
+          PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
+          PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
+          CORBA::Object_var obj(newVar->activate());
+          SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
+          p.first=obj2; p.second=newVar;
+          varc0->decrRef();
+        }
     }
 }
 
index eafc2900aa01b0b015f0a009f9f596bb6e034682..7b5b67f7dbe4acee1560feeaac6ffc41e6e74921 100644 (file)
@@ -86,7 +86,7 @@ namespace SALOMESDS
     void moveStatusOfVarFromRdWrToRdOnly(const std::string& varName);
     void moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName);
     void moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName);
-    void moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName);
+    void moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName);
   protected:
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const;
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator retrieveVarInternal4(const std::string& varName);
index d345fd15aa06e6016cb585df1ab1311c15d0f0ae..37bf2fd2900ba45176a079112cc8aafb36f5d8e4 100644 (file)
@@ -29,13 +29,13 @@ using namespace SALOMESDS;
 
 const char PickelizedPyObjRdExtInitServer::ACCESS_REPR[]="RdExtInit";
 
-PickelizedPyObjRdExtInitServer::PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServerModifiable(father,varName,value)
+PickelizedPyObjRdExtInitServer::PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServerModifiable(father,varName,value),_nb_of_clients(0)
 {
   _self_deep_copy=DeepCopyPyObj(_self);
 }
 
 //! obj is consumed
-PickelizedPyObjRdExtInitServer::PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj),_self_deep_copy(0)
+PickelizedPyObjRdExtInitServer::PickelizedPyObjRdExtInitServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj),_self_deep_copy(0),_nb_of_clients(0)
 {
   _self_deep_copy=DeepCopyPyObj(obj);
 }
index 25f94d6f783999a06115d2b1df9152a11282f07b..d8eb1c7b84110aa5e796ccb3997501f01c720679 100644 (file)
@@ -30,6 +30,9 @@
 
 namespace SALOMESDS
 {
+  /*!
+   * State during the producer/consumer phase. Activated by TransactionMultiKeyAddSession transaction returned by dss.addMultiKeyValueSession.
+   */
   class PickelizedPyObjRdExtInitServer : public PickelizedPyObjServerModifiable, public virtual POA_SALOME::PickelizedPyObjRdExtInitServer
   {
   public:
@@ -39,10 +42,15 @@ namespace SALOMESDS
   public:
     std::string getAccessStr() const;
     SALOME::ByteVec *fetchSerializedContent();
+  public:
+    void incrNbClients() const { _nb_of_clients++; }
+    bool decrNbClients() const { _nb_of_clients--; return _nb_of_clients<=0; }
   private:
     static PyObject *DeepCopyPyObj(PyObject *pyobj);
   private:
     PyObject *_self_deep_copy;
+    //! this attribute stores number of clients in RdExtInit/RdExt
+    mutable int _nb_of_clients;
   public:
     static const char ACCESS_REPR[];
   };
index 445623f8c9d5f48d7f88ab513a19aa4fb46fe1c4..79eab952f8dc312806de7ba0708ce237cd59094c 100644 (file)
@@ -294,7 +294,7 @@ void TransactionMultiKeyAddSession::prepareRollBackInCaseOfFailure()
 
 void TransactionMultiKeyAddSession::perform()
 {
-  _dsct->moveStatusOfVarFromRdExtInitToRdExt(_var_name);
+  _dsct->moveStatusOfVarFromRdExtOrRdExtInitToRdExt(_var_name);
 }
 
 /*!
index bc94d9f78b346db4cd0ee9345396a22eebd10104..e9b97aad14fa935c4ac2714026b1a9bc73c144a3 100644 (file)
@@ -171,6 +171,9 @@ namespace SALOMESDS
     void notify();
   };
 
+  /*!
+   * This transaction switch from RdExt to RdExtInit in constructor and when perform called RdExtInit to RdExt.
+   */
   class TransactionMultiKeyAddSession : public Transaction, public virtual POA_SALOME::TransactionMultiKeyAddSession
   {
   public: