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 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)
72 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
76 DataScopeServerBase::~DataScopeServerBase()
78 // _globals is borrowed ref -> do nothing
81 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
83 BasicDataServer *obj((*it).second);
92 * Called remotely -> to protect against throw
94 void DataScopeServerBase::ping()
99 * Called remotely -> to protect against throw
101 char *DataScopeServerBase::getScopeName()
103 return CORBA::string_dup(_name.c_str());
107 * Called remotely -> to protect against throw
109 SALOME::StringVec *DataScopeServerBase::listVars()
111 SALOME::StringVec *ret(new SALOME::StringVec);
112 std::size_t sz(_vars.size());
114 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
115 for(std::size_t i=0;i<sz;it++,i++)
117 BasicDataServer *obj((*it).second);
118 std::string name(obj->getVarNameCpp());
119 (*ret)[i]=CORBA::string_dup(name.c_str());
124 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
126 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
127 for(;it!=_vars.end();it++)
128 if((*it).second->getVarNameCpp()==varName)
133 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
135 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
136 return SALOME::BasicDataServer::_duplicate((*it0).first);
139 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
141 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
142 return (*it0).second;
145 void DataScopeServerBase::deleteVar(const char *varName)
147 std::string varNameCpp(varName);
148 std::vector<std::string> allNames(getAllVarNames());
149 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
150 if(it==allNames.end())
152 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
153 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
154 throw Exception(oss.str());
156 std::size_t pos(std::distance(allNames.begin(),it));
157 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
158 for(std::size_t ii=0;ii<pos;ii++,it0++);
159 (*it0).second->decrRef();
163 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
165 SALOME_NamingService ns(_orb);
166 CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
167 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
168 if(CORBA::is_nil(dsm))
169 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
170 // destroy ref in the naming service
171 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
172 ns.Destroy_Name(fullScopeName.c_str());
173 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
174 PortableServer::ServantBase *ret(0);
177 ret=_poa->reference_to_servant(dsm);
179 catch(...) { ret=0; }
184 killer=SALOME::DataScopeKiller::_duplicate(_killer);
191 killer=SALOME::DataScopeKiller::_duplicate(_killer);
196 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
198 BasicDataServer *var(retrieveVarInternal2(varName));
199 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
202 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
203 throw Exception(oss.str());
205 return varc->fetchSerializedContent();
208 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
210 BasicDataServer *var(retrieveVarInternal2(varName));
211 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
214 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
215 throw Exception(oss.str());
219 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
220 throw Exception(oss.str());
222 PyObject *keys(PyDict_Keys(varc->getPyObj()));
223 if(!PyList_Check(keys))
225 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
226 throw Exception(oss.str());
228 Py_ssize_t sz(PyList_Size(keys));
229 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
231 for(Py_ssize_t i=0;i<sz;i++)
233 PyObject *item(PyList_GetItem(keys,i));
235 std::string pickel(varc->pickelize(item));//item consumed
236 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
242 void DataScopeServerBase::initializePython(int argc, char *argv[])
245 PyEval_InitThreads();
246 wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments
247 for (int i = 0; i < argc; i++)
248 changed_argv[i] = Py_DecodeLocale(argv[i], NULL);
249 PySys_SetArgv(argc, changed_argv);
250 PyObject *mainmod(PyImport_AddModule("__main__"));
251 _globals=PyModule_GetDict(mainmod);
252 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
254 PyObject *bimod(PyImport_ImportModule("__builtin__"));
255 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
256 Py_FatalError("can't add __builtins__ to __main__");
259 _locals=PyDict_New();
260 PyObject *tmp(PyList_New(0));
261 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
264 void DataScopeServerBase::registerToSalomePiDict() const
266 PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
269 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
271 { Py_XDECREF(mod); return ; }
272 PyObject *args(PyTuple_New(2));
273 PyTuple_SetItem(args,0,PyLong_FromLong(getpid()));
274 PyTuple_SetItem(args,1,PyUnicode_FromString("SALOME_DataScopeServerBase"));
275 PyObject *res(PyObject_CallObject(meth,args));
282 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
287 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
289 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
290 SALOME_NamingService ns(_orb);
291 ns.Register(ptr,fullScopeName.c_str());
294 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
296 std::ostringstream oss;
297 oss << varName << "@" << COUNTER++;
301 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
303 std::size_t sz(_vars.size());
304 std::vector<std::string> ret(sz);
305 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
306 for(std::size_t i=0;i<sz;it++,i++)
307 ret[i]=(*it).second->getVarNameCpp();
311 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
313 std::vector<std::string> allNames(getAllVarNames());
314 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
315 if(it!=allNames.end())
317 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
318 throw Exception(oss.str());
322 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
324 std::vector<std::string> allNames(getAllVarNames());
325 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
326 if(it==allNames.end())
328 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
329 throw Exception(oss.str());
333 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
335 checkExistingVar(varName);
336 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
337 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
340 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
341 throw Exception(oss.str());
345 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
346 throw Exception(oss.str());
351 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
353 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
354 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
355 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
357 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
358 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
359 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
360 CORBA::Object_var obj(newVar->activate());
361 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
362 p.first=obj2; p.second=newVar;
366 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
368 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
369 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
370 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
372 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
373 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
374 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
375 CORBA::Object_var obj(newVar->activate());
376 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
377 p.first=obj2; p.second=newVar;
381 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
383 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
384 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
385 PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
386 PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
388 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
391 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
392 PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
393 newVar->incrNbClients();
394 CORBA::Object_var obj(newVar->activate());
395 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
396 p.first=obj2; p.second=newVar;
400 varc1->incrNbClients();
403 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(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 PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
408 PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
410 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
413 if(varc0->decrNbClients())
415 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
416 PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
417 CORBA::Object_var obj(newVar->activate());
418 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
419 p.first=obj2; p.second=newVar;
425 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
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::retrieveVarInternal3 : 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 * > >::const_iterator it0(_vars.begin());
437 for(std::size_t i=0;i<pos;i++,it0++);
441 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
443 std::vector<std::string> allNames(getAllVarNames());
444 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
445 if(it==allNames.end())
447 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
448 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
449 throw Exception(oss.str());
451 std::size_t pos(std::distance(allNames.begin(),it));
452 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
453 for(std::size_t i=0;i<pos;i++,it0++);
459 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
463 DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
467 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
469 std::string varNameCpp(varName);
470 checkNotAlreadyExistingVar(varNameCpp);
471 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
472 CORBA::Object_var ret(tmp->activate());
473 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
475 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
478 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
480 std::string varNameCpp(varName);
481 checkNotAlreadyExistingVar(varNameCpp);
482 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
483 CORBA::Object_var ret(tmp->activate());
484 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
486 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
489 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
491 std::string varNameCpp(varName),typeNameCpp(typeName);
492 checkNotAlreadyExistingVar(varNameCpp);
493 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
494 CORBA::Object_var ret(tmp->activate());
495 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
497 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
500 DataScopeServer::~DataScopeServer()
506 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
508 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
509 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
511 PortableServer::POAManager_var mgr(poa->the_POAManager());
512 CORBA::PolicyList policies;
514 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
515 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
516 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
517 threadPol->destroy();
519 _poa_for_key_waiter=poa2;
522 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
526 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
528 std::string varNameCpp(varName);
529 checkExistingVar(varNameCpp);
530 BasicDataServer *var(retrieveVarInternal2(varName));
532 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
533 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
535 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
536 std::string ret(varc->getAccessStr());
537 return CORBA::string_dup(ret.c_str());
541 * This method is here to retrieve atomically accessStr and picklization.
543 void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
545 access=getAccessOfVar(varName);
546 data=fetchSerializedContent(varName);
549 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
551 checkNotAlreadyExistingVar(varName);
552 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
553 CORBA::Object_var ret(tmp->activate());
554 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
558 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
560 checkNotAlreadyExistingVar(varName);
561 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
562 CORBA::Object_var ret(tmp->activate());
563 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
567 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
569 checkNotAlreadyExistingVar(varName);
570 PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
571 CORBA::Object_var ret(tmp->activate());
572 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
576 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
578 checkNotAlreadyExistingVar(varName);
579 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
580 CORBA::Object_var ret(tmp->activate());
581 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
585 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
587 checkNotAlreadyExistingVar(varName);
588 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
589 CORBA::Object_var obj(ret->activate());
590 return SALOME::Transaction::_narrow(obj);
593 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
595 checkNotAlreadyExistingVar(varName);
596 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
597 CORBA::Object_var obj(ret->activate());
598 return SALOME::Transaction::_narrow(obj);
601 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
603 checkNotAlreadyExistingVar(varName);
604 TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
605 CORBA::Object_var obj(ret->activate());
606 return SALOME::Transaction::_narrow(obj);
609 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
611 checkNotAlreadyExistingVar(varName);
612 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
613 CORBA::Object_var obj(ret->activate());
614 return SALOME::Transaction::_narrow(obj);
617 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
620 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
621 _waiting_keys.push_back(kw);
624 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
627 // this part does nothing except to be sure that in notify key all will be OK.
628 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
630 PyObject *waitKey((*it)->getKeyPyObj());
631 PyObject *res(PyObject_CallMethodObjArgs(keyObj, PyUnicode_DecodeASCII("__ne__", 6, NULL), waitKey));
634 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
635 throw Exception(oss.str());
637 PyLong_AsLong(res); // res is bool, but it s ok since __int__ is called
640 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
641 throw Exception(oss.str());
647 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
650 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
651 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
653 if((*it)->getVarName()!=varName)
655 newList.push_back(*it);
658 PyObject *waitKey((*it)->getKeyPyObj());
659 PyObject *res(PyObject_CallMethodObjArgs(keyObj, PyUnicode_DecodeASCII("__ne__", 6, NULL), waitKey));
662 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
663 throw Exception(oss.str());
665 long resCpp(PyLong_AsLong(res)); // res is bool, but it s ok since __int__ is called
668 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
669 throw Exception(oss.str());
673 listOfEltToWakeUp.push_back(*it);
675 newList.push_back(*it);
677 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
678 (*it)->valueJustCome(valueObj);
679 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
681 _waiting_keys=newList;
684 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
686 checkVarExistingAndDict(varName);
687 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
688 CORBA::Object_var obj(ret->activate());
689 return SALOME::Transaction::_narrow(obj);
692 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
694 checkVarExistingAndDict(varName);
695 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
696 CORBA::Object_var obj(ret->activate());
697 return SALOME::Transaction::_narrow(obj);
700 SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
702 checkVarExistingAndDict(varName);
703 TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
704 CORBA::Object_var obj(ret->activate());
705 return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
708 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
710 checkVarExistingAndDict(varName);
711 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
712 CORBA::Object_var obj(ret->activate());
713 return SALOME::Transaction::_narrow(obj);
716 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
718 std::string varNameCpp(varName);
719 checkNotAlreadyExistingVar(varName);
720 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
721 CORBA::Object_var obj(tmp->activate());
722 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
725 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
726 CORBA::Object_var obj2(ret->activate());
727 return SALOME::TransactionRdWrAccess::_narrow(obj2);
730 SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
732 std::string varNameCpp(varName);
733 checkExistingVar(varNameCpp);
735 TransactionKillVar *ret(new TransactionKillVar(this,varName));
736 CORBA::Object_var obj2(ret->activate());
737 return SALOME::Transaction::_narrow(obj2);
740 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
742 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
743 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
744 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
745 return SALOME::KeyWaiter::_narrow(obj);
748 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
750 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
751 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
752 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
754 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
755 CORBA::Object_var obj2(ret1->activate());
756 transac=SALOME::Transaction::_narrow(obj2);
758 return SALOME::KeyWaiter::_narrow(obj);
761 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
763 PortableServer::ServantBase *ret(0);
766 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
768 catch(...) { ret=0; }
769 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
771 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
772 retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
773 SALOME::ByteVec *zeRet(retc->waitForMonoThr());
774 retc->enforcedRelease();
778 SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw)
780 PortableServer::ServantBase *ret(0);
783 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
785 catch(...) { ret=0; }
786 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
788 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
789 retc->_remove_ref();// restore the counter afer _poa_for_key_waiter->reference_to_servant(kw)
790 SALOME::ByteVec *zeRet(retc->waitForAndKill());
791 retc->enforcedRelease();
795 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
797 std::size_t sz(transactions.length());
800 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
801 for(std::size_t i=0;i<sz;i++)
803 PortableServer::ServantBase *eltBase(0);
807 eltBase=_poa->reference_to_servant(transactions[i]);
808 elt=dynamic_cast<Transaction *>(eltBase);
812 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
813 throw Exception(oss.str());
817 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
818 throw Exception(oss.str());
821 transactionsCpp[i]=elt;
823 {// important do not merge loops !
824 std::vector<TrustTransaction> transactions2(sz);
825 bool mustRollback(true);
826 for(std::size_t i=0;i<sz;i++)
827 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
828 for(std::size_t i=0;i<sz;i++)
829 transactions2[i].operate();
832 for(std::size_t i=0;i<sz;i++)
833 transactionsCpp[i]->notify();
836 DataScopeServerTransaction::~DataScopeServerTransaction()