+ std::size_t pos(std::distance(allNames.begin(),it));
+ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
+ for(std::size_t i=0;i<pos;i++,it0++);
+ 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, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
+{
+}
+
+DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
+{
+}
+
+SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
+{
+ std::string varNameCpp(varName);
+ checkNotAlreadyExistingVar(varNameCpp);
+ PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+ return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
+}
+
+SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
+{
+ std::string varNameCpp(varName);
+ checkNotAlreadyExistingVar(varNameCpp);
+ PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+ return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
+}
+
+SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
+{
+ std::string varNameCpp(varName),typeNameCpp(typeName);
+ checkNotAlreadyExistingVar(varNameCpp);
+ PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+ return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
+}
+
+DataScopeServer::~DataScopeServer()
+{
+}
+
+////////
+
+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));
+ //
+ PortableServer::POAManager_var mgr(poa->the_POAManager());
+ CORBA::PolicyList policies;
+ policies.length(1);
+ PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
+ policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
+ PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
+ threadPol->destroy();
+ //
+ _poa_for_key_waiter=poa2;
+}
+
+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);
+ PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(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::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(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::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);
+ PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(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);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
+ CORBA::Object_var obj(ret->activate());
+ 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);
+ TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
+{
+ if(!kw)
+ throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
+ _waiting_keys.push_back(kw);
+}
+
+void DataScopeServerTransaction::pingKey(PyObject *keyObj)
+{
+ PyObject *cmpObj(getPyCmpFunc());
+ if(!keyObj)
+ throw Exception("ataScopeServerTransaction::pingKey : Key Object is NULL !");
+ PyObject *args(PyTuple_New(2));
+ PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
+ std::size_t ii(0);
+ // this part does nothing except to be sure that in notify key all will be OK.
+ for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
+ {
+ PyObject *waitKey((*it)->getKeyPyObj());
+ PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
+ PyObject *res(PyObject_CallObject(cmpObj,args));
+ if(res==NULL)
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
+ throw Exception(oss.str());
+ }
+ PyInt_AsLong(res);
+ if(PyErr_Occurred())
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
+ throw Exception(oss.str());
+ }
+ Py_XDECREF(res);
+ }
+}
+
+void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
+{
+ PyObject *cmpObj(getPyCmpFunc());
+ if(!keyObj)
+ throw Exception("DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! Key Object is NULL !");
+ PyObject *args(PyTuple_New(2));
+ PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
+ std::size_t ii(0);
+ 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));
+ if(res==NULL)
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
+ throw Exception(oss.str());
+ }
+ long resCpp(PyInt_AsLong(res));
+ if(PyErr_Occurred())
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
+ throw Exception(oss.str());
+ }
+ Py_XDECREF(res);
+ if(resCpp==0)
+ listOfEltToWakeUp.push_back(*it);
+ else
+ newList.push_back(*it);
+ }
+ for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
+ (*it)->valueJustCome(valueObj);
+ for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
+ (*it)->go();
+ _waiting_keys=newList;
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
+{
+ checkVarExistingAndDict(varName);
+ TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
+{
+ checkVarExistingAndDict(varName);
+ TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
+{
+ checkVarExistingAndDict(varName);
+ 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)
+{
+ checkVarExistingAndDict(varName);
+ TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
+ CORBA::Object_var obj(ret->activate());
+ 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));
+ KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
+ CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
+ return SALOME::KeyWaiter::_narrow(obj);
+}
+
+SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
+{
+ PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
+ KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
+ CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
+ //
+ TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
+ CORBA::Object_var obj2(ret1->activate());
+ transac=SALOME::Transaction::_narrow(obj2);
+ //
+ return SALOME::KeyWaiter::_narrow(obj);
+}
+
+SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
+{
+ PortableServer::ServantBase *ret(0);
+ try
+ {
+ ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
+ }
+ catch(...) { ret=0; }
+ KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
+ if(!retc)
+ throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
+ retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
+ SALOME::ByteVec *zeRet(retc->waitForMonoThr());
+ retc->enforcedRelease();
+ return zeRet;
+}
+
+SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw)
+{
+ PortableServer::ServantBase *ret(0);
+ try
+ {
+ ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
+ }
+ catch(...) { ret=0; }
+ KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
+ if(!retc)
+ throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
+ retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
+ SALOME::ByteVec *zeRet(retc->waitForAndKill());
+ retc->enforcedRelease();
+ return zeRet;