Salome HOME
add method NameChanged to update title name
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_DataScopeServer.cxx
index 9dec327d6da837ba22c874b5ed2fbbce6c04578b..23b809b87f903e49d81a8aea56b814b663dafc5e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,8 @@
 #include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
+#include "SALOMESDS_PickelizedPyObjRdExtInitServer.hxx"
+#include "SALOMESDS_TrustTransaction.hxx"
 #include "SALOMESDS_KeyWaiter.hxx"
 #include "SALOMESDS_Transaction.hxx"
 #include "SALOME_NamingService.hxx"
@@ -44,11 +46,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):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
 {
 }
 
@@ -57,6 +65,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 +142,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 +166,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;
     }
 }
 
@@ -223,10 +247,10 @@ void DataScopeServerBase::initializePython(int argc, char *argv[])
 
 void DataScopeServerBase::registerToSalomePiDict() const
 {
-  PyObject *mod(PyImport_ImportModule("addToKillList"));
+  PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
   if(!mod)
     return;
-  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));
+  PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
   if(!meth)
     { Py_XDECREF(mod); return ; }
   PyObject *args(PyTuple_New(2));
@@ -235,6 +259,7 @@ void DataScopeServerBase::registerToSalomePiDict() const
   PyObject *res(PyObject_CallObject(meth,args));
   Py_XDECREF(args);
   Py_XDECREF(res);
+  Py_XDECREF(meth);
   Py_XDECREF(mod);
 }
 
@@ -307,13 +332,87 @@ 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();
+}
+
+void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
+{
+  std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
+  PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
+  PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
+  if(!varc0 && !varc1)
+    throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
+  if(varc0)
+    {
+      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::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::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
+  if(varc0)
+    {
+      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();
+        }
+    }
+}
+
 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,13 +422,29 @@ 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)
 {
 }
 
-DataScopeServer::DataScopeServer(const DataScopeServer& other):DataScopeServerBase(other)
+DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
 {
 }
 
@@ -355,9 +470,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 +487,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));
@@ -391,10 +503,33 @@ DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, const
   _poa_for_key_waiter=poa2;
 }
 
-DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
+DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
 {
 }
 
+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());
+}
+
+/*!
+ * This method is here to retrieve atomically accessStr and picklization.
+ */
+void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
+{
+  access=getAccessOfVar(varName);
+  data=fetchSerializedContent(varName);
+}
+
 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
 {
   checkNotAlreadyExistingVar(varName);
@@ -413,6 +548,15 @@ void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varNa
   _vars.push_back(p);
 }
 
+void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
+{
+  checkNotAlreadyExistingVar(varName);
+  PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
+  CORBA::Object_var ret(tmp->activate());
+  std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+  _vars.push_back(p);
+}
+
 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
 {
   checkNotAlreadyExistingVar(varName);
@@ -438,6 +582,14 @@ SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const
   return SALOME::Transaction::_narrow(obj);
 }
 
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+  checkNotAlreadyExistingVar(varName);
+  TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
+  CORBA::Object_var obj(ret->activate());
+  return SALOME::Transaction::_narrow(obj);
+}
+
 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
 {
   checkNotAlreadyExistingVar(varName);
@@ -482,7 +634,7 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj)
     }
 }
 
-void DataScopeServerTransaction::notifyKey(PyObject *keyObj, PyObject *valueObj)
+void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
 {
   PyObject *cmpObj(getPyCmpFunc());
   if(!keyObj)
@@ -493,6 +645,11 @@ void DataScopeServerTransaction::notifyKey(PyObject *keyObj, PyObject *valueObj)
   std::list< KeyWaiter *> newList,listOfEltToWakeUp;
   for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
     {
+      if((*it)->getVarName()!=varName)
+        {
+          newList.push_back(*it);
+          continue;
+        }
       PyObject *waitKey((*it)->getKeyPyObj());
       PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
       PyObject *res(PyObject_CallObject(cmpObj,args));
@@ -534,31 +691,14 @@ SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlrea
   TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
   CORBA::Object_var obj(ret->activate());
   return SALOME::Transaction::_narrow(obj);
-};
-
-class TrustTransaction
-{
-public:
-  TrustTransaction():_must_rollback(0),_ptr(0) { }
-  void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); }
-  void operate() { _ptr->perform(); }
-  ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); }
-private:
-  bool *_must_rollback;
-  Transaction *_ptr;
-};
+}
 
-void DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
+SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
 {
   checkVarExistingAndDict(varName);
-  TransactionAddKeyValueErrorIfAlreadyExisting ret(this,varName,key,value);
-  {
-    bool mustRollback(true);
-    TrustTransaction t;
-    t.setTransaction(&ret,&mustRollback);
-    t.operate();
-    mustRollback=false;
-  }
+  TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
+  CORBA::Object_var obj(ret->activate());
+  return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
 }
 
 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
@@ -569,6 +709,30 @@ 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::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
+{
+  std::string varNameCpp(varName);
+  checkExistingVar(varNameCpp);
+  //
+  TransactionKillVar *ret(new TransactionKillVar(this,varName));
+  CORBA::Object_var obj2(ret->activate());
+  return SALOME::Transaction::_narrow(obj2);
+}
+
 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
 {
   PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
@@ -602,7 +766,7 @@ SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter
   if(!retc)
     throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
   retc->_remove_ref();
-  retc->waitForMonoThr();
+  return retc->waitForMonoThr();
 }
 
 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)