From 7fb79056f2e1296712e8c1f4de4308fc7b2616d4 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Tue, 21 Jul 2015 11:05:14 +0200 Subject: [PATCH] End of implementation. Let's test async. --- src/SALOMESDS/SALOMESDS_DataScopeServer.cxx | 43 ++++++++++++++++++- src/SALOMESDS/SALOMESDS_KeyWaiter.cxx | 46 ++++++++++++++++----- src/SALOMESDS/SALOMESDS_KeyWaiter.hxx | 11 +++-- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index e07d72ddc..e1c35d127 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -412,10 +412,11 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj) { PyObject *cmpObj(getPyCmpFunc()); if(!keyObj) - throw Exception("Key Object is NULL !"); + 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. for(std::list< KeyWaiter *>::iterator it=_waiting_keys.begin();it!=_waiting_keys.end();it++,ii++) { PyObject *waitKey((*it)->getKeyPyObj()); @@ -426,12 +427,52 @@ void DataScopeServerTransaction::pingKey(PyObject *keyObj) std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during cmp(k,wk[i]) !"; throw Exception(oss.str()); } + PyInt_AsLong(res); + if(PyErr_Occurred()) + { + std::ostringstream oss; oss << "DataScopeServerTransaction::pingKey : for object id #" << ii << " error during interpretation of cmp(k,wk[i]) !"; + throw Exception(oss.str()); + } Py_XDECREF(res); } } void DataScopeServerTransaction::notifyKey(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); + std::list< KeyWaiter *> newList,listOfEltToWakeUp; + 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)); + 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)); + 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) + listOfEltToWakeUp.push_back(*it); + else + newList.push_back(*it); + } + 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++) + (*it)->go(); + _waiting_keys=newList; } SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value) diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx index ff5348662..0c28da39d 100644 --- a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx +++ b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx @@ -22,16 +22,22 @@ #include "SALOMESDS_DataScopeServer.hxx" #include "SALOMESDS_PickelizedPyObjServer.hxx" +#include + using namespace SALOMESDS; -KeyWaiter::KeyWaiter(PickelizedPyObjServer *dst, const SALOME::ByteVec& keyVal):_dst(dst),_ze_key(0),_ze_value(0) +KeyWaiter::KeyWaiter(PickelizedPyObjServer *var, const SALOME::ByteVec& keyVal):_var(var),_ze_key(0),_ze_value(0) { - if(!dynamic_cast(dst->getFather())) + if(sem_init(&_sem,0,0)!=0)// put value to 0 to lock by default + throw Exception("KeyWaiter constructor : Error on initialization of semaphore !"); + if(!var) + throw Exception("KeyWaiter constructor : Invalid glob var is NULL !"); + if(!dynamic_cast(var->getFather())) throw Exception("KeyWaiter constructor : Invalid glob var ! Invalid DataScope hosting it ! DataScopeServerTransaction excpected !"); std::string st; PickelizedPyObjServer::FromByteSeqToCpp(keyVal,st); _ze_key=PickelizedPyObjServer::GetPyObjFromPickled(st,getDSS()); - PyObject *selfMeth(PyObject_GetAttrString(_dst->getPyObj(),"__contains__")); + PyObject *selfMeth(PyObject_GetAttrString(_var->getPyObj(),"__contains__")); PyObject *args(PyTuple_New(1)); PyTuple_SetItem(args,0,_ze_key); Py_XINCREF(_ze_key); // _ze_key is stolen by PyTuple_SetItem PyObject *retPy(PyObject_CallObject(selfMeth,args)); @@ -42,7 +48,7 @@ KeyWaiter::KeyWaiter(PickelizedPyObjServer *dst, const SALOME::ByteVec& keyVal): throw Exception("KeyWaiter constructor : unexpected return of dict.__contains__ !"); if(retPy==Py_True) { - selfMeth=PyObject_GetAttrString(_dst->getPyObj(),"__getitem__"); + selfMeth=PyObject_GetAttrString(_var->getPyObj(),"__getitem__"); args=PyTuple_New(1); PyTuple_SetItem(args,0,_ze_key); Py_XINCREF(_ze_key); // _ze_key is stolen by PyTuple_SetItem retPy=PyObject_CallObject(selfMeth,args); @@ -51,10 +57,11 @@ KeyWaiter::KeyWaiter(PickelizedPyObjServer *dst, const SALOME::ByteVec& keyVal): _ze_value=retPy; Py_XDECREF(args); Py_XDECREF(selfMeth); + go();//notify that value already arrives -> unlock } else { - getDSS()->addWaitKey(this); + getDSS()->addWaitKey(this);// key not present let the DataScope managing it ! } Py_XDECREF(retPy); } @@ -72,14 +79,31 @@ PortableServer::POA_var KeyWaiter::getPOA() const } SALOME::ByteVec *KeyWaiter::waitFor() +{ + sem_wait(&_sem); + if(!_ze_value) + throw Exception("KeyWaiter::waitFor : internal error !"); + Py_XINCREF(_ze_value); + std::string st(PickelizedPyObjServer::Pickelize(_ze_value,_var->getFather())); + return PickelizedPyObjServer::FromCppToByteSeq(st); +} + +/*! + * WARNING call this method before calling go ! + */ +void KeyWaiter::valueJustCome(PyObject *val) { if(_ze_value) + Py_XDECREF(_ze_value); + _ze_value=val; + Py_XINCREF(_ze_value); +} + +void KeyWaiter::go() +{ + if(sem_post(&_sem)!=0) { - Py_XINCREF(_ze_value); - std::string st(PickelizedPyObjServer::Pickelize(_ze_value,_dst->getFather())); - return PickelizedPyObjServer::FromCppToByteSeq(st); + std::ostringstream oss; oss << "KeyWaiter::go : error on post of semaphore ! "; + throw Exception(oss.str()); } - else - throw Exception("KeyWaiter::waitFor : not implemented yet !"); - return 0; } diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx index d5f09b4bc..a2f92abce 100644 --- a/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx +++ b/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx @@ -31,6 +31,8 @@ #include +#include + namespace SALOMESDS { class DataScopeServerTransaction; @@ -38,17 +40,20 @@ namespace SALOMESDS class SALOMESDS_EXPORT KeyWaiter : public virtual POA_SALOME::KeyWaiter, public POAHolder { public: - KeyWaiter(PickelizedPyObjServer *dst, const SALOME::ByteVec& keyVal); + KeyWaiter(PickelizedPyObjServer *var, const SALOME::ByteVec& keyVal); PyObject *getKeyPyObj() const { return _ze_key; } virtual ~KeyWaiter(); PortableServer::POA_var getPOA() const; SALOME::ByteVec *waitFor(); + void valueJustCome(PyObject *val); + void go(); private: - DataScopeServerTransaction *getDSS() const { return static_cast(_dst->getFather()); }//thanks to dynamic_cast in constructor + DataScopeServerTransaction *getDSS() const { return static_cast(_var->getFather()); }//thanks to dynamic_cast in constructor private: - PickelizedPyObjServer *_dst; + PickelizedPyObjServer *_var; PyObject *_ze_key; PyObject *_ze_value; + sem_t _sem; }; } -- 2.39.2