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.
{
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();
+ }
}
}
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);
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);
}
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:
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[];
};
void TransactionMultiKeyAddSession::perform()
{
- _dsct->moveStatusOfVarFromRdExtInitToRdExt(_var_name);
+ _dsct->moveStatusOfVarFromRdExtOrRdExtInitToRdExt(_var_name);
}
/*!
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: