{
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());
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)
#include "SALOMESDS_DataScopeServer.hxx"
#include "SALOMESDS_PickelizedPyObjServer.hxx"
+#include <sstream>
+
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<DataScopeServerTransaction *>(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<DataScopeServerTransaction *>(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));
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);
_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);
}
}
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;
}
#include <Python.h>
+#include <semaphore.h>
+
namespace SALOMESDS
{
class DataScopeServerTransaction;
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<DataScopeServerTransaction *>(_dst->getFather()); }//thanks to dynamic_cast in constructor
+ DataScopeServerTransaction *getDSS() const { return static_cast<DataScopeServerTransaction *>(_var->getFather()); }//thanks to dynamic_cast in constructor
private:
- PickelizedPyObjServer *_dst;
+ PickelizedPyObjServer *_var;
PyObject *_ze_key;
PyObject *_ze_value;
+ sem_t _sem;
};
}