1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, 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.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 #if PY_VERSION_HEX < 0x03050000
51 Py_EncodeLocale(const wchar_t *arg, size_t *size)
53 return _Py_wchar2char(arg, size);
56 Py_DecodeLocale(const char *arg, size_t *size)
58 return _Py_char2wchar(arg, size);
62 void DataScopeKiller::shutdown()
68 RequestSwitcher::RequestSwitcher(CORBA::ORB_ptr orb)
70 CORBA::Object_var obj(orb->resolve_initial_references("RootPOA"));
71 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
72 _poa_manager_under_control=poa->the_POAManager();
74 CORBA::PolicyList policies;
76 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
77 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
78 // all is in PortableServer::POAManager::_nil. By specifying _nil cf Advanced CORBA Programming with C++ p 506
79 // a new POA manager is created. This POA manager is independent from POA manager of the son ones.
80 _poa_for_request_control=poa->create_POA("4RqstSwitcher",PortableServer::POAManager::_nil(),policies);
82 PortableServer::POAManager_var mgr(_poa_for_request_control->the_POAManager());
84 //obj=orb->resolve_initial_references ("POACurrent");// agy : usage of POACurrent breaks the hold_requests. Why ?
85 //PortableServer::Current_var current(PortableServer::Current::_narrow(obj));
88 void RequestSwitcher::holdRequests()
90 _poa_manager_under_control->hold_requests(true);
93 void RequestSwitcher::activeRequests()
95 _poa_manager_under_control->activate();
98 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)
102 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
106 DataScopeServerBase::~DataScopeServerBase()
108 // _globals is borrowed ref -> do nothing
110 Py_XDECREF(_pickler);
111 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
113 BasicDataServer *obj((*it).second);
122 * Called remotely -> to protect against throw
124 void DataScopeServerBase::ping()
129 * Called remotely -> to protect against throw
131 char *DataScopeServerBase::getScopeName()
133 return CORBA::string_dup(_name.c_str());
137 * Called remotely -> to protect against throw
139 SALOME::StringVec *DataScopeServerBase::listVars()
141 SALOME::StringVec *ret(new SALOME::StringVec);
142 std::size_t sz(_vars.size());
144 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
145 for(std::size_t i=0;i<sz;it++,i++)
147 BasicDataServer *obj((*it).second);
148 std::string name(obj->getVarNameCpp());
149 (*ret)[i]=CORBA::string_dup(name.c_str());
154 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
156 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
157 for(;it!=_vars.end();it++)
158 if((*it).second->getVarNameCpp()==varName)
163 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
165 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
166 return SALOME::BasicDataServer::_duplicate((*it0).first);
169 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
171 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
172 return (*it0).second;
175 void DataScopeServerBase::deleteVar(const char *varName)
177 std::string varNameCpp(varName);
178 std::vector<std::string> allNames(getAllVarNames());
179 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
180 if(it==allNames.end())
182 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
183 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
184 throw Exception(oss.str());
186 std::size_t pos(std::distance(allNames.begin(),it));
187 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
188 for(std::size_t ii=0;ii<pos;ii++,it0++);
189 (*it0).second->decrRef();
193 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
195 SALOME_NamingService ns(_orb);
196 CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
197 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
198 if(CORBA::is_nil(dsm))
199 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
200 // destroy ref in the naming service
201 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
202 ns.Destroy_Name(fullScopeName.c_str());
203 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
204 PortableServer::ServantBase *ret(0);
207 ret=_poa->reference_to_servant(dsm);
209 catch(...) { ret=0; }
214 killer=SALOME::DataScopeKiller::_duplicate(_killer);
221 killer=SALOME::DataScopeKiller::_duplicate(_killer);
226 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
228 BasicDataServer *var(retrieveVarInternal2(varName));
229 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
232 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
233 throw Exception(oss.str());
235 return varc->fetchSerializedContent();
238 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
240 BasicDataServer *var(retrieveVarInternal2(varName));
241 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
244 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
245 throw Exception(oss.str());
249 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
250 throw Exception(oss.str());
252 PyObject *keys(PyDict_Keys(varc->getPyObj()));
253 if(!PyList_Check(keys))
255 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
256 throw Exception(oss.str());
258 Py_ssize_t sz(PyList_Size(keys));
259 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
261 for(Py_ssize_t i=0;i<sz;i++)
263 PyObject *item(PyList_GetItem(keys,i));
265 std::string pickel(varc->pickelize(item));//item consumed
266 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
272 SALOME::RequestSwitcher_ptr DataScopeServerBase::getRequestSwitcher()
276 _rs=new RequestSwitcher(_orb);
278 CORBA::Object_var obj(_rs->activate());
279 return SALOME::RequestSwitcher::_narrow(obj);
282 void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
284 if(napDurationInSec<0.)
285 throw Exception("DataScopeServerBase::takeANap : negative value !");
287 struct timespec req,rem;
288 long nbSec((long)napDurationInSec);
289 double remainTime(napDurationInSec-(double)nbSec);
291 req.tv_nsec=(long)(remainTime*1000000.);
292 int ret(nanosleep(&req,&rem));
294 throw Exception("DataScopeServerBase::takeANap : nap not finished as expected !");
296 throw Exception("DataScopeServerBase::takeANap : not implemented for Windows !");
300 void DataScopeServerBase::initializePython(int argc, char *argv[])
303 PyEval_InitThreads();
304 wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
305 for (int i = 0; i < argc; i++)
306 changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
307 PySys_SetArgv(argc, changed_argv);
308 PyObject *mainmod(PyImport_AddModule("__main__"));
309 _globals=PyModule_GetDict(mainmod);
310 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
312 PyObject *bimod(PyImport_ImportModule("__builtin__"));
313 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
314 Py_FatalError("can't add __builtins__ to __main__");
317 _locals=PyDict_New();
318 PyObject *tmp(PyList_New(0));
319 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
322 void DataScopeServerBase::registerToSalomePiDict() const
324 PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
327 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
329 { Py_XDECREF(mod); return ; }
330 PyObject *args(PyTuple_New(2));
331 PyTuple_SetItem(args,0,PyLong_FromLong(getpid()));
332 PyTuple_SetItem(args,1,PyUnicode_FromString("SALOME_DataScopeServerBase"));
333 PyObject *res(PyObject_CallObject(meth,args));
340 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
345 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
347 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
348 SALOME_NamingService ns(_orb);
349 ns.Register(ptr,fullScopeName.c_str());
352 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
354 std::ostringstream oss;
355 oss << varName << "@" << COUNTER++;
359 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
361 std::size_t sz(_vars.size());
362 std::vector<std::string> ret(sz);
363 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
364 for(std::size_t i=0;i<sz;it++,i++)
365 ret[i]=(*it).second->getVarNameCpp();
369 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
371 std::vector<std::string> allNames(getAllVarNames());
372 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
373 if(it!=allNames.end())
375 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
376 throw Exception(oss.str());
380 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
382 std::vector<std::string> allNames(getAllVarNames());
383 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
384 if(it==allNames.end())
386 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
387 throw Exception(oss.str());
391 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
393 checkExistingVar(varName);
394 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
395 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
398 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
399 throw Exception(oss.str());
403 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
404 throw Exception(oss.str());
409 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
411 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
412 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
413 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
415 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
416 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
417 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
418 CORBA::Object_var obj(newVar->activate());
419 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
420 p.first=obj2; p.second=newVar;
424 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
426 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
427 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
428 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
430 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
431 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
432 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
433 CORBA::Object_var obj(newVar->activate());
434 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
435 p.first=obj2; p.second=newVar;
439 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
441 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
442 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
443 PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
444 PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
446 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
449 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
450 PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
451 newVar->incrNbClients();
452 CORBA::Object_var obj(newVar->activate());
453 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
454 p.first=obj2; p.second=newVar;
458 varc1->incrNbClients();
461 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName)
463 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
464 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
465 PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
466 PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
468 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
471 if(varc0->decrNbClients())
473 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
474 PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
475 CORBA::Object_var obj(newVar->activate());
476 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
477 p.first=obj2; p.second=newVar;
483 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
485 std::vector<std::string> allNames(getAllVarNames());
486 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
487 if(it==allNames.end())
489 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
490 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
491 throw Exception(oss.str());
493 std::size_t pos(std::distance(allNames.begin(),it));
494 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
495 for(std::size_t i=0;i<pos;i++,it0++);
499 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
501 std::vector<std::string> allNames(getAllVarNames());
502 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
503 if(it==allNames.end())
505 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
506 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
507 throw Exception(oss.str());
509 std::size_t pos(std::distance(allNames.begin(),it));
510 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
511 for(std::size_t i=0;i<pos;i++,it0++);
517 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
521 DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
525 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
527 std::string varNameCpp(varName);
528 checkNotAlreadyExistingVar(varNameCpp);
529 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
530 CORBA::Object_var ret(tmp->activate());
531 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
533 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
536 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
538 std::string varNameCpp(varName);
539 checkNotAlreadyExistingVar(varNameCpp);
540 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
541 CORBA::Object_var ret(tmp->activate());
542 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
544 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
547 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
549 std::string varNameCpp(varName),typeNameCpp(typeName);
550 checkNotAlreadyExistingVar(varNameCpp);
551 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
552 CORBA::Object_var ret(tmp->activate());
553 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
555 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
558 DataScopeServer::~DataScopeServer()
564 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
566 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
567 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
569 PortableServer::POAManager_var mgr(poa->the_POAManager());
570 CORBA::PolicyList policies;
572 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
573 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
574 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
575 threadPol->destroy();
577 _poa_for_key_waiter=poa2;
580 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
584 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
586 std::string varNameCpp(varName);
587 checkExistingVar(varNameCpp);
588 BasicDataServer *var(retrieveVarInternal2(varName));
590 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
591 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
593 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
594 std::string ret(varc->getAccessStr());
595 return CORBA::string_dup(ret.c_str());
599 * This method is here to retrieve atomically accessStr and picklization.
601 void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
603 access=getAccessOfVar(varName);
604 data=fetchSerializedContent(varName);
607 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
609 checkNotAlreadyExistingVar(varName);
610 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
611 CORBA::Object_var ret(tmp->activate());
612 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
616 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
618 checkNotAlreadyExistingVar(varName);
619 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
620 CORBA::Object_var ret(tmp->activate());
621 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
625 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
627 checkNotAlreadyExistingVar(varName);
628 PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
629 CORBA::Object_var ret(tmp->activate());
630 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
634 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
636 checkNotAlreadyExistingVar(varName);
637 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
638 CORBA::Object_var ret(tmp->activate());
639 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
643 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
645 checkNotAlreadyExistingVar(varName);
646 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
647 CORBA::Object_var obj(ret->activate());
648 return SALOME::Transaction::_narrow(obj);
651 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
653 checkNotAlreadyExistingVar(varName);
654 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
655 CORBA::Object_var obj(ret->activate());
656 return SALOME::Transaction::_narrow(obj);
659 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
661 checkNotAlreadyExistingVar(varName);
662 TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
663 CORBA::Object_var obj(ret->activate());
664 return SALOME::Transaction::_narrow(obj);
667 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
669 checkNotAlreadyExistingVar(varName);
670 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
671 CORBA::Object_var obj(ret->activate());
672 return SALOME::Transaction::_narrow(obj);
675 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
678 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
679 _waiting_keys.push_back(kw);
682 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
685 // this part does nothing except to be sure that in notify key all will be OK.
686 PyObject *args(PyTuple_New(1));
687 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
688 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
690 PyObject *waitKey((*it)->getKeyPyObj());
691 PyObject *meth(PyObject_GetAttrString(keyObj,"__eq__"));
694 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
695 throw Exception(oss.str());
697 PyObject *res(PyObject_CallObject(meth,args));
701 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
702 throw Exception(oss.str());
707 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
708 throw Exception(oss.str());
715 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
718 PyObject *args(PyTuple_New(1));
719 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
720 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
721 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
723 if((*it)->getVarName()!=varName)
725 newList.push_back(*it);
728 PyObject *waitKey((*it)->getKeyPyObj());
729 PyObject *meth(PyObject_GetAttrString(keyObj,"__eq__"));
732 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
733 throw Exception(oss.str());
735 PyObject *res(PyObject_CallObject(meth,args));
737 if(!PyBool_Check(res))
739 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !";
740 throw Exception(oss.str());
744 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
745 throw Exception(oss.str());
748 listOfEltToWakeUp.push_back(*it);
750 newList.push_back(*it);
754 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
755 (*it)->valueJustCome(valueObj);
756 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
758 _waiting_keys=newList;
761 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
763 checkVarExistingAndDict(varName);
764 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
765 CORBA::Object_var obj(ret->activate());
766 return SALOME::Transaction::_narrow(obj);
769 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
771 checkVarExistingAndDict(varName);
772 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
773 CORBA::Object_var obj(ret->activate());
774 return SALOME::Transaction::_narrow(obj);
777 SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
779 checkVarExistingAndDict(varName);
780 TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
781 CORBA::Object_var obj(ret->activate());
782 return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
785 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
787 checkVarExistingAndDict(varName);
788 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
789 CORBA::Object_var obj(ret->activate());
790 return SALOME::Transaction::_narrow(obj);
793 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
795 std::string varNameCpp(varName);
796 checkNotAlreadyExistingVar(varName);
797 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
798 CORBA::Object_var obj(tmp->activate());
799 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
802 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
803 CORBA::Object_var obj2(ret->activate());
804 return SALOME::TransactionRdWrAccess::_narrow(obj2);
807 SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
809 std::string varNameCpp(varName);
810 checkExistingVar(varNameCpp);
812 TransactionKillVar *ret(new TransactionKillVar(this,varName));
813 CORBA::Object_var obj2(ret->activate());
814 return SALOME::Transaction::_narrow(obj2);
817 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
819 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
820 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
821 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
822 return SALOME::KeyWaiter::_narrow(obj);
825 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
827 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
828 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
829 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
831 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
832 CORBA::Object_var obj2(ret1->activate());
833 transac=SALOME::Transaction::_narrow(obj2);
835 return SALOME::KeyWaiter::_narrow(obj);
838 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
840 PortableServer::ServantBase *ret(0);
843 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
845 catch(...) { ret=0; }
846 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
848 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
849 retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
850 SALOME::ByteVec *zeRet(retc->waitForMonoThr());
851 retc->enforcedRelease();
855 SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw)
857 PortableServer::ServantBase *ret(0);
860 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
862 catch(...) { ret=0; }
863 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
865 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
866 retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
867 SALOME::ByteVec *zeRet(retc->waitForAndKill());
868 retc->enforcedRelease();
872 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
874 std::size_t sz(transactions.length());
877 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
878 for(std::size_t i=0;i<sz;i++)
880 PortableServer::ServantBase *eltBase(0);
884 eltBase=_poa->reference_to_servant(transactions[i]);
885 elt=dynamic_cast<Transaction *>(eltBase);
889 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
890 throw Exception(oss.str());
894 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
895 throw Exception(oss.str());
898 transactionsCpp[i]=elt;
900 {// important do not merge loops !
901 std::vector<TrustTransaction> transactions2(sz);
902 bool mustRollback(true);
903 for(std::size_t i=0;i<sz;i++)
904 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
905 for(std::size_t i=0;i<sz;i++)
906 transactions2[i].operate();
909 for(std::size_t i=0;i<sz;i++)
910 transactionsCpp[i]->notify();
913 DataScopeServerTransaction::~DataScopeServerTransaction()