-// 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
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)
{
}
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)
}
_locals=PyDict_New();
PyObject *tmp(PyList_New(0));
- _pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
+ _pickler=PyImport_ImportModuleLevel(const_cast<char *>("pickle"),_globals,_locals,tmp,0);
}
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);
return ret;
}
-void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
+bool DataScopeServerBase::isExistingVar(const std::string& varName) const
{
std::vector<std::string> allNames(getAllVarNames());
std::vector<std::string>::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());
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<PickelizedPyObjRdExtInitServer *>(p.second));
PickelizedPyObjRdExtServer *varc1(dynamic_cast<PickelizedPyObjRdExtServer *>(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();
+ }
}
}
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);
_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<Sha1Keeper *>(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<PickelizedPyObjServer *>(ds));
+ if(!ds3)
+ {
+ std::ostringstream oss;
+ oss << "DataScopeServerTransaction::createRdExtVarFreeStyleInternal : varname \"" << varName << "\" already exists with a non PickelizedPyObjServer type !";
+ throw Exception(oss.str());
+ }
+ std::vector<unsigned char> 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);
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);
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]) !";
}
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++)
{
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++)
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));
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<KeyWaiter *>(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<KeyWaiter *>(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)
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);
}
-