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, DataScopeServerTransaction *ds):RequestSwitcherBase(orb),_ds(ds)
59 SALOME::StringVec *RequestSwitcher::listVars()
61 return _ds->listVars();
64 SALOME::ByteVec *RequestSwitcher::fetchSerializedContent(const char *varName)
66 return _ds->fetchSerializedContent(varName);
69 void RequestSwitcher::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
71 return _ds->fetchAndGetAccessOfVar(varName,access,data);
74 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)
78 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):omniServant(other),ServantBase(other),_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars),_killer(other._killer)
82 DataScopeServerBase::~DataScopeServerBase()
84 // _globals is borrowed ref -> do nothing
87 for(std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it=_vars.begin();it!=_vars.end();it++)
89 BasicDataServer *obj((*it).second);
98 * Called remotely -> to protect against throw
100 void DataScopeServerBase::ping()
105 * Called remotely -> to protect against throw
107 char *DataScopeServerBase::getScopeName()
109 return CORBA::string_dup(_name.c_str());
113 * Called remotely -> to protect against throw
115 SALOME::StringVec *DataScopeServerBase::listVars()
117 SALOME::StringVec *ret(new SALOME::StringVec);
118 std::size_t sz(_vars.size());
120 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(_vars.begin());
121 for(std::size_t i=0;i<sz;it++,i++)
123 BasicDataServer *obj((*it).second);
124 std::string name(obj->getVarNameCpp());
125 (*ret)[i]=CORBA::string_dup(name.c_str());
130 CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
132 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
133 for(;it!=_vars.end();it++)
134 if((*it).second->getVarNameCpp()==varName)
139 SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
141 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
142 return SALOME::BasicDataServer::_duplicate((*it0).first);
145 BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
147 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
148 return (*it0).second;
151 void DataScopeServerBase::deleteVar(const char *varName)
153 std::string varNameCpp(varName);
154 std::vector<std::string> allNames(getAllVarNames());
155 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
156 if(it==allNames.end())
158 std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
159 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
160 throw Exception(oss.str());
162 std::size_t pos(std::distance(allNames.begin(),it));
163 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
164 for(std::size_t ii=0;ii<pos;ii++,it0++);
165 (*it0).second->decrRef();
169 CORBA::Boolean DataScopeServerBase::shutdownIfNotHostedByDSM(SALOME::DataScopeKiller_out killer)
171 SALOME_NamingService ns(_orb);
172 CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
173 SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(obj));
174 if(CORBA::is_nil(dsm))
175 throw Exception("Unable to reach in the NS the unique DataServerManager instance of the Session !");
176 // destroy ref in the naming service
177 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
178 ns.Destroy_Name(fullScopeName.c_str());
179 // establish if dsm and this shared the same POA. If yes dsm and this are collocated !
180 PortableServer::ServantBase *ret(0);
183 ret=_poa->reference_to_servant(dsm);
185 catch(...) { ret=0; }
190 killer=SALOME::DataScopeKiller::_duplicate(_killer);
197 killer=SALOME::DataScopeKiller::_duplicate(_killer);
202 SALOME::ByteVec *DataScopeServerBase::fetchSerializedContent(const char *varName)
204 BasicDataServer *var(retrieveVarInternal2(varName));
205 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
208 std::ostringstream oss; oss << "DataScopeServerBase::fetchSerializedContent : var \"" << varName << "\" exists but it is not serialized !";
209 throw Exception(oss.str());
211 return varc->fetchSerializedContent();
214 SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const char *varName)
216 BasicDataServer *var(retrieveVarInternal2(varName));
217 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
220 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not serialized !";
221 throw Exception(oss.str());
225 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" exists but it is not a PyDict !";
226 throw Exception(oss.str());
228 PyObject *keys(PyDict_Keys(varc->getPyObj()));
229 if(!PyList_Check(keys))
231 std::ostringstream oss; oss << "DataScopeServerBase::getAllKeysOfVarWithTypeDict : var \"" << varName << "\" has keys but not of type list !";
232 throw Exception(oss.str());
234 Py_ssize_t sz(PyList_Size(keys));
235 SALOME::SeqOfByteVec *ret(new SALOME::SeqOfByteVec);
237 for(Py_ssize_t i=0;i<sz;i++)
239 PyObject *item(PyList_GetItem(keys,i));
241 std::string pickel(varc->pickelize(item));//item consumed
242 PickelizedPyObjServer::FromCppToByteSeq(pickel,(*ret)[i]);
248 void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec)
250 if(napDurationInSec<0.)
251 throw Exception("DataScopeServerBase::takeANap : negative value !");
253 struct timespec req,rem;
254 long nbSec((long)napDurationInSec);
255 double remainTime(napDurationInSec-(double)nbSec);
257 req.tv_nsec=(long)(remainTime*1000000.);
258 int ret(nanosleep(&req,&rem));
260 throw Exception("DataScopeServerBase::takeANap : nap not finished as expected !");
262 throw Exception("DataScopeServerBase::takeANap : not implemented for Windows !");
266 void DataScopeServerBase::initializePython(int argc, char *argv[])
269 PyEval_InitThreads();
270 PySys_SetArgv(argc,argv);
271 PyObject *mainmod(PyImport_AddModule("__main__"));
272 _globals=PyModule_GetDict(mainmod);
273 if(PyDict_GetItemString(_globals, "__builtins__") == NULL)
275 PyObject *bimod(PyImport_ImportModule("__builtin__"));
276 if (bimod == NULL || PyDict_SetItemString(_globals, "__builtins__", bimod) != 0)
277 Py_FatalError("can't add __builtins__ to __main__");
280 _locals=PyDict_New();
281 PyObject *tmp(PyList_New(0));
282 _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
285 void DataScopeServerBase::registerToSalomePiDict() const
287 PyObject *mod(PyImport_ImportModule("addToKillList"));//new value
290 PyObject *meth(PyObject_GetAttrString(mod,"addToKillList"));//new value
292 { Py_XDECREF(mod); return ; }
293 PyObject *args(PyTuple_New(2));
294 PyTuple_SetItem(args,0,PyInt_FromLong(getpid()));
295 PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServerBase"));
296 PyObject *res(PyObject_CallObject(meth,args));
303 void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
308 void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
310 std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
311 SALOME_NamingService ns(_orb);
312 ns.Register(ptr,fullScopeName.c_str());
315 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
317 std::ostringstream oss;
318 oss << varName << "@" << COUNTER++;
322 std::vector< std::string > DataScopeServerBase::getAllVarNames() const
324 std::size_t sz(_vars.size());
325 std::vector<std::string> ret(sz);
326 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
327 for(std::size_t i=0;i<sz;it++,i++)
328 ret[i]=(*it).second->getVarNameCpp();
332 void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
334 std::vector<std::string> allNames(getAllVarNames());
335 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
336 if(it!=allNames.end())
338 std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
339 throw Exception(oss.str());
343 void DataScopeServerBase::checkExistingVar(const std::string& varName) const
345 std::vector<std::string> allNames(getAllVarNames());
346 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
347 if(it==allNames.end())
349 std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
350 throw Exception(oss.str());
354 PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
356 checkExistingVar(varName);
357 BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
358 PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
361 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
362 throw Exception(oss.str());
366 std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
367 throw Exception(oss.str());
372 void DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly(const std::string& varName)
374 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
375 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
376 PickelizedPyObjRdWrServer *varc(dynamic_cast<PickelizedPyObjRdWrServer *>(p.second));
378 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdWrToRdOnly : var is not a RdWr !");
379 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
380 PickelizedPyObjRdOnlyServer *newVar(new PickelizedPyObjRdOnlyServer(this,varName,pyobj));
381 CORBA::Object_var obj(newVar->activate());
382 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
383 p.first=obj2; p.second=newVar;
387 void DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr(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 PickelizedPyObjRdOnlyServer *varc(dynamic_cast<PickelizedPyObjRdOnlyServer *>(p.second));
393 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdOnlyToRdWr : var is not a RdWr !");
394 PyObject *pyobj(varc->getPyObj()); Py_XINCREF(pyobj);
395 PickelizedPyObjRdWrServer *newVar(new PickelizedPyObjRdWrServer(this,varName,pyobj));
396 CORBA::Object_var obj(newVar->activate());
397 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
398 p.first=obj2; p.second=newVar;
402 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const std::string& varName)
404 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
405 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
406 PickelizedPyObjRdExtServer *varc0(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
407 PickelizedPyObjRdExtInitServer *varc1(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
409 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !");
412 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
413 PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj));
414 newVar->incrNbClients();
415 CORBA::Object_var obj(newVar->activate());
416 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
417 p.first=obj2; p.second=newVar;
421 varc1->incrNbClients();
424 void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName)
426 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName));
427 std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it);
428 PickelizedPyObjRdExtInitServer *varc0(dynamic_cast<PickelizedPyObjRdExtInitServer *>(p.second));
429 PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(p.second));
431 throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !");
434 if(varc0->decrNbClients())
436 PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj);
437 PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj));
438 CORBA::Object_var obj(newVar->activate());
439 SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj));
440 p.first=obj2; p.second=newVar;
446 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
448 std::vector<std::string> allNames(getAllVarNames());
449 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
450 if(it==allNames.end())
452 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal3 : name \"" << varName << "\" does not exists ! Possibilities are :";
453 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
454 throw Exception(oss.str());
456 std::size_t pos(std::distance(allNames.begin(),it));
457 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
458 for(std::size_t i=0;i<pos;i++,it0++);
462 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator DataScopeServerBase::retrieveVarInternal4(const std::string& varName)
464 std::vector<std::string> allNames(getAllVarNames());
465 std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
466 if(it==allNames.end())
468 std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal4 : name \"" << varName << "\" does not exists ! Possibilities are :";
469 std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
470 throw Exception(oss.str());
472 std::size_t pos(std::distance(allNames.begin(),it));
473 std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
474 for(std::size_t i=0;i<pos;i++,it0++);
480 DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
484 DataScopeServer::DataScopeServer(const DataScopeServer& other):omniServant(other),ServantBase(other),DataScopeServerBase(other)
488 SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
490 std::string varNameCpp(varName);
491 checkNotAlreadyExistingVar(varNameCpp);
492 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
493 CORBA::Object_var ret(tmp->activate());
494 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
496 return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
499 SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
501 std::string varNameCpp(varName);
502 checkNotAlreadyExistingVar(varNameCpp);
503 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
504 CORBA::Object_var ret(tmp->activate());
505 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
507 return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
510 SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
512 std::string varNameCpp(varName),typeNameCpp(typeName);
513 checkNotAlreadyExistingVar(varNameCpp);
514 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
515 CORBA::Object_var ret(tmp->activate());
516 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
518 return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
521 DataScopeServer::~DataScopeServer()
527 DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, SALOME::DataScopeKiller_var killer, const std::string& scopeName):DataScopeServerBase(orb,killer,scopeName)
529 CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
530 PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
532 PortableServer::POAManager_var mgr(poa->the_POAManager());
533 CORBA::PolicyList policies;
535 PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
536 policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
537 PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
538 threadPol->destroy();
540 _poa_for_key_waiter=poa2;
543 DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):omniServant(other),ServantBase(other),DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
547 char *DataScopeServerTransaction::getAccessOfVar(const char *varName)
549 std::string varNameCpp(varName);
550 checkExistingVar(varNameCpp);
551 BasicDataServer *var(retrieveVarInternal2(varName));
553 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is NULL !");
554 PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
556 throw Exception("DataScopeServerTransaction::getAccessOfVar : variable is not of type PickelizedPyObjServer !");
557 std::string ret(varc->getAccessStr());
558 return CORBA::string_dup(ret.c_str());
562 * This method is here to retrieve atomically accessStr and picklization.
564 void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data)
566 access=getAccessOfVar(varName);
567 data=fetchSerializedContent(varName);
570 void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
572 checkNotAlreadyExistingVar(varName);
573 PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
574 CORBA::Object_var ret(tmp->activate());
575 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
579 void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
581 checkNotAlreadyExistingVar(varName);
582 PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
583 CORBA::Object_var ret(tmp->activate());
584 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
588 void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
590 checkNotAlreadyExistingVar(varName);
591 PickelizedPyObjRdExtInitServer *tmp(new PickelizedPyObjRdExtInitServer(this,varName,constValue));
592 CORBA::Object_var ret(tmp->activate());
593 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
597 void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
599 checkNotAlreadyExistingVar(varName);
600 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
601 CORBA::Object_var ret(tmp->activate());
602 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
606 SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
608 checkNotAlreadyExistingVar(varName);
609 TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
610 CORBA::Object_var obj(ret->activate());
611 return SALOME::Transaction::_narrow(obj);
614 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
616 checkNotAlreadyExistingVar(varName);
617 TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
618 CORBA::Object_var obj(ret->activate());
619 return SALOME::Transaction::_narrow(obj);
622 SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue)
624 checkNotAlreadyExistingVar(varName);
625 TransactionRdExtInitVarCreate *ret(new TransactionRdExtInitVarCreate(this,varName,constValue));
626 CORBA::Object_var obj(ret->activate());
627 return SALOME::Transaction::_narrow(obj);
630 SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
632 checkNotAlreadyExistingVar(varName);
633 TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
634 CORBA::Object_var obj(ret->activate());
635 return SALOME::Transaction::_narrow(obj);
638 void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
641 throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
642 _waiting_keys.push_back(kw);
645 void DataScopeServerTransaction::pingKey(PyObject *keyObj)
647 PyObject *cmpObj(getPyCmpFunc());
649 throw Exception("ataScopeServerTransaction::pingKey : Key Object is NULL !");
650 PyObject *args(PyTuple_New(2));
651 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
653 // this part does nothing except to be sure that in notify key all will be OK.
654 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
656 PyObject *waitKey((*it)->getKeyPyObj());
657 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
658 PyObject *res(PyObject_CallObject(cmpObj,args));
661 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !";
662 throw Exception(oss.str());
667 std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
668 throw Exception(oss.str());
674 void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj)
676 PyObject *cmpObj(getPyCmpFunc());
678 throw Exception("DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! Key Object is NULL !");
679 PyObject *args(PyTuple_New(2));
680 PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj);
682 std::list< KeyWaiter *> newList,listOfEltToWakeUp;
683 for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++)
685 if((*it)->getVarName()!=varName)
687 newList.push_back(*it);
690 PyObject *waitKey((*it)->getKeyPyObj());
691 PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
692 PyObject *res(PyObject_CallObject(cmpObj,args));
695 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !";
696 throw Exception(oss.str());
698 long resCpp(PyInt_AsLong(res));
701 std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !";
702 throw Exception(oss.str());
706 listOfEltToWakeUp.push_back(*it);
708 newList.push_back(*it);
710 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
711 (*it)->valueJustCome(valueObj);
712 for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++)
714 _waiting_keys=newList;
717 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
719 checkVarExistingAndDict(varName);
720 TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
721 CORBA::Object_var obj(ret->activate());
722 return SALOME::Transaction::_narrow(obj);
725 SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
727 checkVarExistingAndDict(varName);
728 TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
729 CORBA::Object_var obj(ret->activate());
730 return SALOME::Transaction::_narrow(obj);
733 SALOME::TransactionMultiKeyAddSession_ptr DataScopeServerTransaction::addMultiKeyValueSession(const char *varName)
735 checkVarExistingAndDict(varName);
736 TransactionMultiKeyAddSession *ret(new TransactionMultiKeyAddSession(this,varName));
737 CORBA::Object_var obj(ret->activate());
738 return SALOME::TransactionMultiKeyAddSession::_narrow(obj);
741 SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
743 checkVarExistingAndDict(varName);
744 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
745 CORBA::Object_var obj(ret->activate());
746 return SALOME::Transaction::_narrow(obj);
749 SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTransac(const char *varName, const SALOME::ByteVec& constValue)
751 std::string varNameCpp(varName);
752 checkNotAlreadyExistingVar(varName);
753 PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varNameCpp,constValue));
754 CORBA::Object_var obj(tmp->activate());
755 std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(obj),tmp);
758 TransactionMorphRdWrIntoRdOnly *ret(new TransactionMorphRdWrIntoRdOnly(this,varName));
759 CORBA::Object_var obj2(ret->activate());
760 return SALOME::TransactionRdWrAccess::_narrow(obj2);
763 SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName)
765 std::string varNameCpp(varName);
766 checkExistingVar(varNameCpp);
768 TransactionKillVar *ret(new TransactionKillVar(this,varName));
769 CORBA::Object_var obj2(ret->activate());
770 return SALOME::Transaction::_narrow(obj2);
773 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
775 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
776 KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
777 CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
778 return SALOME::KeyWaiter::_narrow(obj);
781 SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
783 PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
784 KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
785 CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
787 TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
788 CORBA::Object_var obj2(ret1->activate());
789 transac=SALOME::Transaction::_narrow(obj2);
791 return SALOME::KeyWaiter::_narrow(obj);
794 SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
796 PortableServer::ServantBase *ret(0);
799 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
801 catch(...) { ret=0; }
802 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
804 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
805 retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
806 SALOME::ByteVec *zeRet(retc->waitForMonoThr());
807 retc->enforcedRelease();
811 SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw)
813 PortableServer::ServantBase *ret(0);
816 ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented !
818 catch(...) { ret=0; }
819 KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
821 throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
822 retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw)
823 SALOME::ByteVec *zeRet(retc->waitForAndKill());
824 retc->enforcedRelease();
828 void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
830 std::size_t sz(transactions.length());
833 std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
834 for(std::size_t i=0;i<sz;i++)
836 PortableServer::ServantBase *eltBase(0);
840 eltBase=_poa->reference_to_servant(transactions[i]);
841 elt=dynamic_cast<Transaction *>(eltBase);
845 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
846 throw Exception(oss.str());
850 std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
851 throw Exception(oss.str());
854 transactionsCpp[i]=elt;
856 {// important do not merge loops !
857 std::vector<TrustTransaction> transactions2(sz);
858 bool mustRollback(true);
859 for(std::size_t i=0;i<sz;i++)
860 transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
861 for(std::size_t i=0;i<sz;i++)
862 transactions2[i].operate();
865 for(std::size_t i=0;i<sz;i++)
866 transactionsCpp[i]->notify();
870 * Returns borrowed reference.
872 PyObject *DataScopeServerTransaction::getPyCmpFunc()
874 PyObject *builtins(PyDict_GetItemString(_globals,"__builtins__"));//borrowed
876 throw Exception("Fail to find reference to builtins !");
877 PyObject *builtins2(PyModule_GetDict(builtins));//borrowed
879 throw Exception("Fail to invoke __dict__ on builtins !");
880 PyObject *cmpObj(PyDict_GetItemString(builtins2,"cmp"));
882 throw Exception("Fail to find cmp in __builtins__ !");
886 DataScopeServerTransaction::~DataScopeServerTransaction()
890 SALOME::RequestSwitcher_ptr DataScopeServerTransaction::getRequestSwitcher()
894 _rs=new RequestSwitcher(_orb,this);
896 CORBA::Object_var obj(_rs->activate());
897 return SALOME::RequestSwitcher::_narrow(obj);