X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FSALOMESDS%2FSALOMESDS_DataScopeServer.cxx;h=d8b70ef3a8f620bfddf96e5da172a5b57236d654;hb=c2c1a75bf40fde2010d34d07f999ffb7e6b13304;hp=76a78c8ee724e66b2a0b309f5001459a74306260;hpb=8146c533bb26ecd6be3d0a3ec8ac33d94066e286;p=modules%2Fkernel.git diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index 76a78c8ee..d8b70ef3a 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -46,12 +46,44 @@ using namespace SALOMESDS; std::size_t DataScopeServerBase::COUNTER=0; +#if PY_VERSION_HEX < 0x03050000 +static char* +Py_EncodeLocale(const wchar_t *arg, size_t *size) +{ + return _Py_wchar2char(arg, size); +} +static wchar_t* +Py_DecodeLocale(const char *arg, size_t *size) +{ + return _Py_char2wchar(arg, size); +} +#endif + void DataScopeKiller::shutdown() { Py_Finalize(); _orb->shutdown(0); } +RequestSwitcher::RequestSwitcher(CORBA::ORB_ptr orb, DataScopeServerTransaction *ds):RequestSwitcherBase(orb),_ds(ds) +{ +} + +SALOME::StringVec *RequestSwitcher::listVars() +{ + return _ds->listVars(); +} + +SALOME::ByteVec *RequestSwitcher::fetchSerializedContent(const char *varName) +{ + return _ds->fetchSerializedContent(varName); +} + +void RequestSwitcher::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data) +{ + return _ds->fetchAndGetAccessOfVar(varName,access,data); +} + 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) { } @@ -226,11 +258,32 @@ SALOME::SeqOfByteVec *DataScopeServerBase::getAllKeysOfVarWithTypeDict(const cha return ret; } +void DataScopeServerBase::takeANap(CORBA::Double napDurationInSec) +{ + if(napDurationInSec<0.) + throw Exception("DataScopeServerBase::takeANap : negative value !"); +#ifndef WIN32 + struct timespec req,rem; + long nbSec((long)napDurationInSec); + double remainTime(napDurationInSec-(double)nbSec); + req.tv_sec=nbSec; + req.tv_nsec=(long)(remainTime*1000000.); + int ret(nanosleep(&req,&rem)); + if(ret!=0) + throw Exception("DataScopeServerBase::takeANap : nap not finished as expected !"); +#else + throw Exception("DataScopeServerBase::takeANap : not implemented for Windows !"); +#endif +} + void DataScopeServerBase::initializePython(int argc, char *argv[]) { Py_Initialize(); PyEval_InitThreads(); - PySys_SetArgv(argc,argv); + wchar_t **changed_argv = new wchar_t*[argc]; // Setting arguments + for (int i = 0; i < argc; i++) + changed_argv[i] = Py_DecodeLocale(argv[i], NULL); + PySys_SetArgv(argc, changed_argv); PyObject *mainmod(PyImport_AddModule("__main__")); _globals=PyModule_GetDict(mainmod); if(PyDict_GetItemString(_globals, "__builtins__") == NULL) @@ -242,7 +295,7 @@ void DataScopeServerBase::initializePython(int argc, char *argv[]) } _locals=PyDict_New(); PyObject *tmp(PyList_New(0)); - _pickler=PyImport_ImportModuleLevel(const_cast("cPickle"),_globals,_locals,tmp,-1); + _pickler=PyImport_ImportModuleLevel(const_cast("pickle"),_globals,_locals,tmp,0); } void DataScopeServerBase::registerToSalomePiDict() const @@ -254,8 +307,8 @@ void DataScopeServerBase::registerToSalomePiDict() const if(!meth) { Py_XDECREF(mod); return ; } PyObject *args(PyTuple_New(2)); - PyTuple_SetItem(args,0,PyInt_FromLong(getpid())); - PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServerBase")); + PyTuple_SetItem(args,0,PyLong_FromLong(getpid())); + PyTuple_SetItem(args,1,PyUnicode_FromString("SALOME_DataScopeServerBase")); PyObject *res(PyObject_CallObject(meth,args)); Py_XDECREF(args); Py_XDECREF(res); @@ -292,11 +345,16 @@ std::vector< std::string > DataScopeServerBase::getAllVarNames() const return ret; } -void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const +bool DataScopeServerBase::isExistingVar(const std::string& varName) const { std::vector allNames(getAllVarNames()); std::vector::iterator it(std::find(allNames.begin(),allNames.end(),varName)); - if(it!=allNames.end()) + return it!=allNames.end(); +} + +void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const +{ + if(isExistingVar(varName)) { std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !"; throw Exception(oss.str()); @@ -372,31 +430,35 @@ void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit(const s throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExtInit : var is neither RdExt nor RdExtInit !"); if(varc0) { - PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj); - PickelizedPyObjRdExtInitServer *newVar(new PickelizedPyObjRdExtInitServer(this,varName,pyobj)); + PickelizedPyObjRdExtInitServer *newVar(varc0->buildInitInstanceFrom(varName)); + newVar->incrNbClients(); CORBA::Object_var obj(newVar->activate()); SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj)); p.first=obj2; p.second=newVar; varc0->decrRef(); } + else + varc1->incrNbClients(); } -void DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt(const std::string& varName) +void DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt(const std::string& varName) { std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it(retrieveVarInternal4(varName)); std::pair< SALOME::BasicDataServer_var, BasicDataServer * >& p(*it); PickelizedPyObjRdExtInitServer *varc0(dynamic_cast(p.second)); PickelizedPyObjRdExtServer *varc1(dynamic_cast(p.second)); if(!varc0 && !varc1) - throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtInitToRdExt : var is not a RdExtInit !"); + throw Exception("DataScopeServerBase::moveStatusOfVarFromRdExtOrRdExtInitToRdExt : var is not a RdExtInit !"); if(varc0) { - PyObject *pyobj(varc0->getPyObj()); Py_XINCREF(pyobj); - PickelizedPyObjRdExtServer *newVar(new PickelizedPyObjRdExtServer(this,varName,pyobj)); - CORBA::Object_var obj(newVar->activate()); - SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj)); - p.first=obj2; p.second=newVar; - varc0->decrRef(); + if(varc0->decrNbClients()) + { + PickelizedPyObjRdExtServer *newVar(varc0->buildStdInstanceFrom(varName)); + CORBA::Object_var obj(newVar->activate()); + SALOME::BasicDataServer_var obj2(SALOME::BasicDataServer::_narrow(obj)); + p.first=obj2; p.second=newVar; + varc0->decrRef(); + } } } @@ -515,6 +577,15 @@ char *DataScopeServerTransaction::getAccessOfVar(const char *varName) return CORBA::string_dup(ret.c_str()); } +/*! + * This method is here to retrieve atomically accessStr and picklization. + */ +void DataScopeServerTransaction::fetchAndGetAccessOfVar(const char *varName, CORBA::String_out access, SALOME::ByteVec_out data) +{ + access=getAccessOfVar(varName); + data=fetchSerializedContent(varName); +} + void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue) { checkNotAlreadyExistingVar(varName); @@ -533,6 +604,51 @@ void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varNa _vars.push_back(p); } +void DataScopeServerTransaction::createRdExtVarFreeStyleInternal(const std::string& varName, const SALOME::ByteVec& constValue, std::string&& compareFuncContent, SALOME::AutoPyRef&& compareFunc) +{ + if(!isExistingVar(varName)) + { + PickelizedPyObjRdExtFreeStyleServer *tmp(new PickelizedPyObjRdExtFreeStyleServer(this,varName,constValue,std::move(compareFuncContent),std::move(compareFunc))); + CORBA::Object_var ret(tmp->activate()); + std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp); + _vars.push_back(p); + } + else + { + BasicDataServer *ds(retrieveVarInternal2(varName)); + if(!ds) + { + std::ostringstream oss; + oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : internal error 1 for varname \"" << varName << "\"!"; + throw Exception(oss.str()); + } + Sha1Keeper *ds2(dynamic_cast(ds)); + if(!ds2) + { + std::ostringstream oss; + oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non Sha1Keeper type !"; + throw Exception(oss.str()); + } + PickelizedPyObjServer *ds3(dynamic_cast(ds)); + if(!ds3) + { + std::ostringstream oss; + oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non PickelizedPyObjServer type !"; + throw Exception(oss.str()); + } + std::vector constValueAsCpp; + Transaction::FromByteSeqToVB(constValue,constValueAsCpp); + SALOME::AutoPyRef newObj(PickelizedPyObjServer::GetPyObjFromPickled(constValueAsCpp,this)); + if(newObj.isNull()) + { + std::ostringstream oss; + oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists but input pickelized object is not loadable !"; + throw Exception(oss.str()); + } + ds2->checkSame(varName,compareFuncContent,ds3->getPyObj(),newObj); + } +} + void DataScopeServerTransaction::createRdExtInitVarInternal(const std::string& varName, const SALOME::ByteVec& constValue) { checkNotAlreadyExistingVar(varName); @@ -567,6 +683,13 @@ SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const return SALOME::Transaction::_narrow(obj); } +SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarFreeStyleTransac(const char *varName, const SALOME::ByteVec& constValue, const char *compareFuncContent) +{// no check on varName done here. Will be done on perform + TransactionRdExtVarFreeStyleCreate *ret(new TransactionRdExtVarFreeStyleCreate(this,varName,constValue,compareFuncContent)); + CORBA::Object_var obj(ret->activate()); + return SALOME::Transaction::_narrow(obj); +} + SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtInitVarTransac(const char *varName, const SALOME::ByteVec& constValue) { checkNotAlreadyExistingVar(varName); @@ -592,24 +715,27 @@ void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw) void DataScopeServerTransaction::pingKey(PyObject *keyObj) { - PyObject *cmpObj(getPyCmpFunc()); - if(!keyObj) - throw Exception("ataScopeServerTransaction::pingKey : Key Object is NULL !"); - PyObject *args(PyTuple_New(2)); - PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj); std::size_t ii(0); // this part does nothing except to be sure that in notify key all will be OK. + PyObject *args(PyTuple_New(1)); + PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj); for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++) { PyObject *waitKey((*it)->getKeyPyObj()); - PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey); - PyObject *res(PyObject_CallObject(cmpObj,args)); + PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__")); + if(!meth) + { + std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !"; + throw Exception(oss.str()); + } + PyObject *res(PyObject_CallObject(meth,args)); + Py_XDECREF(meth); if(res==NULL) { std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !"; throw Exception(oss.str()); } - PyInt_AsLong(res); + PyBool_Check(res); if(PyErr_Occurred()) { std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !"; @@ -617,16 +743,14 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj) } Py_XDECREF(res); } + Py_XDECREF(args); } void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject *keyObj, PyObject *valueObj) { - PyObject *cmpObj(getPyCmpFunc()); - if(!keyObj) - throw Exception("DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! Key Object is NULL !"); - PyObject *args(PyTuple_New(2)); - PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj); std::size_t ii(0); + PyObject *args(PyTuple_New(1)); + PyTuple_SetItem(args,0,keyObj); Py_XINCREF(keyObj); std::list< KeyWaiter *> newList,listOfEltToWakeUp; for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++) { @@ -636,25 +760,31 @@ void DataScopeServerTransaction::notifyKey(const std::string& varName, PyObject continue; } PyObject *waitKey((*it)->getKeyPyObj()); - PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey); - PyObject *res(PyObject_CallObject(cmpObj,args)); - if(res==NULL) - { - std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during cmp(k,wk[i]) !"; - throw Exception(oss.str()); - } - long resCpp(PyInt_AsLong(res)); + PyObject *meth(PyObject_GetAttrString(waitKey,"__eq__")); + if(!meth) + { + std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !"; + throw Exception(oss.str()); + } + PyObject *res(PyObject_CallObject(meth,args)); + Py_XDECREF(meth); + if(!PyBool_Check(res)) + { + std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " no __eq__ in pyobj !"; + throw Exception(oss.str()); + } if(PyErr_Occurred()) { std::ostringstream oss; oss << "DataScopeServerTransaction::notifyKey : MAIN INTERNAL ERROR ! for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !"; throw Exception(oss.str()); } - Py_XDECREF(res); - if(resCpp==0) + if(res==Py_True) listOfEltToWakeUp.push_back(*it); else newList.push_back(*it); + Py_XDECREF(res); } + Py_XDECREF(args); for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++) (*it)->valueJustCome(valueObj); for(std::list< KeyWaiter *>::iterator it=listOfEltToWakeUp.begin();it!=listOfEltToWakeUp.end();it++) @@ -708,6 +838,16 @@ SALOME::TransactionRdWrAccess_ptr DataScopeServerTransaction::createWorkingVarTr return SALOME::TransactionRdWrAccess::_narrow(obj2); } +SALOME::Transaction_ptr DataScopeServerTransaction::killVarTransac(const char *varName) +{ + std::string varNameCpp(varName); + checkExistingVar(varNameCpp); + // + TransactionKillVar *ret(new TransactionKillVar(this,varName)); + CORBA::Object_var obj2(ret->activate()); + return SALOME::Transaction::_narrow(obj2); +} + SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal) { PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName)); @@ -734,14 +874,33 @@ SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter PortableServer::ServantBase *ret(0); try { - ret=_poa_for_key_waiter->reference_to_servant(kw); + ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented ! + } + catch(...) { ret=0; } + KeyWaiter *retc(dynamic_cast(ret)); + if(!retc) + throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !"); + retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw) + SALOME::ByteVec *zeRet(retc->waitForMonoThr()); + retc->enforcedRelease(); + return zeRet; +} + +SALOME::ByteVec *DataScopeServerTransaction::waitForAndKill(SALOME::KeyWaiter_ptr kw) +{ + PortableServer::ServantBase *ret(0); + try + { + ret=_poa_for_key_waiter->reference_to_servant(kw);// Warning ref cnt of ret has been incremented ! } catch(...) { ret=0; } KeyWaiter *retc(dynamic_cast(ret)); if(!retc) throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !"); - retc->_remove_ref(); - return retc->waitForMonoThr(); + retc->_remove_ref();// restore the counter after _poa_for_key_waiter->reference_to_servant(kw) + SALOME::ByteVec *zeRet(retc->waitForAndKill()); + retc->enforcedRelease(); + return zeRet; } void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions) @@ -785,24 +944,16 @@ void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& tr transactionsCpp[i]->notify(); } -/*! - * Returns borrowed reference. - */ -PyObject *DataScopeServerTransaction::getPyCmpFunc() +DataScopeServerTransaction::~DataScopeServerTransaction() { - PyObject *builtins(PyDict_GetItemString(_globals,"__builtins__"));//borrowed - if(builtins==NULL) - throw Exception("Fail to find reference to builtins !"); - PyObject *builtins2(PyModule_GetDict(builtins));//borrowed - if(builtins2==NULL) - throw Exception("Fail to invoke __dict__ on builtins !"); - PyObject *cmpObj(PyDict_GetItemString(builtins2,"cmp")); - if(cmpObj==NULL) - throw Exception("Fail to find cmp in __builtins__ !"); - return cmpObj; } -DataScopeServerTransaction::~DataScopeServerTransaction() +SALOME::RequestSwitcher_ptr DataScopeServerTransaction::getRequestSwitcher() { + if(_rs.isNull()) + { + _rs=new RequestSwitcher(_orb,this); + } + CORBA::Object_var obj(_rs->activate()); + return SALOME::RequestSwitcher::_narrow(obj); } -