1 // Copyright (C) 2007-2015 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_KeyWaiter.hxx"
27 #include "SALOMESDS_Transaction.hxx"
28 #include "SALOME_NamingService.hxx"
29 #include "SALOMESDS_Exception.hxx"
35 // agy : awful, to be factorized with ContainerManager.
40 #define getpid _getpid
43 using namespace SALOMESDS;
45 std::size_t DataScopeServerBase::COUNTER=0;
47 void DataScopeKiller::shutdown()
53 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)
57 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
61 DataScopeServerBase::~DataScopeServerBase()
63 // _globals is borrowed ref -> do nothing
66 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
68 BasicDataServer *obj((*it).second);
77 * Called remotely -> to protect against throw
79 void DataScopeServerBase::ping()
84 * Called remotely -> to protect against throw
86 char *DataScopeServerBase::getScopeName()
88 return CORBA::string_dup(_name.c_str());
92 * Called remotely -> to protect against throw
94 SALOME::StringVec *DataScopeServerBase::listVars()
96 SALOME::StringVec *ret(new SALOME::StringVec);
97 std::size_t sz(_vars.size());
99 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
100 for(std::size_t i=0;i<sz;it++,i++)
102 BasicDataServer *obj((*it).second);
103 std::string name(obj->getVarNameCpp());
104 (*ret)[i]=CORBA::string_dup(name.c_str());
109 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
111 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
112 for(;it!=_vars.end();it++)
113 if((*it).second->getVarNameCpp()==varName)
118 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
120 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
121 return SALOME::BasicDataServer::_duplicate((*it0).first);
124 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
126 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
127 return (*it0).second;
130 void DataScopeServerBase::deleteVar(const char *varName)
132 std::string varNameCpp(varName);
133 std::vector<std::string> allNames(getAllVarNames());
134 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
135 if(it==allNames.end())
137 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
138 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
139 throw Exception(oss.str());
141 std::size_t pos(std::distance(allNames.begin(),it));
142 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
143 for(std::size_t ii=0;ii<pos;ii++,it0++);
144 (*it0).second->decrRef();
148 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
150 SALOME_NamingService ns(_orb);
151 CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
152 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
153 if(CORBA::is_nil(dsm))
154 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
155 // destroy ref in the naming service
156 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
157 ns.Destroy_Name(fullScopeName.c_str());
158 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
159 PortableServer::ServantBase *ret(0);
162 ret=_poa->reference_to_servant(dsm);
164 catch(...) { ret=0; }
169 killer=SALOME::DataScopeKiller::_duplicate(_killer);
176 killer=SALOME::DataScopeKiller::_duplicate(_killer);
181 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
183 BasicDataServer *var(retrieveVarInternal2(varName));
184 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
187 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
188 throw Exception(oss.str());
190 return varc->fetchSerializedContent();
193 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
195 BasicDataServer *var(retrieveVarInternal2(varName));
196 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
199 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
200 throw Exception(oss.str());
204 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
205 throw Exception(oss.str());
207 PyObject *keys(PyDict_Keys(varc->getPyObj()));
208 if(!PyList_Check(keys))
210 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
211 throw Exception(oss.str());
213 Py_ssize_t sz(PyList_Size(keys));
214 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
216 for(Py_ssize_t i=0;i<sz;i++)
218 PyObject *item(PyList_GetItem(keys,i));
220 std::string pickel(varc->pickelize(item));//item consumed
221 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
227 void DataScopeServerBase::initializePython(int argc, char *argv[])
230 PyEval_InitThreads();
231 PySys_SetArgv(argc,argv);
232 PyObject *mainmod(PyImport_AddModule("__main__"));
233 _globals=PyModule_GetDict(mainmod);
234 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
236 PyObject *bimod(PyImport_ImportModule("__builtin__"));
237 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
238 Py_FatalError("can't add __builtins__ to __main__");
241 _locals=PyDict_New();
242 PyObject *tmp(PyList_New(0));
243 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
246 void DataScopeServerBase::registerToSalomePiDict() const
248 PyObject *mod(PyImport_ImportModule("addToKillList"));
251 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));
253 { Py_XDECREF(mod); return ; }
254 PyObject *args(PyTuple_New(2));
255 PyTuple_SetItem(args,0,PyInt_FromLong(getpid()));
256 PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServerBase"));
257 PyObject *res(PyObject_CallObject(meth,args));
263 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
268 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
270 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
271 SALOME_NamingService ns(_orb);
272 ns.Register(ptr,fullScopeName.c_str());
275 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
277 std::ostringstream oss;
278 oss << varName << "@" << COUNTER++;
282 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
284 std::size_t sz(_vars.size());
285 std::vector<std::string> ret(sz);
286 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
287 for(std::size_t i=0;i<sz;it++,i++)
288 ret[i]=(*it).second->getVarNameCpp();
292 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
294 std::vector<std::string> allNames(getAllVarNames());
295 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
296 if(it!=allNames.end())
298 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
299 throw Exception(oss.str());
303 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
305 std::vector<std::string> allNames(getAllVarNames());
306 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
307 if(it==allNames.end())
309 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
310 throw Exception(oss.str());
314 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
316 checkExistingVar(varName);
317 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
318 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
321 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
322 throw Exception(oss.str());
326 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
327 throw Exception(oss.str());
332 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
334 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
335 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
336 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
338 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
339 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
340 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
341 CORBA::Object_var obj(newVar->activate());
342 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
343 p.first=obj2; p.second=newVar;
347 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(const std::string& varName)
349 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
350 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
351 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
353 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
354 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
355 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
356 CORBA::Object_var obj(newVar->activate());
357 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
358 p.first=obj2; p.second=newVar;
362 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
364 std::vector<std::string> allNames(getAllVarNames());
365 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
366 if(it==allNames.end())
368 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
369 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
370 throw Exception(oss.str());
372 std::size_t pos(std::distance(allNames.begin(),it));
373 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
374 for(std::size_t i=0;i<pos;i++,it0++);
378 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
380 std::vector<std::string> allNames(getAllVarNames());
381 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
382 if(it==allNames.end())
384 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
385 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
386 throw Exception(oss.str());
388 std::size_t pos(std::distance(allNames.begin(),it));
389 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
390 for(std::size_t i=0;i<pos;i++,it0++);
396 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
400 DataScopeServer::DataScopeServer(const DataScopeServer& other):DataScopeServerBase(other)
404 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
406 std::string varNameCpp(varName);
407 checkNotAlreadyExistingVar(varNameCpp);
408 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
409 CORBA::Object_var ret(tmp->activate());
410 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
412 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
415 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
417 std::string varNameCpp(varName);
418 checkNotAlreadyExistingVar(varNameCpp);
419 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
420 CORBA::Object_var ret(tmp->activate());
421 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
423 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
426 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
428 std::string varNameCpp(varName),typeNameCpp(typeName);
429 checkNotAlreadyExistingVar(varNameCpp);
430 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
431 CORBA::Object_var ret(tmp->activate());
432 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
434 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
437 DataScopeServer::~DataScopeServer()
443 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
445 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
446 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
448 PortableServer::POAManager_var mgr(poa->the_POAManager());
449 CORBA::PolicyList policies;
451 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
452 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
453 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
454 threadPol->destroy();
456 _poa_for_key_waiter=poa2;
459 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
463 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
465 std::string varNameCpp(varName);
466 checkExistingVar(varNameCpp);
467 BasicDataServer *var(retrieveVarInternal2(varName));
469 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
470 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
472 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
473 std::string ret(varc->getAccessStr());
474 return CORBA::string_dup(ret.c_str());
477 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
479 checkNotAlreadyExistingVar(varName);
480 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
481 CORBA::Object_var ret(tmp->activate());
482 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
486 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
488 checkNotAlreadyExistingVar(varName);
489 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
490 CORBA::Object_var ret(tmp->activate());
491 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
495 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
497 checkNotAlreadyExistingVar(varName);
498 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
499 CORBA::Object_var ret(tmp->activate());
500 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
504 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
506 checkNotAlreadyExistingVar(varName);
507 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
508 CORBA::Object_var obj(ret->activate());
509 return SALOME::Transaction::_narrow(obj);
512 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
514 checkNotAlreadyExistingVar(varName);
515 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
516 CORBA::Object_var obj(ret->activate());
517 return SALOME::Transaction::_narrow(obj);
520 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
522 checkNotAlreadyExistingVar(varName);
523 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
524 CORBA::Object_var obj(ret->activate());
525 return SALOME::Transaction::_narrow(obj);
528 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
531 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
532 _waiting_keys.push_back(kw);
535 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
537 PyObject *cmpObj(getPyCmpFunc());
539 throw Exception("ataScopeServerTransaction::pingKey : Key Object is NULL !");
540 PyObject *args(PyTuple_New(2));
541 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
543 // this part does nothing except to be sure that in notify key all will be OK.
544 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
546 PyObject *waitKey((*it)->getKeyPyObj());
547 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
548 PyObject *res(PyObject_CallObject(cmpObj,args));
551 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
552 throw Exception(oss.str());
557 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
558 throw Exception(oss.str());
564 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
566 PyObject *cmpObj(getPyCmpFunc());
568 throw Exception("DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! Key Object is NULL !");
569 PyObject *args(PyTuple_New(2));
570 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
572 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
573 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
575 if((*it)->getVarName()!=varName)
577 newList.push_back(*it);
580 PyObject *waitKey((*it)->getKeyPyObj());
581 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
582 PyObject *res(PyObject_CallObject(cmpObj,args));
585 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
586 throw Exception(oss.str());
588 long resCpp(PyInt_AsLong(res));
591 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
592 throw Exception(oss.str());
596 listOfEltToWakeUp.push_back(*it);
598 newList.push_back(*it);
600 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
601 (*it)->valueJustCome(valueObj);
602 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
604 _waiting_keys=newList;
607 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
609 checkVarExistingAndDict(varName);
610 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
611 CORBA::Object_var obj(ret->activate());
612 return SALOME::Transaction::_narrow(obj);
615 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
617 checkVarExistingAndDict(varName);
618 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
619 CORBA::Object_var obj(ret->activate());
620 return SALOME::Transaction::_narrow(obj);
623 class TrustTransaction
626 TrustTransaction():_must_rollback(0),_ptr(0) { }
627 void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); }
628 void operate() { _ptr->perform(); }
629 ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); }
631 bool *_must_rollback;
635 void DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExistingNow(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
637 checkVarExistingAndDict(varName);
638 TransactionAddKeyValueErrorIfAlreadyExisting ret(this,varName,key,value);
640 bool mustRollback(true);
642 t.setTransaction(&ret,&mustRollback);
648 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
650 checkVarExistingAndDict(varName);
651 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
652 CORBA::Object_var obj(ret->activate());
653 return SALOME::Transaction::_narrow(obj);
656 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
658 std::string varNameCpp(varName);
659 checkNotAlreadyExistingVar(varName);
660 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
661 CORBA::Object_var obj(tmp->activate());
662 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
665 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
666 CORBA::Object_var obj2(ret->activate());
667 return SALOME::TransactionRdWrAccess::_narrow(obj2);
670 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
672 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
673 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
674 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
675 return SALOME::KeyWaiter::_narrow(obj);
678 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
680 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
681 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
682 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
684 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
685 CORBA::Object_var obj2(ret1->activate());
686 transac=SALOME::Transaction::_narrow(obj2);
688 return SALOME::KeyWaiter::_narrow(obj);
691 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
693 PortableServer::ServantBase *ret(0);
696 ret=_poa_for_key_waiter->reference_to_servant(kw);
698 catch(...) { ret=0; }
699 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
701 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
703 retc->waitForMonoThr();
706 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
708 std::size_t sz(transactions.length());
711 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
712 for(std::size_t i=0;i<sz;i++)
714 PortableServer::ServantBase *eltBase(0);
718 eltBase=_poa->reference_to_servant(transactions[i]);
719 elt=dynamic_cast<Transaction *>(eltBase);
723 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
724 throw Exception(oss.str());
728 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
729 throw Exception(oss.str());
732 transactionsCpp[i]=elt;
734 {// important do not merge loops !
735 std::vector<TrustTransaction> transactions2(sz);
736 bool mustRollback(true);
737 for(std::size_t i=0;i<sz;i++)
738 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
739 for(std::size_t i=0;i<sz;i++)
740 transactions2[i].operate();
743 for(std::size_t i=0;i<sz;i++)
744 transactionsCpp[i]->notify();
748 * Returns borrowed reference.
750 PyObject *DataScopeServerTransaction::getPyCmpFunc()
752 PyObject *builtins(PyDict_GetItemString(_globals,"__builtins__"));//borrowed
754 throw Exception("Fail to find reference to builtins !");
755 PyObject *builtins2(PyModule_GetDict(builtins));//borrowed
757 throw Exception("Fail to invoke __dict__ on builtins !");
758 PyObject *cmpObj(PyDict_GetItemString(builtins2,"cmp"));
760 throw Exception("Fail to find cmp in __builtins__ !");
764 DataScopeServerTransaction::~DataScopeServerTransaction()