From: Anthony Geay Date: Fri, 30 Oct 2015 09:32:43 +0000 (+0100) Subject: Fix bug of concurrency between consumer/producer. Rare occurence. X-Git-Tag: V8_0_pre~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=07e511ee5814b1334473374cc70b9befb011529a;p=modules%2Fkernel.git Fix bug of concurrency between consumer/producer. Rare occurence. 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. --- diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index 409fdf623..4467adffa 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -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(p.second)); PickelizedPyObjRdExtServer *varc1(dynamic_cast(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(); + } } } diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx index eafc2900a..7b5b67f7d 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx @@ -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); diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx index d345fd15a..37bf2fd29 100644 --- a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx +++ b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.cxx @@ -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); } diff --git a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx index 25f94d6f7..d8eb1c7b8 100644 --- a/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx +++ b/src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtInitServer.hxx @@ -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[]; }; diff --git a/src/SALOMESDS/SALOMESDS_Transaction.cxx b/src/SALOMESDS/SALOMESDS_Transaction.cxx index 445623f8c..79eab952f 100644 --- a/src/SALOMESDS/SALOMESDS_Transaction.cxx +++ b/src/SALOMESDS/SALOMESDS_Transaction.cxx @@ -294,7 +294,7 @@ void TransactionMultiKeyAddSession::prepareRollBackInCaseOfFailure() void TransactionMultiKeyAddSession::perform() { - _dsct->moveStatusOfVarFromRdExtInitToRdExt(_var_name); + _dsct->moveStatusOfVarFromRdExtOrRdExtInitToRdExt(_var_name); } /*! diff --git a/src/SALOMESDS/SALOMESDS_Transaction.hxx b/src/SALOMESDS/SALOMESDS_Transaction.hxx index bc94d9f78..e9b97aad1 100644 --- a/src/SALOMESDS/SALOMESDS_Transaction.hxx +++ b/src/SALOMESDS/SALOMESDS_Transaction.hxx @@ -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: