]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
End of implementation. Let's test async.
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 21 Jul 2015 09:05:14 +0000 (11:05 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 21 Jul 2015 09:05:14 +0000 (11:05 +0200)
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_KeyWaiter.cxx
src/SALOMESDS/SALOMESDS_KeyWaiter.hxx

index e07d72ddc4b4d48ee25729a413f7edab3442f3e1..e1c35d1271555cf4efacd588cadc8b28e0080696 100644 (file)
@@ -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)
index ff5348662de3acce342c4bc9e78f260341bbcdf1..0c28da39d09642d7f791f2c88680bb7d581cf98c 100644 (file)
 #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));
@@ -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;
 }
index d5f09b4bcf040521e5071ab94c683f214f205cc0..a2f92abce9d640da033c9dee1edfc8e75940f4f1 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <Python.h>
 
+#include <semaphore.h>
+
 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<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;
   };
 }