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 void DataScopeKiller::shutdown()
55 RequestSwitcher::RequestSwitcher(CORBA::ORB_ptr orb, DataScopeServerBase *ds):_ds(ds)
57 CORBA::Object_var obj(orb->resolve_initial_references("RootPOA"));
58 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
59 _poa_manager_under_control=poa->the_POAManager();
61 CORBA::PolicyList policies;
63 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
64 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
65 // all is in PortableServer::POAManager::_nil. By specifying _nil cf Advanced CORBA Programming with C++ p 506
66 // a new POA manager is created. This POA manager is independent from POA manager of the son ones.
67 _poa_for_request_control=poa->create_POA("4RqstSwitcher",PortableServer::POAManager::_nil(),policies);
69 PortableServer::POAManager_var mgr(_poa_for_request_control->the_POAManager());
71 //obj=orb->resolve_initial_references ("POACurrent");// agy : usage of POACurrent breaks the hold_requests. Why ?
72 //PortableServer::Current_var current(PortableServer::Current::_narrow(obj));
75 void RequestSwitcher::holdRequests()
77 _poa_manager_under_control->hold_requests(true);
80 void RequestSwitcher::activeRequests()
82 _poa_manager_under_control->activate();
85 SALOME::StringVec *RequestSwitcher::listVars()
87 return _ds->listVars();
90 SALOME::ByteVec *RequestSwitcher::fetchSerializedContent(const char *varName)
92 return _ds->fetchSerializedContent(varName);
95 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)
99 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
103 DataScopeServerBase::~DataScopeServerBase()
105 // _globals is borrowed ref -> do nothing
107 Py_XDECREF(_pickler);
108 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
110 BasicDataServer *obj((*it).second);
119 * Called remotely -> to protect against throw
121 void DataScopeServerBase::ping()
126 * Called remotely -> to protect against throw
128 char *DataScopeServerBase::getScopeName()
130 return CORBA::string_dup(_name.c_str());
134 * Called remotely -> to protect against throw
136 SALOME::StringVec *DataScopeServerBase::listVars()
138 SALOME::StringVec *ret(new SALOME::StringVec);
139 std::size_t sz(_vars.size());
141 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
142 for(std::size_t i=0;i<sz;it++,i++)
144 BasicDataServer *obj((*it).second);
145 std::string name(obj->getVarNameCpp());
146 (*ret)[i]=CORBA::string_dup(name.c_str());
151 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
153 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
154 for(;it!=_vars.end();it++)
155 if((*it).second->getVarNameCpp()==varName)
160 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
162 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
163 return SALOME::BasicDataServer::_duplicate((*it0).first);
166 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
168 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
169 return (*it0).second;
172 void DataScopeServerBase::deleteVar(const char *varName)
174 std::string varNameCpp(varName);
175 std::vector<std::string> allNames(getAllVarNames());
176 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
177 if(it==allNames.end())
179 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
180 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
181 throw Exception(oss.str());
183 std::size_t pos(std::distance(allNames.begin(),it));
184 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
185 for(std::size_t ii=0;ii<pos;ii++,it0++);
186 (*it0).second->decrRef();
190 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
192 SALOME_NamingService ns(_orb);
193 CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
194 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
195 if(CORBA::is_nil(dsm))
196 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
197 // destroy ref in the naming service
198 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
199 ns.Destroy_Name(fullScopeName.c_str());
200 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
201 PortableServer::ServantBase *ret(0);
204 ret=_poa->reference_to_servant(dsm);
206 catch(...) { ret=0; }
211 killer=SALOME::DataScopeKiller::_duplicate(_killer);
218 killer=SALOME::DataScopeKiller::_duplicate(_killer);
223 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
225 BasicDataServer *var(retrieveVarInternal2(varName));
226 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
229 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
230 throw Exception(oss.str());
232 return varc->fetchSerializedContent();
235 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
237 BasicDataServer *var(retrieveVarInternal2(varName));
238 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
241 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
242 throw Exception(oss.str());
246 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
247 throw Exception(oss.str());
249 PyObject *keys(PyDict_Keys(varc->getPyObj()));
250 if(!PyList_Check(keys))
252 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
253 throw Exception(oss.str());
255 Py_ssize_t sz(PyList_Size(keys));
256 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
258 for(Py_ssize_t i=0;i<sz;i++)
260 PyObject *item(PyList_GetItem(keys,i));
262 std::string pickel(varc->pickelize(item));//item consumed
263 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
269 SALOME::RequestSwitcher_ptr DataScopeServerBase::getRequestSwitcher()
273 _rs=new RequestSwitcher(_orb,this);
275 CORBA::Object_var obj(_rs->activate());
276 return SALOME::RequestSwitcher::_narrow(obj);
279 void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
281 if(napDurationInSec<0.)
282 throw Exception("DataScopeServerBase::takeANap : negative value !");
284 struct timespec req,rem;
285 long nbSec((long)napDurationInSec);
286 double remainTime(napDurationInSec-(double)nbSec);
288 req.tv_nsec=(long)(remainTime*1000000.);
289 int ret(nanosleep(&req,&rem));
291 throw Exception("DataScopeServerBase::takeANap : nap not finished as expected !");
293 throw Exception("DataScopeServerBase::takeANap : not implemented for Windows !");
297 void DataScopeServerBase::initializePython(int argc, char *argv[])
300 PyEval_InitThreads();
301 PySys_SetArgv(argc,argv);
302 PyObject *mainmod(PyImport_AddModule("__main__"));
303 _globals=PyModule_GetDict(mainmod);
304 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
306 PyObject *bimod(PyImport_ImportModule("__builtin__"));
307 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
308 Py_FatalError("can't add __builtins__ to __main__");
311 _locals=PyDict_New();
312 PyObject *tmp(PyList_New(0));
313 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
316 void DataScopeServerBase::registerToSalomePiDict() const
318 PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
321 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
323 { Py_XDECREF(mod); return ; }
324 PyObject *args(PyTuple_New(2));
325 PyTuple_SetItem(args,0,PyInt_FromLong(getpid()));
326 PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServerBase"));
327 PyObject *res(PyObject_CallObject(meth,args));
334 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
339 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
341 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
342 SALOME_NamingService ns(_orb);
343 ns.Register(ptr,fullScopeName.c_str());
346 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
348 std::ostringstream oss;
349 oss << varName << "@" << COUNTER++;
353 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
355 std::size_t sz(_vars.size());
356 std::vector<std::string> ret(sz);
357 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
358 for(std::size_t i=0;i<sz;it++,i++)
359 ret[i]=(*it).second->getVarNameCpp();
363 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
365 std::vector<std::string> allNames(getAllVarNames());
366 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
367 if(it!=allNames.end())
369 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
370 throw Exception(oss.str());
374 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
376 std::vector<std::string> allNames(getAllVarNames());
377 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
378 if(it==allNames.end())
380 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
381 throw Exception(oss.str());
385 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
387 checkExistingVar(varName);
388 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
389 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
392 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
393 throw Exception(oss.str());
397 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
398 throw Exception(oss.str());
403 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
405 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
406 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
407 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
409 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
410 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
411 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
412 CORBA::Object_var obj(newVar->activate());
413 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
414 p.first=obj2; p.second=newVar;
418 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
420 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
421 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
422 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
424 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
425 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
426 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
427 CORBA::Object_var obj(newVar->activate());
428 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
429 p.first=obj2; p.second=newVar;
433 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
435 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
436 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
437 PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
438 PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
440 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
443 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
444 PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
445 newVar->incrNbClients();
446 CORBA::Object_var obj(newVar->activate());
447 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
448 p.first=obj2; p.second=newVar;
452 varc1->incrNbClients();
455 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName)
457 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
458 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
459 PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
460 PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
462 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
465 if(varc0->decrNbClients())
467 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
468 PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
469 CORBA::Object_var obj(newVar->activate());
470 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
471 p.first=obj2; p.second=newVar;
477 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
479 std::vector<std::string> allNames(getAllVarNames());
480 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
481 if(it==allNames.end())
483 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
484 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
485 throw Exception(oss.str());
487 std::size_t pos(std::distance(allNames.begin(),it));
488 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
489 for(std::size_t i=0;i<pos;i++,it0++);
493 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
495 std::vector<std::string> allNames(getAllVarNames());
496 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
497 if(it==allNames.end())
499 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
500 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
501 throw Exception(oss.str());
503 std::size_t pos(std::distance(allNames.begin(),it));
504 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
505 for(std::size_t i=0;i<pos;i++,it0++);
511 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
515 DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
519 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
521 std::string varNameCpp(varName);
522 checkNotAlreadyExistingVar(varNameCpp);
523 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
524 CORBA::Object_var ret(tmp->activate());
525 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
527 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
530 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
532 std::string varNameCpp(varName);
533 checkNotAlreadyExistingVar(varNameCpp);
534 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
535 CORBA::Object_var ret(tmp->activate());
536 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
538 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
541 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
543 std::string varNameCpp(varName),typeNameCpp(typeName);
544 checkNotAlreadyExistingVar(varNameCpp);
545 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
546 CORBA::Object_var ret(tmp->activate());
547 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
549 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
552 DataScopeServer::~DataScopeServer()
558 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
560 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
561 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
563 PortableServer::POAManager_var mgr(poa->the_POAManager());
564 CORBA::PolicyList policies;
566 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
567 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
568 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
569 threadPol->destroy();
571 _poa_for_key_waiter=poa2;
574 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
578 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
580 std::string varNameCpp(varName);
581 checkExistingVar(varNameCpp);
582 BasicDataServer *var(retrieveVarInternal2(varName));
584 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
585 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
587 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
588 std::string ret(varc->getAccessStr());
589 return CORBA::string_dup(ret.c_str());
593 * This method is here to retrieve atomically accessStr and picklization.
595 void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
597 access=getAccessOfVar(varName);
598 data=fetchSerializedContent(varName);
601 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
603 checkNotAlreadyExistingVar(varName);
604 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
605 CORBA::Object_var ret(tmp->activate());
606 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
610 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
612 checkNotAlreadyExistingVar(varName);
613 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
614 CORBA::Object_var ret(tmp->activate());
615 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
619 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
621 checkNotAlreadyExistingVar(varName);
622 PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
623 CORBA::Object_var ret(tmp->activate());
624 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
628 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
630 checkNotAlreadyExistingVar(varName);
631 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
632 CORBA::Object_var ret(tmp->activate());
633 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
637 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
639 checkNotAlreadyExistingVar(varName);
640 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
641 CORBA::Object_var obj(ret->activate());
642 return SALOME::Transaction::_narrow(obj);
645 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
647 checkNotAlreadyExistingVar(varName);
648 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
649 CORBA::Object_var obj(ret->activate());
650 return SALOME::Transaction::_narrow(obj);
653 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
655 checkNotAlreadyExistingVar(varName);
656 TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
657 CORBA::Object_var obj(ret->activate());
658 return SALOME::Transaction::_narrow(obj);
661 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
663 checkNotAlreadyExistingVar(varName);
664 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
665 CORBA::Object_var obj(ret->activate());
666 return SALOME::Transaction::_narrow(obj);
669 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
672 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
673 _waiting_keys.push_back(kw);
676 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
678 PyObject *cmpObj(getPyCmpFunc());
680 throw Exception("ataScopeServerTransaction::pingKey : Key Object is NULL !");
681 PyObject *args(PyTuple_New(2));
682 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
684 // this part does nothing except to be sure that in notify key all will be OK.
685 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
687 PyObject *waitKey((*it)->getKeyPyObj());
688 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
689 PyObject *res(PyObject_CallObject(cmpObj,args));
692 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
693 throw Exception(oss.str());
698 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
699 throw Exception(oss.str());
705 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
707 PyObject *cmpObj(getPyCmpFunc());
709 throw Exception("DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! Key Object is NULL !");
710 PyObject *args(PyTuple_New(2));
711 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
713 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
714 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
716 if((*it)->getVarName()!=varName)
718 newList.push_back(*it);
721 PyObject *waitKey((*it)->getKeyPyObj());
722 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
723 PyObject *res(PyObject_CallObject(cmpObj,args));
726 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
727 throw Exception(oss.str());
729 long resCpp(PyInt_AsLong(res));
732 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
733 throw Exception(oss.str());
737 listOfEltToWakeUp.push_back(*it);
739 newList.push_back(*it);
741 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
742 (*it)->valueJustCome(valueObj);
743 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
745 _waiting_keys=newList;
748 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
750 checkVarExistingAndDict(varName);
751 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
752 CORBA::Object_var obj(ret->activate());
753 return SALOME::Transaction::_narrow(obj);
756 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
758 checkVarExistingAndDict(varName);
759 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
760 CORBA::Object_var obj(ret->activate());
761 return SALOME::Transaction::_narrow(obj);
764 SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
766 checkVarExistingAndDict(varName);
767 TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
768 CORBA::Object_var obj(ret->activate());
769 return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
772 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
774 checkVarExistingAndDict(varName);
775 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
776 CORBA::Object_var obj(ret->activate());
777 return SALOME::Transaction::_narrow(obj);
780 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
782 std::string varNameCpp(varName);
783 checkNotAlreadyExistingVar(varName);
784 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
785 CORBA::Object_var obj(tmp->activate());
786 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
789 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
790 CORBA::Object_var obj2(ret->activate());
791 return SALOME::TransactionRdWrAccess::_narrow(obj2);
794 SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
796 std::string varNameCpp(varName);
797 checkExistingVar(varNameCpp);
799 TransactionKillVar *ret(new TransactionKillVar(this,varName));
800 CORBA::Object_var obj2(ret->activate());
801 return SALOME::Transaction::_narrow(obj2);
804 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
806 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
807 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
808 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
809 return SALOME::KeyWaiter::_narrow(obj);
812 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
814 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
815 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
816 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
818 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
819 CORBA::Object_var obj2(ret1->activate());
820 transac=SALOME::Transaction::_narrow(obj2);
822 return SALOME::KeyWaiter::_narrow(obj);
825 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
827 PortableServer::ServantBase *ret(0);
830 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
832 catch(...) { ret=0; }
833 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
835 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
836 retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
837 SALOME::ByteVec *zeRet(retc->waitForMonoThr());
838 retc->enforcedRelease();
842 SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw)
844 PortableServer::ServantBase *ret(0);
847 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
849 catch(...) { ret=0; }
850 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
852 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
853 retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
854 SALOME::ByteVec *zeRet(retc->waitForAndKill());
855 retc->enforcedRelease();
859 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
861 std::size_t sz(transactions.length());
864 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
865 for(std::size_t i=0;i<sz;i++)
867 PortableServer::ServantBase *eltBase(0);
871 eltBase=_poa->reference_to_servant(transactions[i]);
872 elt=dynamic_cast<Transaction *>(eltBase);
876 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
877 throw Exception(oss.str());
881 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
882 throw Exception(oss.str());
885 transactionsCpp[i]=elt;
887 {// important do not merge loops !
888 std::vector<TrustTransaction> transactions2(sz);
889 bool mustRollback(true);
890 for(std::size_t i=0;i<sz;i++)
891 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
892 for(std::size_t i=0;i<sz;i++)
893 transactions2[i].operate();
896 for(std::size_t i=0;i<sz;i++)
897 transactionsCpp[i]->notify();
901 * Returns borrowed reference.
903 PyObject *DataScopeServerTransaction::getPyCmpFunc()
905 PyObject *builtins(PyDict_GetItemString(_globals,"__builtins__"));//borrowed
907 throw Exception("Fail to find reference to builtins !");
908 PyObject *builtins2(PyModule_GetDict(builtins));//borrowed
910 throw Exception("Fail to invoke __dict__ on builtins !");
911 PyObject *cmpObj(PyDict_GetItemString(builtins2,"cmp"));
913 throw Exception("Fail to find cmp in __builtins__ !");
917 DataScopeServerTransaction::~DataScopeServerTransaction()