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 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)
59 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
63 DataScopeServerBase::~DataScopeServerBase()
65 // _globals is borrowed ref -> do nothing
68 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
70 BasicDataServer *obj((*it).second);
79 * Called remotely -> to protect against throw
81 void DataScopeServerBase::ping()
86 * Called remotely -> to protect against throw
88 char *DataScopeServerBase::getScopeName()
90 return CORBA::string_dup(_name.c_str());
94 * Called remotely -> to protect against throw
96 SALOME::StringVec *DataScopeServerBase::listVars()
98 SALOME::StringVec *ret(new SALOME::StringVec);
99 std::size_t sz(_vars.size());
101 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
102 for(std::size_t i=0;i<sz;it++,i++)
104 BasicDataServer *obj((*it).second);
105 std::string name(obj->getVarNameCpp());
106 (*ret)[i]=CORBA::string_dup(name.c_str());
111 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
113 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
114 for(;it!=_vars.end();it++)
115 if((*it).second->getVarNameCpp()==varName)
120 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
122 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
123 return SALOME::BasicDataServer::_duplicate((*it0).first);
126 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
128 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
129 return (*it0).second;
132 void DataScopeServerBase::deleteVar(const char *varName)
134 std::string varNameCpp(varName);
135 std::vector<std::string> allNames(getAllVarNames());
136 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
137 if(it==allNames.end())
139 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
140 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
141 throw Exception(oss.str());
143 std::size_t pos(std::distance(allNames.begin(),it));
144 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
145 for(std::size_t ii=0;ii<pos;ii++,it0++);
146 (*it0).second->decrRef();
150 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
152 SALOME_NamingService ns(_orb);
153 CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
154 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
155 if(CORBA::is_nil(dsm))
156 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
157 // destroy ref in the naming service
158 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
159 ns.Destroy_Name(fullScopeName.c_str());
160 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
161 PortableServer::ServantBase *ret(0);
164 ret=_poa->reference_to_servant(dsm);
166 catch(...) { ret=0; }
171 killer=SALOME::DataScopeKiller::_duplicate(_killer);
178 killer=SALOME::DataScopeKiller::_duplicate(_killer);
183 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
185 BasicDataServer *var(retrieveVarInternal2(varName));
186 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
189 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
190 throw Exception(oss.str());
192 return varc->fetchSerializedContent();
195 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
197 BasicDataServer *var(retrieveVarInternal2(varName));
198 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
201 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
202 throw Exception(oss.str());
206 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
207 throw Exception(oss.str());
209 PyObject *keys(PyDict_Keys(varc->getPyObj()));
210 if(!PyList_Check(keys))
212 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
213 throw Exception(oss.str());
215 Py_ssize_t sz(PyList_Size(keys));
216 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
218 for(Py_ssize_t i=0;i<sz;i++)
220 PyObject *item(PyList_GetItem(keys,i));
222 std::string pickel(varc->pickelize(item));//item consumed
223 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
229 void DataScopeServerBase::initializePython(int argc, char *argv[])
232 PyEval_InitThreads();
233 PySys_SetArgv(argc,argv);
234 PyObject *mainmod(PyImport_AddModule("__main__"));
235 _globals=PyModule_GetDict(mainmod);
236 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
238 PyObject *bimod(PyImport_ImportModule("__builtin__"));
239 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
240 Py_FatalError("can't add __builtins__ to __main__");
243 _locals=PyDict_New();
244 PyObject *tmp(PyList_New(0));
245 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
248 void DataScopeServerBase::registerToSalomePiDict() const
250 PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
253 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
255 { Py_XDECREF(mod); return ; }
256 PyObject *args(PyTuple_New(2));
257 PyTuple_SetItem(args,0,PyInt_FromLong(getpid()));
258 PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServerBase"));
259 PyObject *res(PyObject_CallObject(meth,args));
266 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
271 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
273 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
274 SALOME_NamingService ns(_orb);
275 ns.Register(ptr,fullScopeName.c_str());
278 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
280 std::ostringstream oss;
281 oss << varName << "@" << COUNTER++;
285 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
287 std::size_t sz(_vars.size());
288 std::vector<std::string> ret(sz);
289 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
290 for(std::size_t i=0;i<sz;it++,i++)
291 ret[i]=(*it).second->getVarNameCpp();
295 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
297 std::vector<std::string> allNames(getAllVarNames());
298 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
299 if(it!=allNames.end())
301 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
302 throw Exception(oss.str());
306 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
308 std::vector<std::string> allNames(getAllVarNames());
309 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
310 if(it==allNames.end())
312 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
313 throw Exception(oss.str());
317 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
319 checkExistingVar(varName);
320 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
321 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
324 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
325 throw Exception(oss.str());
329 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
330 throw Exception(oss.str());
335 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
337 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
338 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
339 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
341 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
342 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
343 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
344 CORBA::Object_var obj(newVar->activate());
345 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
346 p.first=obj2; p.second=newVar;
350 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
352 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
353 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
354 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
356 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
357 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
358 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
359 CORBA::Object_var obj(newVar->activate());
360 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
361 p.first=obj2; p.second=newVar;
365 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
367 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
368 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
369 PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
370 PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
372 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
375 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
376 PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
377 newVar->incrNbClients();
378 CORBA::Object_var obj(newVar->activate());
379 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
380 p.first=obj2; p.second=newVar;
384 varc1->incrNbClients();
387 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName)
389 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
390 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
391 PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
392 PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
394 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
397 if(varc0->decrNbClients())
399 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
400 PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
401 CORBA::Object_var obj(newVar->activate());
402 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
403 p.first=obj2; p.second=newVar;
409 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
411 std::vector<std::string> allNames(getAllVarNames());
412 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
413 if(it==allNames.end())
415 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
416 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
417 throw Exception(oss.str());
419 std::size_t pos(std::distance(allNames.begin(),it));
420 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
421 for(std::size_t i=0;i<pos;i++,it0++);
425 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
427 std::vector<std::string> allNames(getAllVarNames());
428 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
429 if(it==allNames.end())
431 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
432 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
433 throw Exception(oss.str());
435 std::size_t pos(std::distance(allNames.begin(),it));
436 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
437 for(std::size_t i=0;i<pos;i++,it0++);
443 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
447 DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
451 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
453 std::string varNameCpp(varName);
454 checkNotAlreadyExistingVar(varNameCpp);
455 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
456 CORBA::Object_var ret(tmp->activate());
457 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
459 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
462 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
464 std::string varNameCpp(varName);
465 checkNotAlreadyExistingVar(varNameCpp);
466 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
467 CORBA::Object_var ret(tmp->activate());
468 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
470 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
473 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
475 std::string varNameCpp(varName),typeNameCpp(typeName);
476 checkNotAlreadyExistingVar(varNameCpp);
477 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
478 CORBA::Object_var ret(tmp->activate());
479 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
481 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
484 DataScopeServer::~DataScopeServer()
490 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
492 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
493 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
495 PortableServer::POAManager_var mgr(poa->the_POAManager());
496 CORBA::PolicyList policies;
498 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
499 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
500 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
501 threadPol->destroy();
503 _poa_for_key_waiter=poa2;
506 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
510 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
512 std::string varNameCpp(varName);
513 checkExistingVar(varNameCpp);
514 BasicDataServer *var(retrieveVarInternal2(varName));
516 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
517 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
519 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
520 std::string ret(varc->getAccessStr());
521 return CORBA::string_dup(ret.c_str());
525 * This method is here to retrieve atomically accessStr and picklization.
527 void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
529 access=getAccessOfVar(varName);
530 data=fetchSerializedContent(varName);
533 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
535 checkNotAlreadyExistingVar(varName);
536 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
537 CORBA::Object_var ret(tmp->activate());
538 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
542 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
544 checkNotAlreadyExistingVar(varName);
545 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
546 CORBA::Object_var ret(tmp->activate());
547 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
551 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
553 checkNotAlreadyExistingVar(varName);
554 PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
555 CORBA::Object_var ret(tmp->activate());
556 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
560 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
562 checkNotAlreadyExistingVar(varName);
563 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
564 CORBA::Object_var ret(tmp->activate());
565 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
569 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
571 checkNotAlreadyExistingVar(varName);
572 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
573 CORBA::Object_var obj(ret->activate());
574 return SALOME::Transaction::_narrow(obj);
577 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
579 checkNotAlreadyExistingVar(varName);
580 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
581 CORBA::Object_var obj(ret->activate());
582 return SALOME::Transaction::_narrow(obj);
585 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
587 checkNotAlreadyExistingVar(varName);
588 TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
589 CORBA::Object_var obj(ret->activate());
590 return SALOME::Transaction::_narrow(obj);
593 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
595 checkNotAlreadyExistingVar(varName);
596 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
597 CORBA::Object_var obj(ret->activate());
598 return SALOME::Transaction::_narrow(obj);
601 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
604 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
605 _waiting_keys.push_back(kw);
608 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
610 PyObject *cmpObj(getPyCmpFunc());
612 throw Exception("ataScopeServerTransaction::pingKey : Key Object is NULL !");
613 PyObject *args(PyTuple_New(2));
614 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
616 // this part does nothing except to be sure that in notify key all will be OK.
617 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
619 PyObject *waitKey((*it)->getKeyPyObj());
620 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
621 PyObject *res(PyObject_CallObject(cmpObj,args));
624 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
625 throw Exception(oss.str());
630 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
631 throw Exception(oss.str());
637 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
639 PyObject *cmpObj(getPyCmpFunc());
641 throw Exception("DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! Key Object is NULL !");
642 PyObject *args(PyTuple_New(2));
643 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
645 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
646 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
648 if((*it)->getVarName()!=varName)
650 newList.push_back(*it);
653 PyObject *waitKey((*it)->getKeyPyObj());
654 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
655 PyObject *res(PyObject_CallObject(cmpObj,args));
658 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
659 throw Exception(oss.str());
661 long resCpp(PyInt_AsLong(res));
664 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
665 throw Exception(oss.str());
669 listOfEltToWakeUp.push_back(*it);
671 newList.push_back(*it);
673 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
674 (*it)->valueJustCome(valueObj);
675 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
677 _waiting_keys=newList;
680 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
682 checkVarExistingAndDict(varName);
683 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
684 CORBA::Object_var obj(ret->activate());
685 return SALOME::Transaction::_narrow(obj);
688 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
690 checkVarExistingAndDict(varName);
691 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
692 CORBA::Object_var obj(ret->activate());
693 return SALOME::Transaction::_narrow(obj);
696 SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
698 checkVarExistingAndDict(varName);
699 TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
700 CORBA::Object_var obj(ret->activate());
701 return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
704 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
706 checkVarExistingAndDict(varName);
707 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
708 CORBA::Object_var obj(ret->activate());
709 return SALOME::Transaction::_narrow(obj);
712 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
714 std::string varNameCpp(varName);
715 checkNotAlreadyExistingVar(varName);
716 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
717 CORBA::Object_var obj(tmp->activate());
718 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
721 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
722 CORBA::Object_var obj2(ret->activate());
723 return SALOME::TransactionRdWrAccess::_narrow(obj2);
726 SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
728 std::string varNameCpp(varName);
729 checkExistingVar(varNameCpp);
731 TransactionKillVar *ret(new TransactionKillVar(this,varName));
732 CORBA::Object_var obj2(ret->activate());
733 return SALOME::Transaction::_narrow(obj2);
736 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
738 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
739 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
740 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
741 return SALOME::KeyWaiter::_narrow(obj);
744 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
746 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
747 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
748 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
750 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
751 CORBA::Object_var obj2(ret1->activate());
752 transac=SALOME::Transaction::_narrow(obj2);
754 return SALOME::KeyWaiter::_narrow(obj);
757 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
759 PortableServer::ServantBase *ret(0);
762 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
764 catch(...) { ret=0; }
765 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
767 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
768 retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
769 SALOME::ByteVec *zeRet(retc->waitForMonoThr());
770 retc->enforcedRelease();
774 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
776 std::size_t sz(transactions.length());
779 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
780 for(std::size_t i=0;i<sz;i++)
782 PortableServer::ServantBase *eltBase(0);
786 eltBase=_poa->reference_to_servant(transactions[i]);
787 elt=dynamic_cast<Transaction *>(eltBase);
791 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
792 throw Exception(oss.str());
796 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
797 throw Exception(oss.str());
800 transactionsCpp[i]=elt;
802 {// important do not merge loops !
803 std::vector<TrustTransaction> transactions2(sz);
804 bool mustRollback(true);
805 for(std::size_t i=0;i<sz;i++)
806 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
807 for(std::size_t i=0;i<sz;i++)
808 transactions2[i].operate();
811 for(std::size_t i=0;i<sz;i++)
812 transactionsCpp[i]->notify();
816 * Returns borrowed reference.
818 PyObject *DataScopeServerTransaction::getPyCmpFunc()
820 PyObject *builtins(PyDict_GetItemString(_globals,"__builtins__"));//borrowed
822 throw Exception("Fail to find reference to builtins !");
823 PyObject *builtins2(PyModule_GetDict(builtins));//borrowed
825 throw Exception("Fail to invoke __dict__ on builtins !");
826 PyObject *cmpObj(PyDict_GetItemString(builtins2,"cmp"));
828 throw Exception("Fail to find cmp in __builtins__ !");
832 DataScopeServerTransaction::~DataScopeServerTransaction()