From: Anthony Geay Date: Wed, 22 Jul 2015 13:56:51 +0000 (+0200) Subject: A safer and cleaner method to avoid conflicts between threads with python. X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4a3043cf38f3aef200cd828fac869177f05d299a;p=modules%2Fkernel.git A safer and cleaner method to avoid conflicts between threads with python. --- diff --git a/idl/SALOME_SDS.idl b/idl/SALOME_SDS.idl index 23f10a36a..a7bb219bd 100644 --- a/idl/SALOME_SDS.idl +++ b/idl/SALOME_SDS.idl @@ -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 diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index 7616e40c9..de077f7da 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -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(ret)); + if(!retc) + throw Exception("DataScopeServerTransaction::invokeMonoThr : internal error 1 !"); + retc->_remove_ref(); + retc->waitForMonoThr(); +} + class TrustTransaction { public: diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx index b77e47dc6..f79e0a92c 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx @@ -30,7 +30,6 @@ #include "SALOMESDS_Defines.hxx" #include -#include #include #include @@ -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); diff --git a/src/SALOMESDS/SALOMESDS_DataServerManager.cxx b/src/SALOMESDS/SALOMESDS_DataServerManager.cxx index 3f9c633de..326adefe1 100644 --- a/src/SALOMESDS/SALOMESDS_DataServerManager.cxx +++ b/src/SALOMESDS/SALOMESDS_DataServerManager.cxx @@ -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() diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx index 5249be58d..78ca04526 100644 --- a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx +++ b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx @@ -26,15 +26,6 @@ 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 1 !"); + 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 ! */ diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx index a2f92abce..f16c72d7f 100644 --- a/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx +++ b/src/SALOMESDS/SALOMESDS_KeyWaiter.hxx @@ -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(_var->getFather()); }//thanks to dynamic_cast in constructor private: diff --git a/src/SALOMESDS/SALOME_DataScopeServer.cxx b/src/SALOMESDS/SALOME_DataScopeServer.cxx index 16f68161f..de6790b1f 100644 --- a/src/SALOMESDS/SALOME_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOME_DataScopeServer.cxx @@ -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();