1 // Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony GEAY (EDF R&D)
21 #include "SALOMESDS_DataScopeServer.hxx"
22 #include "SALOMESDS_DataServerManager.hxx"
23 #include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx"
24 #include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
25 #include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
26 #include "SALOMESDS_PickelizedPyObjRdExtInitServer.hxx"
27 #include "SALOMESDS_TrustTransaction.hxx"
28 #include "SALOMESDS_KeyWaiter.hxx"
29 #include "SALOMESDS_Transaction.hxx"
30 #include "SALOME_NamingService_Abstract.hxx"
31 #include "SALOMESDS_Exception.hxx"
37 // agy : awful, to be factorized with ContainerManager.
42 #define getpid _getpid
45 using namespace SALOMESDS;
47 std::size_t DataScopeServerBase::COUNTER=0;
49 void DataScopeKiller::shutdown()
54 RequestSwitcher::RequestSwitcher(CORBA::ORB_ptr orb, DataScopeServerTransaction *ds):RequestSwitcherBase(orb),_ds(ds)
58 SALOME::StringVec *RequestSwitcher::listVars()
60 return _ds->listVars();
63 SALOME::ByteVec *RequestSwitcher::fetchSerializedContent(const char *varName)
65 return _ds->fetchSerializedContent(varName);
68 void RequestSwitcher::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
70 return _ds->fetchAndGetAccessOfVar(varName,access,data);
73 DataScopeServerBase::DataScopeServerBase(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName, SALOME_NamingService_Container_Abstract *ns):_ns(ns),_pyHelper(pyHelper),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName),_killer(killer)
77 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_ns(other._ns->clone()),_pyHelper(other._pyHelper),_name(other._name),_vars(other._vars),_killer(other._killer)
81 DataScopeServerBase::~DataScopeServerBase()
83 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
85 BasicDataServer *obj((*it).second);
95 * Called remotely -> to protect against throw
97 void DataScopeServerBase::ping()
102 * Called remotely -> to protect against throw
104 char *DataScopeServerBase::getScopeName()
106 return CORBA::string_dup(_name.c_str());
110 * Called remotely -> to protect against throw
112 SALOME::StringVec *DataScopeServerBase::listVars()
114 SALOME::StringVec *ret(new SALOME::StringVec);
115 std::size_t sz(_vars.size());
116 ret->length((CORBA::ULong)sz); //!< TODO: size_t to CORBA::ULong
117 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
118 for(std::size_t i=0;i<sz;it++,i++)
120 BasicDataServer *obj((*it).second);
121 std::string name(obj->getVarNameCpp());
122 (*ret)[(CORBA::ULong)i]=CORBA::string_dup(name.c_str()); //!< TODO: size_t to CORBA::ULong
127 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
129 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
130 for(;it!=_vars.end();it++)
131 if((*it).second->getVarNameCpp()==varName)
136 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
138 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
139 return SALOME::BasicDataServer::_duplicate((*it0).first);
142 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
144 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
145 return (*it0).second;
148 void DataScopeServerBase::deleteVar(const char *varName)
150 std::string varNameCpp(varName);
151 std::vector<std::string> allNames(getAllVarNames());
152 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
153 if(it==allNames.end())
155 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
156 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
157 throw Exception(oss.str());
159 std::size_t pos(std::distance(allNames.begin(),it));
160 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
161 for(std::size_t ii=0;ii<pos;ii++,it0++);
162 (*it0).second->decrRef();
166 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
168 CORBA::Object_var obj(_ns->Resolve(DataServerManager::NAME_IN_NS));
169 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
170 if(CORBA::is_nil(dsm))
171 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
172 // destroy ref in the naming service
173 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
174 _ns->Destroy_Name(fullScopeName.c_str());
175 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
176 PortableServer::ServantBase *ret(0);
179 ret=_poa->reference_to_servant(dsm);
181 catch(...) { ret=0; }
186 killer=SALOME::DataScopeKiller::_duplicate(_killer);
193 killer=SALOME::DataScopeKiller::_duplicate(_killer);
198 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
200 BasicDataServer *var(retrieveVarInternal2(varName));
201 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
204 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
205 throw Exception(oss.str());
207 return varc->fetchSerializedContent();
210 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
212 BasicDataServer *var(retrieveVarInternal2(varName));
213 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
216 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
217 throw Exception(oss.str());
221 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
222 throw Exception(oss.str());
224 PyObject *keys(PyDict_Keys(varc->getPyObj()));
225 if(!PyList_Check(keys))
227 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
228 throw Exception(oss.str());
230 Py_ssize_t sz(PyList_Size(keys));
231 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
232 ret->length((CORBA::ULong)sz); //!< TODO: convert Py_ssize_t in CORBA::ULong
233 for(Py_ssize_t i=0;i<sz;i++)
235 PyObject *item(PyList_GetItem(keys,i));
237 std::string pickel(varc->pickelize(item));//item consumed
238 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[(CORBA::ULong)i]); //!< TODO: convert Py_ssize_t in CORBA::ULong
244 SALOME::ByteVec *DataScopeServerBase::getValueOfVarWithTypeDict(const char *varName, const SALOME::ByteVec& constKey)
246 BasicDataServer *var(retrieveVarInternal2(varName));
247 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
250 std::ostringstream oss; oss << "DataScopeServerBase::getValueOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
251 throw Exception(oss.str());
255 std::ostringstream oss; oss << "DataScopeServerBase::getValueOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
256 throw Exception(oss.str());
260 PickelizedPyObjServer::FromByteSeqToCpp(constKey,keyCpp);
261 SALOME::AutoPyRef key(PickelizedPyObjServer::GetPyObjFromPickled(keyCpp,this));
262 PyObject *value(PyDict_GetItem(varc->getPyObj(),key.get()));//borrowed
265 std::ostringstream oss; oss << "DataScopeServerBase::getValueOfVarWithTypeDict : var \"" << varName << "\" seems to not have key specified !";
266 throw Exception(oss.str());
269 std::string ret(PickelizedPyObjServer::Pickelize(value,this));//value is consumed
270 return PickelizedPyObjServer::FromCppToByteSeq(ret);
273 void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
275 if(napDurationInSec<0.)
276 throw Exception("DataScopeServerBase::takeANap : negative value !");
278 struct timespec req,rem;
279 long nbSec((long)napDurationInSec);
280 double remainTime(napDurationInSec-(double)nbSec);
282 req.tv_nsec=(long)(remainTime*1000000.);
283 int ret(nanosleep(&req,&rem));
285 throw Exception("DataScopeServerBase::takeANap : nap not finished as expected !");
287 throw Exception("DataScopeServerBase::takeANap : not implemented for Windows !");
291 void DataScopeServerBase::registerToSalomePiDict() const
293 _pyHelper->registerToSalomePiDict("SALOME_DataScopeServerBase",getpid());
296 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
301 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
303 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
304 _ns->Register(ptr,fullScopeName.c_str());
307 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
309 std::ostringstream oss;
310 oss << varName << "@" << COUNTER++;
314 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
316 std::size_t sz(_vars.size());
317 std::vector<std::string> ret(sz);
318 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
319 for(std::size_t i=0;i<sz;it++,i++)
320 ret[i]=(*it).second->getVarNameCpp();
324 bool DataScopeServerBase::isExistingVar(const std::string& varName) const
326 std::vector<std::string> allNames(getAllVarNames());
327 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
328 return it!=allNames.end();
331 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
333 if(isExistingVar(varName))
335 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
336 throw Exception(oss.str());
340 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
342 std::vector<std::string> allNames(getAllVarNames());
343 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
344 if(it==allNames.end())
346 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
347 throw Exception(oss.str());
351 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
353 checkExistingVar(varName);
354 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
355 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
358 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
359 throw Exception(oss.str());
363 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
364 throw Exception(oss.str());
369 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
371 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
372 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
373 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
375 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
376 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
377 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
378 CORBA::Object_var obj(newVar->activate());
379 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
380 p.first=obj2; p.second=newVar;
384 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
386 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
387 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
388 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
390 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
391 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
392 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
393 CORBA::Object_var obj(newVar->activate());
394 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
395 p.first=obj2; p.second=newVar;
399 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
401 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
402 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
403 PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
404 PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
406 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
409 PickelizedPyObjRdExtInitServer *newVar(varc0->buildInitInstanceFrom(varName));
410 newVar->incrNbClients();
411 CORBA::Object_var obj(newVar->activate());
412 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
413 p.first=obj2; p.second=newVar;
417 varc1->incrNbClients();
420 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName)
422 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
423 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
424 PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
425 PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
427 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
430 if(varc0->decrNbClients())
432 PickelizedPyObjRdExtServer *newVar(varc0->buildStdInstanceFrom(varName));
433 CORBA::Object_var obj(newVar->activate());
434 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
435 p.first=obj2; p.second=newVar;
441 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
443 std::vector<std::string> allNames(getAllVarNames());
444 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
445 if(it==allNames.end())
447 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
448 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
449 throw Exception(oss.str());
451 std::size_t pos(std::distance(allNames.begin(),it));
452 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
453 for(std::size_t i=0;i<pos;i++,it0++);
457 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
459 std::vector<std::string> allNames(getAllVarNames());
460 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
461 if(it==allNames.end())
463 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
464 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
465 throw Exception(oss.str());
467 std::size_t pos(std::distance(allNames.begin(),it));
468 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
469 for(std::size_t i=0;i<pos;i++,it0++);
475 DataScopeServer::DataScopeServer(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName, SALOME_NamingService_Container_Abstract *ns):DataScopeServerBase(pyHelper,orb,killer,scopeName,ns)
479 DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
483 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
485 std::string varNameCpp(varName);
486 checkNotAlreadyExistingVar(varNameCpp);
487 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
488 CORBA::Object_var ret(tmp->activate());
489 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
491 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
494 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
496 std::string varNameCpp(varName);
497 checkNotAlreadyExistingVar(varNameCpp);
498 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
499 CORBA::Object_var ret(tmp->activate());
500 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
502 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
505 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
507 std::string varNameCpp(varName),typeNameCpp(typeName);
508 checkNotAlreadyExistingVar(varNameCpp);
509 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
510 CORBA::Object_var ret(tmp->activate());
511 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
513 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
516 DataScopeServer::~DataScopeServer()
522 DataScopeServerTransaction::DataScopeServerTransaction(const SALOME_CPythonHelper *pyHelper, CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName, SALOME_NamingService_Container_Abstract *ns):DataScopeServerBase(pyHelper,orb,killer,scopeName,ns)
524 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
525 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
527 PortableServer::POAManager_var mgr(poa->the_POAManager());
528 CORBA::PolicyList policies;
530 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
531 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
532 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
533 threadPol->destroy();
535 _poa_for_key_waiter=poa2;
538 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
542 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
544 std::string varNameCpp(varName);
545 checkExistingVar(varNameCpp);
546 BasicDataServer *var(retrieveVarInternal2(varName));
548 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
549 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
551 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
552 std::string ret(varc->getAccessStr());
553 return CORBA::string_dup(ret.c_str());
557 * This method is here to retrieve atomically accessStr and picklization.
559 void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
561 access=getAccessOfVar(varName);
562 data=fetchSerializedContent(varName);
565 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
567 checkNotAlreadyExistingVar(varName);
568 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
569 CORBA::Object_var ret(tmp->activate());
570 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
574 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
576 checkNotAlreadyExistingVar(varName);
577 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
578 CORBA::Object_var ret(tmp->activate());
579 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
583 void DataScopeServerTransaction::createRdExtVarFreeStyleInternal(const std::string& varName, const SALOME::ByteVec& constValue, std::string&& compareFuncContent, SALOME::AutoPyRef&& compareFunc)
585 if(!isExistingVar(varName))
587 PickelizedPyObjRdExtFreeStyleServer *tmp(new PickelizedPyObjRdExtFreeStyleServer(this,varName,constValue,std::move(compareFuncContent),std::move(compareFunc)));
588 CORBA::Object_var ret(tmp->activate());
589 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
594 BasicDataServer *ds(retrieveVarInternal2(varName));
597 std::ostringstream oss;
598 oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : internal error 1 for varname \"" << varName << "\"!";
599 throw Exception(oss.str());
601 Sha1Keeper *ds2(dynamic_cast<Sha1Keeper *>(ds));
604 std::ostringstream oss;
605 oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non Sha1Keeper type !";
606 throw Exception(oss.str());
608 PickelizedPyObjServer *ds3(dynamic_cast<PickelizedPyObjServer *>(ds));
611 std::ostringstream oss;
612 oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non PickelizedPyObjServer type !";
613 throw Exception(oss.str());
615 std::vector<unsigned char> constValueAsCpp;
616 Transaction::FromByteSeqToVB(constValue,constValueAsCpp);
617 SALOME::AutoPyRef newObj(PickelizedPyObjServer::GetPyObjFromPickled(constValueAsCpp,this));
620 std::ostringstream oss;
621 oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists but input pickelized object is not loadable !";
622 throw Exception(oss.str());
624 ds2->checkSame(varName,compareFuncContent,ds3->getPyObj(),newObj);
628 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
630 checkNotAlreadyExistingVar(varName);
631 PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
632 CORBA::Object_var ret(tmp->activate());
633 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
637 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
639 checkNotAlreadyExistingVar(varName);
640 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
641 CORBA::Object_var ret(tmp->activate());
642 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
646 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
648 checkNotAlreadyExistingVar(varName);
649 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
650 CORBA::Object_var obj(ret->activate());
651 return SALOME::Transaction::_narrow(obj);
654 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
656 checkNotAlreadyExistingVar(varName);
657 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
658 CORBA::Object_var obj(ret->activate());
659 return SALOME::Transaction::_narrow(obj);
662 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarFreeStyleTransac(const char *varName, const SALOME::ByteVec& constValue, const char *compareFuncContent)
663 {// no check on varName done here. Will be done on perform
664 TransactionRdExtVarFreeStyleCreate *ret(new TransactionRdExtVarFreeStyleCreate(this,varName,constValue,compareFuncContent));
665 CORBA::Object_var obj(ret->activate());
666 return SALOME::Transaction::_narrow(obj);
669 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
671 checkNotAlreadyExistingVar(varName);
672 TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
673 CORBA::Object_var obj(ret->activate());
674 return SALOME::Transaction::_narrow(obj);
677 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
679 checkNotAlreadyExistingVar(varName);
680 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
681 CORBA::Object_var obj(ret->activate());
682 return SALOME::Transaction::_narrow(obj);
685 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
688 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
689 _waiting_keys.push_back(kw);
692 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
695 // this part does nothing except to be sure that in notify key all will be OK.
696 PyObject *args(PyTuple_New(1));
697 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
698 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
700 PyObject *waitKey((*it)->getKeyPyObj());
701 PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__"));
704 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
705 throw Exception(oss.str());
707 PyObject *res(PyObject_CallObject(meth,args));
711 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
712 throw Exception(oss.str());
717 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
718 throw Exception(oss.str());
725 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
728 PyObject *args(PyTuple_New(1));
729 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
730 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
731 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
733 if((*it)->getVarName()!=varName)
735 newList.push_back(*it);
738 PyObject *waitKey((*it)->getKeyPyObj());
739 PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__"));
742 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
743 throw Exception(oss.str());
745 PyObject *res(PyObject_CallObject(meth,args));
747 if(!PyBool_Check(res))
749 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
750 throw Exception(oss.str());
754 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
755 throw Exception(oss.str());
758 listOfEltToWakeUp.push_back(*it);
760 newList.push_back(*it);
764 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
765 (*it)->valueJustCome(valueObj);
766 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
768 _waiting_keys=newList;
771 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
773 checkVarExistingAndDict(varName);
774 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
775 CORBA::Object_var obj(ret->activate());
776 return SALOME::Transaction::_narrow(obj);
779 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
781 checkVarExistingAndDict(varName);
782 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
783 CORBA::Object_var obj(ret->activate());
784 return SALOME::Transaction::_narrow(obj);
787 SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
789 checkVarExistingAndDict(varName);
790 TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
791 CORBA::Object_var obj(ret->activate());
792 return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
795 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
797 checkVarExistingAndDict(varName);
798 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
799 CORBA::Object_var obj(ret->activate());
800 return SALOME::Transaction::_narrow(obj);
803 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
805 std::string varNameCpp(varName);
806 checkNotAlreadyExistingVar(varName);
807 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
808 CORBA::Object_var obj(tmp->activate());
809 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
812 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
813 CORBA::Object_var obj2(ret->activate());
814 return SALOME::TransactionRdWrAccess::_narrow(obj2);
817 SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
819 std::string varNameCpp(varName);
820 checkExistingVar(varNameCpp);
822 TransactionKillVar *ret(new TransactionKillVar(this,varName));
823 CORBA::Object_var obj2(ret->activate());
824 return SALOME::Transaction::_narrow(obj2);
827 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
829 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
830 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
831 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
832 return SALOME::KeyWaiter::_narrow(obj);
835 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
837 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
838 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
839 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
841 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
842 CORBA::Object_var obj2(ret1->activate());
843 transac=SALOME::Transaction::_narrow(obj2);
845 return SALOME::KeyWaiter::_narrow(obj);
848 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
850 PortableServer::ServantBase *ret(0);
853 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
855 catch(...) { ret=0; }
856 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
858 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
859 retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
860 SALOME::ByteVec *zeRet(retc->waitForMonoThr());
861 retc->enforcedRelease();
865 SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw)
867 PortableServer::ServantBase *ret(0);
870 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
872 catch(...) { ret=0; }
873 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
875 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
876 retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
877 SALOME::ByteVec *zeRet(retc->waitForAndKill());
878 retc->enforcedRelease();
882 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
884 std::size_t sz(transactions.length());
887 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
888 for(std::size_t i=0;i<sz;i++)
890 PortableServer::ServantBase *eltBase(0);
894 eltBase=_poa->reference_to_servant(transactions[(CORBA::ULong)i]); //!< TODO: size_t to CORBA::ULong
895 elt=dynamic_cast<Transaction *>(eltBase);
899 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
900 throw Exception(oss.str());
904 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
905 throw Exception(oss.str());
908 transactionsCpp[i]=elt;
910 {// important do not merge loops !
911 std::vector<TrustTransaction> transactions2(sz);
912 bool mustRollback(true);
913 for(std::size_t i=0;i<sz;i++)
914 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
915 for(std::size_t i=0;i<sz;i++)
916 transactions2[i].operate();
919 for(std::size_t i=0;i<sz;i++)
920 transactionsCpp[i]->notify();
923 DataScopeServerTransaction::~DataScopeServerTransaction()
927 SALOME::RequestSwitcher_ptr DataScopeServerTransaction::getRequestSwitcher()
931 _rs=new RequestSwitcher(_orb,this);
933 CORBA::Object_var obj(_rs->activate());
934 return SALOME::RequestSwitcher::_narrow(obj);