]> SALOME platform Git repositories - modules/kernel.git/commitdiff
Salome HOME
A safer and cleaner method to avoid conflicts between threads with python.
authorAnthony Geay <anthony.geay@edf.fr>
Wed, 22 Jul 2015 13:56:51 +0000 (15:56 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Wed, 22 Jul 2015 13:56:51 +0000 (15:56 +0200)
idl/SALOME_SDS.idl
src/SALOMESDS/SALOMESDS_DataScopeServer.cxx
src/SALOMESDS/SALOMESDS_DataScopeServer.hxx
src/SALOMESDS/SALOMESDS_DataServerManager.cxx
src/SALOMESDS/SALOMESDS_KeyWaiter.cxx
src/SALOMESDS/SALOMESDS_KeyWaiter.hxx
src/SALOMESDS/SALOME_DataScopeServer.cxx

index 23f10a36a75b856fe8dc4528929abc2ab623664c..a7bb219bdbe39d93c971fb2011a3c3cf6209d973 100644 (file)
@@ -98,6 +98,7 @@ module SALOME
     KeyWaiter waitForKeyInVar(in string varName, in ByteVec keyVal) raises (SALOME::SALOME_Exception);
     KeyWaiter waitForKeyInVarAndKillIt(in string varName, in ByteVec keyVal, out Transaction transac) raises (SALOME::SALOME_Exception);
     void atomicApply(in ListOfTransaction transactions) raises (SALOME::SALOME_Exception);
+    ByteVec waitForMonoThrRev(in KeyWaiter kw) raises (SALOME::SALOME_Exception);
   };
 
   interface DataServerManager
index 7616e40c9f1a160b7d68886defb689d3bb2a663f..de077f7da19faf7b9c6f7ddf1ad7164f19f8c3b2 100644 (file)
@@ -46,7 +46,6 @@ std::size_t DataScopeServerBase::COUNTER=0;
 
 DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName)
 {
-  pthread_mutex_init(&_mutex_for_py_interp,0);
 }
 
 DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars)
@@ -193,15 +192,17 @@ void DataScopeServerBase::registerToSalomePiDict() const
   Py_XDECREF(mod);
 }
 
-/*!
- * \a ptr has been activated by the POA \a poa.
- */
-void DataScopeServerBase::setPOAAndRegister(PortableServer::POA_var poa, SALOME::DataScopeServerBase_ptr ptr)
+void DataScopeServerBase::setPOA(PortableServer::POA_var poa)
 {
   _poa=poa;
+}
+
+void DataScopeServerBase::registerInNS(SALOME::DataScopeServerBase_ptr ptr)
+{
   std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(_name));
   SALOME_NamingService ns(_orb);
   ns.Register(ptr,fullScopeName.c_str());
+  _ptr_of_this=SALOME::DataScopeServerBase::_duplicate(ptr);
 }
 
 std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
@@ -531,6 +532,21 @@ SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const
   return SALOME::KeyWaiter::_narrow(obj);
 }
 
+SALOME::ByteVec *DataScopeServerTransaction::waitForMonoThrRev(SALOME::KeyWaiter_ptr kw)
+{
+  PortableServer::ServantBase *ret(0);
+  try
+    {
+      ret=_poa_for_key_waiter->reference_to_servant(kw);
+    }
+  catch(...) { ret=0; }
+  KeyWaiter *retc(dynamic_cast<KeyWaiter *>(ret));
+  if(!retc)
+    throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !");
+  retc->_remove_ref();
+  retc->waitForMonoThr();
+}
+
 class TrustTransaction
 {
 public:
index b77e47dc6bbf3b790e8c5f5649f77368a544a73f..f79e0a92c2820093eb711b5ad2800c0eb82f5be9 100644 (file)
@@ -30,7 +30,6 @@
 #include "SALOMESDS_Defines.hxx"
 
 #include <Python.h>
-#include <pthread.h>
 
 #include <string>
 #include <vector>
@@ -58,12 +57,15 @@ namespace SALOMESDS
   public:
     void initializePython(int argc, char *argv[]);
     void registerToSalomePiDict() const;
-    void setPOAAndRegister(PortableServer::POA_var poa, SALOME::DataScopeServerBase_ptr ptr);
+    void setPOA(PortableServer::POA_var poa);
+    void registerInNS(SALOME::DataScopeServerBase_ptr ptr);
     PyObject *getGlobals() const { return _globals; }
     PyObject *getLocals() const { return _locals; }
     PyObject *getPickler() const { return _pickler; }
     PortableServer::POA_var getPOA() const { return _poa; }
     CORBA::ORB_var getORB() { return _orb; }
+    //! MTA = Mono thread activated
+    SALOME::DataScopeServerBase_var getObjectRefMTA() { return _ptr_of_this ;}
     std::string getScopeNameCpp() const { return _name; }
     static std::string BuildTmpVarNameFrom(const std::string& varName);
   public:
@@ -71,7 +73,6 @@ namespace SALOMESDS
     void checkNotAlreadyExistingVar(const std::string& varName) const;
     void checkExistingVar(const std::string& varName) const;
     PickelizedPyObjServer *checkVarExistingAndDict(const std::string& varName);
-    pthread_mutex_t *getMutexForPyInterp() { return &_mutex_for_py_interp; }
   protected:
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const;
   protected:
@@ -82,7 +83,8 @@ namespace SALOMESDS
     CORBA::ORB_var _orb;
     std::string _name;
     std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > > _vars;
-    pthread_mutex_t _mutex_for_py_interp;
+    // CORBA pointer of this activated by monothread POA _poa.
+    SALOME::DataScopeServerBase_var _ptr_of_this;
     static std::size_t COUNTER;
   };
   
@@ -111,6 +113,7 @@ namespace SALOMESDS
     void addWaitKey(KeyWaiter *kw);
     void pingKey(PyObject *keyObj);
     void notifyKey(PyObject *keyObj, PyObject *valueObj);
+    SALOME::ByteVec *waitForMonoThrRev(SALOME::KeyWaiter_ptr kw);
   public://remotely callable
     SALOME::ByteVec *fetchSerializedContent(const char *varName);
     SALOME::Transaction_ptr createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue);
index 3f9c633de1598a9d00a330ae16eee8d6ff074791..326adefe19bcd194955b9f28a1cc7b9c0732dc3c 100644 (file)
@@ -53,10 +53,10 @@ DataServerManager::DataServerManager(int argc, char *argv[], CORBA::ORB_ptr orb,
   SALOME_NamingService ns(orb);
   ns.Register(obj2,NAME_IN_NS);
   // the default DataScopeServer object is the only one hosted by the current process
-  id=_poa->activate_object(dftScope);
-  obj=_poa->id_to_reference(id);
+  dftScope->setPOA(_poa);
+  obj=dftScope->activate();
   SALOME::DataScopeServer_var dftScopePtr(SALOME::DataScopeServer::_narrow(obj));
-  dftScope->setPOAAndRegister(_poa,dftScopePtr);// agy : Very important ! invoke this method BEFORE activation ! Because this method initializes Python !
+  dftScope->registerInNS(dftScopePtr);// agy : Very important ! invoke this method BEFORE activation ! Because this method initializes Python !
 }
 
 SALOME::StringVec *DataServerManager::listScopes()
index 5249be58d3c14e244f58fd450eef61d206bd57ad..78ca045261b8501322189d90adb36a3296e8dbbe 100644 (file)
 
 using namespace SALOMESDS;
 
-class MutexLocker
-{
-public:
-  MutexLocker(DataScopeServerBase *dss):_dss(dss) { pthread_mutex_lock(_dss->getMutexForPyInterp()); }
-  ~MutexLocker() { pthread_mutex_unlock(_dss->getMutexForPyInterp()); }
-private:
-  DataScopeServerBase *_dss;
-};
-
 KeyWaiter::KeyWaiter(PickelizedPyObjServer *var, const SALOME::ByteVec& keyVal):_var(var),_ze_key(0),_ze_value(0)
 {
   if(sem_init(&_sem,0,0)!=0)// put value to 0 to lock by default
@@ -87,18 +78,28 @@ SALOME::ByteVec *KeyWaiter::waitFor()
 {
   sem_wait(&_sem);
   if(!_ze_value)
-    throw Exception("KeyWaiter::waitFor : internal error !");
-  std::string st;
+    throw Exception("KeyWaiter::waitFor : internal error !");
+  SALOME::ByteVec *ret(0);
   {
-    MutexLocker ml(_var->getFather());
-    Py_XINCREF(_ze_value);
-    st=PickelizedPyObjServer::Pickelize(_ze_value,_var->getFather());
+    SALOME::DataScopeServerBase_var ptr(_var->getFather()->getObjectRefMTA());
+    SALOME::DataScopeServerTransaction_var ptr2(SALOME::DataScopeServerTransaction::_narrow(ptr));
+    if(CORBA::is_nil(ptr2))
+      throw Exception("KeyWaiter::waitFor : internal error 2 !");
+    CORBA::Object_var thisPtr(getPOA()->servant_to_reference(this));
+    SALOME::KeyWaiter_var thisPtr2(SALOME::KeyWaiter::_narrow(thisPtr));
+    ret=ptr2->waitForMonoThrRev(thisPtr2);
   }
-  SALOME::ByteVec *ret(PickelizedPyObjServer::FromCppToByteSeq(st));
   enforcedRelease();
   return ret;
 }
 
+SALOME::ByteVec *KeyWaiter::waitForMonoThr()
+{
+  Py_XINCREF(_ze_value);
+  std::string st(PickelizedPyObjServer::Pickelize(_ze_value,_var->getFather()));
+  return PickelizedPyObjServer::FromCppToByteSeq(st);
+}
+
 /*!
  * WARNING call this method before calling go !
  */
index a2f92abce9d640da033c9dee1edfc8e75940f4f1..f16c72d7ff69bfd355efe0f45eaff4ea73501825 100644 (file)
@@ -47,6 +47,7 @@ namespace SALOMESDS
     SALOME::ByteVec *waitFor();
     void valueJustCome(PyObject *val);
     void go();
+    SALOME::ByteVec *waitForMonoThr();
   private:
     DataScopeServerTransaction *getDSS() const { return static_cast<DataScopeServerTransaction *>(_var->getFather()); }//thanks to dynamic_cast in constructor
   private:
index 16f68161f9a9298a0d2ff7d3fc71f466825fdd08..de6790b1f8f07f82072156720ff0d13aec566e91 100644 (file)
@@ -55,10 +55,11 @@ int main(int argc, char *argv[])
   threadPol->destroy();
   server->initializePython(argc,argv);// agy : Very important ! invoke this method BEFORE activation !
   server->registerToSalomePiDict();
-  PortableServer::ObjectId_var id(poa2->activate_object(server));
-  obj=poa2->id_to_reference(id);
+  //
+  server->setPOA(poa2);
+  obj=server->activate();
   SALOME::DataScopeServerBase_var serverPtr(SALOME::DataScopeServerBase::_narrow(obj));
-  server->setPOAAndRegister(poa2,serverPtr);
+  server->registerInNS(serverPtr);
   //
   orb->run();
   server->_remove_ref();