Salome HOME
Implementation of working glob var. Remove memory leak on TestSalomeSDS.py.
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 4 Aug 2015 16:12:23 +0000 (18:12 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 4 Aug 2015 16:12:23 +0000 (18:12 +0200)
20 files changed:
idl/SALOME_SDS.idl
src/SALOMESDS/SALOMESDS_BasicDataServer.cxx
src/SALOMESDS/SALOMESDS_BasicDataServer.hxx
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_DataServerManager.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtServer.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdExtServer.hxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdOnlyServer.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdOnlyServer.hxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdWrServer.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjRdWrServer.hxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.cxx
src/SALOMESDS/SALOMESDS_PickelizedPyObjServer.hxx
src/SALOMESDS/SALOMESDS_RefCountServ.hxx
src/SALOMESDS/SALOMESDS_Transaction.cxx
src/SALOMESDS/SALOMESDS_Transaction.hxx
src/SALOMESDS/SALOME_DataScopeServer.cxx
src/SALOMESDS/SalomeSDSClt.py
src/SALOMESDS/TestSalomeSDS.py

index b3ceaa9585be96d981af434dc77c9532c8d4a413..ed8b9a39d15945f8d9196765b94b3110cdc01a6a 100644 (file)
@@ -34,6 +34,7 @@ module SALOME
     DataScopeServer getMyDataScopeServer();
     string getVarName();
     string getScopeName();
+    long getRCValue();
   };
 
   interface PickelizedPyObjServer : BasicDataServer
@@ -58,6 +59,11 @@ module SALOME
 
   interface DataServerManager;
 
+  interface DataScopeKiller
+  {
+    void shutdown();
+  };
+
   interface DataScopeServerBase
   {
     void ping();
@@ -65,7 +71,7 @@ module SALOME
     StringVec listVars();
     boolean existVar(in string varName) raises (SALOME::SALOME_Exception);
     void deleteVar(in string varName) raises (SALOME::SALOME_Exception);
-    void shutdownIfNotHostedByDSM();
+    boolean shutdownIfNotHostedByDSM(out DataScopeKiller killer) raises (SALOME::SALOME_Exception);
     ByteVec fetchSerializedContent(in string varName) raises (SALOME::SALOME_Exception);
     SeqOfByteVec getAllKeysOfVarWithTypeDict(in string varName) raises (SALOME::SALOME_Exception);
   };
@@ -75,13 +81,17 @@ module SALOME
     BasicDataServer retrieveVar(in string varName) raises (SALOME::SALOME_Exception);
     PickelizedPyObjRdOnlyServer createRdOnlyVar(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     PickelizedPyObjRdExtServer createRdExtVar(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
-    //PickelizedPyObjRdWrServer createRdWrVar(in string typeName, in string varName) raises (SALOME::SALOME_Exception);
   };
 
   interface Transaction
   {
   };
 
+  interface TransactionRdWrAccess : Transaction
+  {
+    PickelizedPyObjRdWrServer getVar() raises (SALOME::SALOME_Exception);
+  };
+
   typedef sequence<Transaction> ListOfTransaction;
 
   interface KeyWaiter
@@ -91,6 +101,7 @@ module SALOME
 
   interface DataScopeServerTransaction : DataScopeServerBase
   {
+    string getAccessOfVar(in string varName) raises (SALOME::SALOME_Exception);
     Transaction createRdOnlyVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction createRdExtVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction createRdWrVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
@@ -98,6 +109,7 @@ module SALOME
     Transaction addKeyValueInVarErrorIfAlreadyExisting(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     void addKeyValueInVarErrorIfAlreadyExistingNow(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     Transaction removeKeyInVarErrorIfNotAlreadyExisting(in string varName, in ByteVec keyValue) raises (SALOME::SALOME_Exception);
+    TransactionRdWrAccess createWorkingVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
     KeyWaiter waitForKeyInVar(in string varName, in ByteVec keyVal) raises (SALOME::SALOME_Exception);
     KeyWaiter waitForKeyInVarAndKillIt(in string varName, in ByteVec keyVal, out Transaction transac) raises (SALOME::SALOME_Exception);
     void atomicApply(in ListOfTransaction transactions) raises (SALOME::SALOME_Exception);
index e89fd16535226ed340ec55c5d8ae0b1e3b9a9bca..64fed000e7aafc3e37b63f44b45e37993a889e58 100644 (file)
@@ -75,6 +75,11 @@ void BasicDataServer::Destroy()
   enforcedRelease();
 }
 
+CORBA::Long BasicDataServer::getRCValue()
+{
+  return getCounter();
+}
+
 PortableServer::POA_var BasicDataServer::getPOA() const
 {
   return _father->getPOA();
index 7a22300efb9e2cfe4b4722706ddc194476b3c9e9..eace20393a38bdc96d9cc6767a9917ebe9627d44 100644 (file)
@@ -43,6 +43,7 @@ namespace SALOMESDS
     void Register();
     void UnRegister();
     void Destroy();
+    CORBA::Long getRCValue();
   public:
     DataScopeServerBase *getFather() const { return _father; }
     std::string getVarNameCpp() const { return _var_name; }
index 9dec327d6da837ba22c874b5ed2fbbce6c04578b..514956e24dcd7898b0a51636046b82be68570c40 100644 (file)
@@ -44,11 +44,17 @@ using namespace SALOMESDS;
 
 std::size_t DataScopeServerBase::COUNTER=0;
 
-DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName)
+void DataScopeKiller::shutdown()
 {
+  Py_Finalize();
+  _orb->shutdown(0);
 }
 
-DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars)
+DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
+{
+}
+
+DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
 {
 }
 
@@ -57,6 +63,14 @@ DataScopeServerBase::~DataScopeServerBase()
   // _globals is borrowed ref -> do nothing
   Py_XDECREF(_locals);
   Py_XDECREF(_pickler);
+  for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
+    {
+       BasicDataServer *obj((*it).second);
+       if(obj)
+         {
+           obj->decrRef();
+         }
+    }
 }
 
 /*!
@@ -126,17 +140,18 @@ void DataScopeServerBase::deleteVar(const char *varName)
     }
   std::size_t pos(std::distance(allNames.begin(),it));
   std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
-  (*it0).first->UnRegister();
+  for(std::size_t ii=0;ii<pos;ii++,it0++);
+  (*it0).second->decrRef();
   _vars.erase(it0);
 }
 
-void DataScopeServerBase::shutdownIfNotHostedByDSM()
+CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
 {
   SALOME_NamingService ns(_orb);
   CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
   SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
   if(CORBA::is_nil(dsm))
-    return ;
+    throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
   // destroy ref in the naming service
   std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
   ns.Destroy_Name(fullScopeName.c_str());
@@ -149,10 +164,17 @@ void DataScopeServerBase::shutdownIfNotHostedByDSM()
   catch(...) { ret=0; }
   //
   if(!ret)
-    _orb->shutdown(0);
+    {
+      enforcedRelease();
+      killer=SALOME::DataScopeKiller::_duplicate(_killer);
+      return true;
+    }
   else
     {
+      ret->_remove_ref();
       enforcedRelease();
+      killer=SALOME::DataScopeKiller::_duplicate(_killer);
+      return false;
     }
 }
 
@@ -307,13 +329,43 @@ PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::s
   return ret;
 }
 
+void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
+{
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
+  PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
+  if(!varc)
+    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
+  PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
+  PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
+  CORBA::Object_var obj(newVar->activate());
+  SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
+  p.first=obj2; p.second=newVar;
+  varc->decrRef();
+}
+
+void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
+{
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
+  PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
+  if(!varc)
+    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
+  PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
+  PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
+  CORBA::Object_var obj(newVar->activate());
+  SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
+  p.first=obj2; p.second=newVar;
+  varc->decrRef();
+}
+
 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
 {
   std::vector<std::string> allNames(getAllVarNames());
   std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
   if(it==allNames.end())
     {
-      std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal : name \"" << varName << "\" does not exists ! Possibilities are :";
+      std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
       std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
       throw Exception(oss.str());
     }
@@ -323,9 +375,25 @@ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_
   return it0;
 }
 
+std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
+{
+  std::vector<std::string> allNames(getAllVarNames());
+  std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
+  if(it==allNames.end())
+    {
+      std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
+      std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
+      throw Exception(oss.str());
+    }
+  std::size_t pos(std::distance(allNames.begin(),it));
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
+  for(std::size_t i=0;i<pos;i++,it0++);
+  return it0;
+}
+
 ///////
 
-DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName):DataScopeServerBase(orb,scopeName)
+DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
 {
 }
 
@@ -355,9 +423,6 @@ SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const cha
   return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
 }
 
-/*!
- * Called remotely -> to protect against throw
- */
 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
 {
   std::string varNameCpp(varName),typeNameCpp(typeName);
@@ -375,7 +440,7 @@ DataScopeServer::~DataScopeServer()
 
 ////////
 
-DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, const std::string& scopeName):DataScopeServerBase(orb,scopeName)
+DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
 {
   CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
   PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
@@ -395,6 +460,20 @@ DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTran
 {
 }
 
+char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
+{
+  std::string varNameCpp(varName);
+  checkExistingVar(varNameCpp);
+  BasicDataServer *var(retrieveVarInternal2(varName));
+  if(!var)
+    throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
+  PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
+  if(!varc)
+    throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
+  std::string ret(varc->getAccessStr());
+  return CORBA::string_dup(ret.c_str());
+}
+
 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
 {
   checkNotAlreadyExistingVar(varName);
@@ -569,6 +648,20 @@ SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlre
   return SALOME::Transaction::_narrow(obj);
 }
 
+SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+  std::string varNameCpp(varName);
+  checkNotAlreadyExistingVar(varName);
+  PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
+  CORBA::Object_var obj(tmp->activate());
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
+  _vars.push_back(p);
+  //
+  TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
+  CORBA::Object_var obj2(ret->activate());
+  return SALOME::TransactionRdWrAccess::_narrow(obj2);
+}
+
 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
 {
   PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
index ab7e810dc73eefd1935119903bdfaf521382eef4..608ae507ec47d5e57cc5f8594995ca1fe86e8224 100644 (file)
 
 namespace SALOMESDS
 {
+  class SALOMESDS_EXPORT DataScopeKiller : public POA_SALOME::DataScopeKiller
+  {
+  public:
+    DataScopeKiller(CORBA::ORB_ptr orb):_orb(CORBA::ORB::_duplicate(orb)) { }
+    void shutdown();
+  private:
+    CORBA::ORB_var _orb;
+  };
+  
   class KeyWaiter;
   class PickelizedPyObjServer;
 
   class SALOMESDS_EXPORT DataScopeServerBase : public virtual POA_SALOME::DataScopeServerBase, public POAHolder
   {
   public:
-    DataScopeServerBase(CORBA::ORB_ptr orb, const std::string& scopeName);
+    DataScopeServerBase(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
     DataScopeServerBase(const DataScopeServerBase& other);
     void ping();
     char *getScopeName();
     SALOME::StringVec *listVars();
     CORBA::Boolean existVar(const char *varName);
     SALOME::BasicDataServer_ptr retrieveVarInternal(const char *varName);
-    BasicDataServer *retrieveVarInternal2(const std::string& varName);
     void deleteVar(const char *varName);
-    void shutdownIfNotHostedByDSM();
+    CORBA::Boolean shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer);
     SALOME::ByteVec *fetchSerializedContent(const char *varName);
     SALOME::SeqOfByteVec *getAllKeysOfVarWithTypeDict(const char *varName);
     ~DataScopeServerBase();
   public:
+    BasicDataServer *retrieveVarInternal2(const std::string& varName);
     void initializePython(int argc, char *argv[]);
     void registerToSalomePiDict() const;
     void setPOA(PortableServer::POA_var poa);
@@ -73,8 +82,12 @@ namespace SALOMESDS
     void checkNotAlreadyExistingVar(const std::string& varName) const;
     void checkExistingVar(const std::string& varName) const;
     PickelizedPyObjServer *checkVarExistingAndDict(const std::string& varName);
+  public:
+    void moveStatusOfVarFromRdWrToRdOnly(const std::string& varName);
+    void moveStatusOfVarFromRdOnlyToRdWr(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);
   protected:
     PyObject *_globals;
     PyObject *_locals;
@@ -83,13 +96,14 @@ namespace SALOMESDS
     CORBA::ORB_var _orb;
     std::string _name;
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > > _vars;
+    SALOME::DataScopeKiller_var _killer;
     static std::size_t COUNTER;
   };
   
   class SALOMESDS_EXPORT DataScopeServer : public DataScopeServerBase, public virtual POA_SALOME::DataScopeServer
   {
   public:
-    DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName);
+    DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
     DataScopeServer(const DataScopeServer& other);
     SALOME::BasicDataServer_ptr retrieveVar(const char *varName) { return retrieveVarInternal(varName); }
     SALOME::PickelizedPyObjRdOnlyServer_ptr createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue);
@@ -101,7 +115,7 @@ namespace SALOMESDS
   class SALOMESDS_EXPORT DataScopeServerTransaction : public DataScopeServerBase, public virtual POA_SALOME::DataScopeServerTransaction
   {
   public://not remotely callable
-    DataScopeServerTransaction(CORBA::ORB_ptr orb, const std::string& scopeName);
+    DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName);
     DataScopeServerTransaction(const DataScopeServerTransaction& other);
     ~DataScopeServerTransaction();
     void createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
@@ -113,6 +127,7 @@ namespace SALOMESDS
     void notifyKey(PyObject *keyObj, PyObject *valueObj);
     SALOME::ByteVec *waitForMonoThrRev(SALOME::KeyWaiter_ptr kw);
   public://remotely callable
+    char *getAccessOfVar(const char *varName);
     SALOME::Transaction_ptr createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::Transaction_ptr createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::Transaction_ptr createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue);
@@ -120,6 +135,7 @@ namespace SALOMESDS
     SALOME::Transaction_ptr addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
     void addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
     SALOME::Transaction_ptr removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key);
+    SALOME::TransactionRdWrAccess_ptr createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue);
     SALOME::KeyWaiter_ptr waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal);
     SALOME::KeyWaiter_ptr waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac);
     void atomicApply(const SALOME::ListOfTransaction& transactions);
index 326adefe19bcd194955b9f28a1cc7b9c0732dc3c..f8b2678e02840971286ae86983d58c484d166a2e 100644 (file)
@@ -35,7 +35,7 @@ const char DataServerManager::DFT_SCOPE_NAME_IN_NS[]="Default";
 
 DataServerManager::DataServerManager(int argc, char *argv[], CORBA::ORB_ptr orb, PortableServer::POA_ptr poa):_orb(CORBA::ORB::_duplicate(orb))
 {
-  DataScopeServer *dftScope(new DataScopeServer(orb,DFT_SCOPE_NAME_IN_NS));//_remove_ref will be call by DataScopeServer::shutdownIfNotHostedByDSM
+  DataScopeServer *dftScope(new DataScopeServer(orb,SALOME::DataScopeKiller::_nil(),DFT_SCOPE_NAME_IN_NS));//_remove_ref will be call by DataScopeServer::shutdownIfNotHostedByDSM
   PortableServer::POAManager_var pman(poa->the_POAManager());
   CORBA::PolicyList policies;
   policies.length(1);
@@ -225,7 +225,10 @@ SALOME::DataScopeServerBase_ptr DataServerManager::retriveDataScope(const char *
 void DataServerManager::removeDataScope(const char *scopeName)
 {
   SALOME::DataScopeServerBase_var scs(getScopePtrGivenName(scopeName));
-  scs->shutdownIfNotHostedByDSM();
+  SALOME::DataScopeKiller_ptr killer;
+  if(scs->shutdownIfNotHostedByDSM(killer))
+    killer->shutdown();
+  CORBA::release(killer);
 }
 
 void DataServerManager::cleanScopesInNS()
@@ -246,7 +249,13 @@ void DataServerManager::shutdownScopes()
 {
   std::vector<std::string> scopeNames(listOfScopesCpp());
   for(std::vector<std::string>::const_iterator it=scopeNames.begin();it!=scopeNames.end();it++)
-    getScopePtrGivenName(*it)->shutdownIfNotHostedByDSM();
+    {
+      SALOME::DataScopeServerBase_var scope(getScopePtrGivenName(*it));
+      SALOME::DataScopeKiller_ptr killer;
+      if(scope->shutdownIfNotHostedByDSM(killer))
+        killer->shutdown();
+      CORBA::release(killer);
+    }
 }
 
 std::string DataServerManager::CreateAbsNameInNSFromScopeName(const std::string& scopeName)
index 0b1a196cc9461ad24aed793ea78c92f866890aec..b4646961eaa547dc3dd9a21d13509a96f1621bf8 100644 (file)
 
 using namespace SALOMESDS;
 
-PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
+const char PickelizedPyObjRdExtServer::ACCESS_REPR[]="RdExt";
+
+PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServerModifiable(father,varName,value)
 {
 }
 
 //! obj is consumed
-PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
+PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj)
 {
 }
 
@@ -135,3 +137,8 @@ void PickelizedPyObjRdExtServer::checkDictSetitemRdExtness(PyObject *argsPy)
       throw Exception("PickelizedPyObjRdExtServer::checkDictSetitemRdExtness : specified key of __setitem__ already exists ! RdExt property is not applied !");
     }
 }
+
+std::string PickelizedPyObjRdExtServer::getAccessStr() const
+{
+  return std::string(ACCESS_REPR);
+}
index d982c165b4162b5ee036c39e6dea9ef872844153..318e9c343508a340a9ac7f43c5576a46ec0b5801 100644 (file)
 
 namespace SALOMESDS
 {
-  class PickelizedPyObjRdExtServer : public PickelizedPyObjServer, public virtual POA_SALOME::PickelizedPyObjRdExtServer
+  class PickelizedPyObjRdExtServer : public PickelizedPyObjServerModifiable, public virtual POA_SALOME::PickelizedPyObjRdExtServer
   {
   public:
     PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
     PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
     ~PickelizedPyObjRdExtServer();
     SALOME::PickelizedPyObjRdExtServer_ptr invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
+  public:
+    std::string getAccessStr() const;
   private:
     void checkRdExtnessOf(const std::string& methodName, PyObject *argsPy);
     void checkListRdExtnessOf(const std::string& methodName, PyObject *argsPy);
     void checkDictRdExtnessOf(const std::string& methodName, PyObject *argsPy);
     void checkDictSetitemRdExtness(PyObject *argsPy);
+  public:
+    static const char ACCESS_REPR[];
   };
 }
 
index e8bef2342b637dfe431171ee69759e68aab9fd14..010ceb3efaf4b1e79aade63c20eaf0e6ad090383 100644 (file)
@@ -22,6 +22,8 @@
 
 using namespace SALOMESDS;
 
+const char PickelizedPyObjRdOnlyServer::ACCESS_REPR[]="RdOnly";
+
 PickelizedPyObjRdOnlyServer::PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
 {
 }
@@ -33,3 +35,13 @@ PickelizedPyObjRdOnlyServer::PickelizedPyObjRdOnlyServer(DataScopeServerBase *fa
 PickelizedPyObjRdOnlyServer::~PickelizedPyObjRdOnlyServer()
 {
 }
+
+void PickelizedPyObjRdOnlyServer::addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value)
+{
+  throw Exception("PickelizedPyObjRdOnlyServer::addKeyValueErrorIfAlreadyExisting : incompatible with RdOnly !");
+}
+
+std::string PickelizedPyObjRdOnlyServer::getAccessStr() const
+{
+  return std::string(ACCESS_REPR);
+}
index a5047fdaa81369b27a412ccba00ba0e10ae93c57..4ff78294bc2599169ad25e77a88f6a57918add2c 100644 (file)
@@ -36,6 +36,11 @@ namespace SALOMESDS
     PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
     PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
     ~PickelizedPyObjRdOnlyServer();
+  public:
+    void addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value);
+    std::string getAccessStr() const;
+  public:
+    static const char ACCESS_REPR[];
   };
 }
 
index cdb0d69222b6c7b879d0a3b566acd8038af10317..38c51e54ad20ad0e1739fa0f57a455d025a0efc3 100644 (file)
 
 using namespace SALOMESDS;
 
-PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& typeName, const std::string& varName):PickelizedPyObjServer(father,varName,CreateDftObjFromType(father->getGlobals(),typeName))
+const char PickelizedPyObjRdWrServer::ACCESS_REPR[]="RdWr";
+
+PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& typeName, const std::string& varName):PickelizedPyObjServerModifiable(father,varName,CreateDftObjFromType(father->getGlobals(),typeName))
 {
 }
 
-PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
+PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServerModifiable(father,varName,value)
 {
 }
 
 //! obj is consumed
-PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
+PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServerModifiable(father,varName,obj)
 {
 }
 
@@ -52,9 +54,6 @@ void PickelizedPyObjRdWrServer::setSerializedContent(const SALOME::ByteVec& newV
   setSerializedContentInternal(newValue);
 }
 
-/*!
- * Called remotely -> to protect against throw
- */
 SALOME::PickelizedPyObjRdWrServer_ptr PickelizedPyObjRdWrServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
 {
   if(!_self)
@@ -108,3 +107,22 @@ SALOME::PickelizedPyObjRdWrServer_ptr PickelizedPyObjRdWrServer::invokePythonMet
   CORBA::Object_var obj(poa->id_to_reference(id));
   return SALOME::PickelizedPyObjRdWrServer::_narrow(obj);
 }
+
+void PickelizedPyObjRdWrServer::addKeyValueHard(PyObject *key, PyObject *value)
+{
+  bool isOK(PyDict_SetItem(_self,key,value)==0);
+  if(!isOK)
+    throw Exception("PickelizedPyObjRdWrServer::addKeyValueHard : error when trying to add key,value to dict !");
+}
+
+void PickelizedPyObjRdWrServer::removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key)
+{
+  checkKeyPresent(key);
+  if(PyDict_DelItem(_self,key)!=0)
+    throw Exception("PickelizedPyObjRdWrServer::removeKeyInVarErrorIfNotAlreadyExisting : error during deletion of key in dict !");
+}
+
+std::string PickelizedPyObjRdWrServer::getAccessStr() const
+{
+  return std::string(ACCESS_REPR);
+}
index b6fba2f21502175c481145ea04e125dfd071826d..0a3a3e0934d8a96853de6e97a84c032b9d766bf0 100644 (file)
@@ -30,7 +30,7 @@
 
 namespace SALOMESDS
 {
-  class PickelizedPyObjRdWrServer : public PickelizedPyObjServer, public virtual POA_SALOME::PickelizedPyObjRdWrServer
+  class PickelizedPyObjRdWrServer : public PickelizedPyObjServerModifiable, public virtual POA_SALOME::PickelizedPyObjRdWrServer
   {
   public:
     PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& typeName, const std::string& varName);
@@ -39,6 +39,12 @@ namespace SALOMESDS
     ~PickelizedPyObjRdWrServer();
     void setSerializedContent(const SALOME::ByteVec& newValue);
     SALOME::PickelizedPyObjRdWrServer_ptr invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
+  public:
+    std::string getAccessStr() const;
+    void addKeyValueHard(PyObject *key, PyObject *value);
+    void removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key);
+  public:
+    static const char ACCESS_REPR[];
   };
 }
 
index f770129eb4825c0b09c6522e3ed7fd33661b8469..587bc55fa5482487580373e5c6b9a90523750924 100644 (file)
@@ -72,24 +72,14 @@ void PickelizedPyObjServer::checkKeyPresent(PyObject *key)
 
 void PickelizedPyObjServer::addKeyValueHard(PyObject *key, PyObject *value)
 {
-  bool isOK(PyDict_SetItem(_self,key,value)==0);
-  if(!isOK)
-    throw Exception("PickelizedPyObjServer::addKeyValueHard : error when trying to add key,value to dict !");
-}
-
-void PickelizedPyObjServer::addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value)
-{
-  checkKeyNotAlreadyPresent(key);
-  bool isOK(PyDict_SetItem(_self,key,value)==0);
-  if(!isOK)
-    throw Exception("PickelizedPyObjServer::addKeyValueErrorIfAlreadyExisting : error when trying to add key,value to dict !");
+  std::ostringstream oss; oss << "PickelizedPyObjServer::addKeyValueHard : var \"" << getVarNameCpp() << "\" is not permitted to alter its value !";
+  throw Exception(oss.str());
 }
 
 void PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key)
 {
-  checkKeyPresent(key);
-  if(PyDict_DelItem(_self,key)!=0)
-    throw Exception("PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting : error during deletion of key in dict !");
+  std::ostringstream oss; oss << "PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting : var \"" << getVarNameCpp() << "\" is not permitted to alter its value !";
+  throw Exception(oss.str());
 }
 
 void PickelizedPyObjServer::FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret)
@@ -264,3 +254,19 @@ void PickelizedPyObjServer::checkKeyPresence(PyObject *key, bool presence)
     }
   Py_XDECREF(retPy);
 }
+
+PickelizedPyObjServerModifiable::PickelizedPyObjServerModifiable(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
+{
+}
+
+PickelizedPyObjServerModifiable::PickelizedPyObjServerModifiable(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
+{
+}
+
+void PickelizedPyObjServerModifiable::addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value)
+{
+  checkKeyNotAlreadyPresent(key);
+  bool isOK(PyDict_SetItem(_self,key,value)==0);
+  if(!isOK)
+    throw Exception("PickelizedPyObjServerModifiable::addKeyValueErrorIfAlreadyExisting : error when trying to add key,value to dict !");
+}
index 2b64906511f26c302cca5db7544495a6e205ed79..03458877574a1863914396b2eff43ca4ba704543 100644 (file)
@@ -37,17 +37,19 @@ namespace SALOMESDS
   public:
     PickelizedPyObjServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
     PickelizedPyObjServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
-    ~PickelizedPyObjServer();
+    virtual ~PickelizedPyObjServer();
     void setSerializedContent(const SALOME::ByteVec& newValue);
     SALOME::ByteVec *fetchSerializedContent();
   public:
     bool isDict();
     void checkKeyNotAlreadyPresent(PyObject *key);
     void checkKeyPresent(PyObject *key);
-    void addKeyValueHard(PyObject *key, PyObject *value);
-    void addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value);
-    void removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key);
     PyObject *getPyObj() const { return _self; }
+  public:
+    virtual void addKeyValueHard(PyObject *key, PyObject *value);
+    virtual void removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key);
+    virtual void addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value) = 0;
+    virtual std::string getAccessStr() const = 0;
   public:
     static void FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret);
     static void FromCppToByteSeq(const std::string& strToBeConv, SALOME::ByteVec& ret);
@@ -68,6 +70,14 @@ namespace SALOMESDS
     PyObject *_self;
     PortableServer::POA_var _poa;
   };
+
+  class PickelizedPyObjServerModifiable : public PickelizedPyObjServer
+  {
+  public:
+    PickelizedPyObjServerModifiable(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
+    PickelizedPyObjServerModifiable(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
+    void addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value);
+  };
 }
 
 #endif
index 2fee70216c89f69ed62b10bcfeab67c2ef25d6d4..3373bfa251d8bb6547360779279db85b2d172d87 100644 (file)
@@ -30,6 +30,7 @@ namespace SALOMESDS
   public:
     void incrRef() const;
     bool decrRef() const;
+    int getCounter() const { return _cnt; }
   protected:
     RefCountServ();
     RefCountServ(const RefCountServ& other);
index ca9bc32ee239973a6f449cbb05667e115dce6d17..463f2f5ffa25f5ddfd762300324d3217bfb8c78b 100644 (file)
@@ -21,6 +21,8 @@
 #include "SALOMESDS_Transaction.hxx"
 #include "SALOMESDS_Exception.hxx"
 #include "SALOMESDS_PickelizedPyObjServer.hxx"
+#include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
+#include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
 
 #include <sstream>
 
@@ -64,7 +66,7 @@ void TransactionVarCreate::rollBack()
 }
 
 /*!
- TODO : To be implemented.
+ * no implementation it is not a bug !
  */
 void TransactionVarCreate::notify()
 {
@@ -169,7 +171,7 @@ void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::perform()
 }
 
 /*!
- * not implementation it is not a bug !
+ * no implementation it is not a bug !
  */
 void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::notify()
 {
@@ -179,3 +181,46 @@ TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::~TransactionRemoveKeyInVarEr
 {
   Py_XDECREF(_key);
 }
+
+TransactionMorphRdWrIntoRdOnly::TransactionMorphRdWrIntoRdOnly(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName)
+{
+}
+
+SALOME::PickelizedPyObjRdWrServer_ptr TransactionMorphRdWrIntoRdOnly::getVar()
+{
+  SALOME::BasicDataServer_var obj(_dsct->retrieveVarInternal(_var_name.c_str()));
+  SALOME::PickelizedPyObjRdWrServer_ptr ret(SALOME::PickelizedPyObjRdWrServer::_narrow(obj));
+  if(CORBA::is_nil(ret))
+    {
+      std::ostringstream oss; oss << "TransactionMorphRdWrIntoRdOnly::getVar : var \"" << _var_name << "\" has not expected PickelizedPyObjRdWrServer type !";
+      throw Exception(oss.str());
+    }
+  return ret;
+}
+
+void TransactionMorphRdWrIntoRdOnly::prepareRollBackInCaseOfFailure()
+{
+  BasicDataServer *var(_dsct->retrieveVarInternal2(_var_name));
+  if(!var)
+    throw Exception("TransactionMorphRdWrIntoRdOnly::prepareRollBackInCaseOfFailure : Returned var is NULL !");
+  PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(var));
+  if(!varc)
+    throw Exception("TransactionMorphRdWrIntoRdOnly::prepareRollBackInCaseOfFailure : Returned var has not expected type !");
+}
+
+void TransactionMorphRdWrIntoRdOnly::perform()
+{
+  _dsct->moveStatusOfVarFromRdWrToRdOnly(_var_name);
+}
+
+void TransactionMorphRdWrIntoRdOnly::rollBack()
+{
+  _dsct->moveStatusOfVarFromRdOnlyToRdWr(_var_name);
+}
+
+/*!
+ * no implementation it is not a bug !
+ */
+void TransactionMorphRdWrIntoRdOnly::notify()
+{
+}
index 2bed22478a995c2aa0d7fdf2b272629a5b9539b0..4fad07b058cfbf4fb6e1badee507638c5385d44c 100644 (file)
@@ -34,6 +34,8 @@
 namespace SALOMESDS
 {
   class PickelizedPyObjServer;
+  class PickelizedPyObjRdWrServer;
+  class PickelizedPyObjRdExtServer;
 
   class SALOMESDS_EXPORT Transaction : public virtual POA_SALOME::Transaction, public POAHolder
   {
@@ -138,6 +140,19 @@ namespace SALOMESDS
   private:
     PyObject *_key;
   };
+
+  class TransactionMorphRdWrIntoRdOnly : public Transaction, public virtual POA_SALOME::TransactionRdWrAccess
+  {
+  public:
+    TransactionMorphRdWrIntoRdOnly(DataScopeServerTransaction *dsct, const std::string& varName);
+  public:
+    SALOME::PickelizedPyObjRdWrServer_ptr getVar();
+  public:
+    void prepareRollBackInCaseOfFailure();
+    void perform();
+    void rollBack();
+    void notify();
+  };
 }
 
 #endif
index de6790b1f8f07f82072156720ff0d13aec566e91..11dca2cec87d636fc37d2f3fb60d71217d8bd801 100644 (file)
@@ -41,11 +41,15 @@ int main(int argc, char *argv[])
   PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
   PortableServer::POAManager_var mgr(poa->the_POAManager());
   mgr->activate();
+  //
+  SALOMESDS::DataScopeKiller *killer(new SALOMESDS::DataScopeKiller(orb));
+  SALOME::DataScopeKiller_var killerObj(killer->_this());
+  //
   SALOMESDS::DataScopeServerBase *server(0);
   if(!isTransac)
-    server=new SALOMESDS::DataScopeServer(orb,scopeName);
+    server=new SALOMESDS::DataScopeServer(orb,killerObj,scopeName);
   else
-    server=new SALOMESDS::DataScopeServerTransaction(orb,scopeName);
+    server=new SALOMESDS::DataScopeServerTransaction(orb,killerObj,scopeName);
   //
   CORBA::PolicyList policies;
   policies.length(1);
@@ -62,7 +66,7 @@ int main(int argc, char *argv[])
   server->registerInNS(serverPtr);
   //
   orb->run();
-  server->_remove_ref();
+  delete killer;
   return 0;
 }
 
index 48eac9d8c669832ff0269f2c106f6adb901cbe86..8c92e668674a4ad3ee41db082a21551fa963981d 100644 (file)
@@ -39,7 +39,7 @@ class InvokatorPossibleStyle(InvokatorStyle):
         
     @classmethod
     def IsOK(cls,varPtr):
-        return isinstance(varPtr,SALOME._objref_PickelizedPyObjRdExtServer)
+        return isinstance(varPtr,SALOME._objref_PickelizedPyObjRdExtServer) or isinstance(varPtr,SALOME._objref_PickelizedPyObjRdWrServer)
     pass
 
 class InvokatorImpossibleStyle(InvokatorStyle):
index dc779c77aa8eb3679e94704abdda4f4ca2533c62..c916d19c29c5f252603c178fde17e2e48cbbaa3e 100644 (file)
@@ -113,9 +113,11 @@ class SalomeSDSTest(unittest.TestCase):
     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
     self.assertTrue(isCreated)
     #
-    t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
+    t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
     dss.atomicApply([t0])
     #
+    self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
+    #
     t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
     dss.atomicApply([t1])
     #
@@ -142,6 +144,8 @@ class SalomeSDSTest(unittest.TestCase):
     t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
     dss.atomicApply([t0])
     #
+    self.assertEqual(dss.getAccessOfVar(varName),"RdExt")
+    #
     self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExisting,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
     t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
     dss.atomicApply([t1])
@@ -160,7 +164,7 @@ class SalomeSDSTest(unittest.TestCase):
     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
     self.assertTrue(isCreated)
     #
-    t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
+    t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
     dss.atomicApply([t0])
     #
     t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
@@ -182,7 +186,7 @@ class SalomeSDSTest(unittest.TestCase):
     dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
     self.assertTrue(isCreated)
     #
-    t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
+    t0=dss.createRdWrVarTransac(varName,obj2Str({"ab":[4,5,6]}))
     dss.atomicApply([t0])
     #
     t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
@@ -218,6 +222,52 @@ class SalomeSDSTest(unittest.TestCase):
     keys=[str2Obj(elt) for elt in dss.getAllKeysOfVarWithTypeDict(varName)]
     self.assertEqual(keys,['ab','cd'])
 
+  def testTransaction6(self):
+    """ Test to test RdWr global vars with transaction"""
+    scopeName="Scope1"
+    varName="a"
+    dsm=salome.naming_service.Resolve("/DataServerManager")
+    dsm.cleanScopesInNS()
+    if scopeName in dsm.listScopes():
+      dsm.removeDataScope(scopeName)
+    dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName)
+    self.assertTrue(isCreated)
+    #
+    t0=dss.createWorkingVarTransac(varName,obj2Str({}))
+    a=SalomeSDSClt.GetHandlerFromRef(t0.getVar())
+    self.assertEqual(dss.getAccessOfVar(varName),"RdWr")
+    # play
+    a["ab"]=4
+    self.assertEqual(a.local_copy(),{"ab":4})
+    a["cd"]=[5]
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
+    a["cd"].append(77)
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
+    a.__setitem__("ef",["a","bb"])
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
+    a["ef"].append("ccc")
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
+    a["gh"]=a
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
+    a["gh"]["cd"].append(99) ; a["cd"].append(88)
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77,99],"ef":["a","bb","ccc"]}})
+    # WARNING here not problem to overwrite
+    a["gh"]=7
+    self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
+    # end of play
+    self.assertTrue(isinstance(a,SalomeSDSClt.Dict))
+    self.assertTrue(isinstance(a,SalomeSDSClt.WrappedType))# important for EEM
+    # commit : RdWr->RdOnly
+    dss.atomicApply([t0])
+    #
+    self.assertEqual(dss.getAccessOfVar(varName),"RdOnly") # after atomicApply the var is readOnly. Impossible to change its value !
+    self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":7})
+    dsm.cleanScopesInNS()
+    del a # very important kill Ref before removingDataScope...
+    if scopeName in dsm.listScopes():
+      dsm.removeDataScope(scopeName)
+    pass
+
   def setUp(self):
     salome.salome_init()
     pass