From ecfa1f6828528b2c5ec768caab82734b4540d486 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 22 Jul 2015 09:37:34 +0200 Subject: [PATCH] OK with the corresponding test --- src/SALOMESDS/CMakeLists.txt | 1 + src/SALOMESDS/SALOMESDS_DataScopeServer.cxx | 2 + src/SALOMESDS/SALOMESDS_DataScopeServer.hxx | 3 ++ src/SALOMESDS/SALOMESDS_KeyWaiter.cxx | 17 ++++++- src/SALOMESDS/TestSalomeSDS2.py | 56 +++++++++++++++++++++ src/SALOMESDS/TestSalomeSDS3.py | 25 +++++++++ 6 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/SALOMESDS/TestSalomeSDS3.py diff --git a/src/SALOMESDS/CMakeLists.txt b/src/SALOMESDS/CMakeLists.txt index 8a9a4c145..259f95a91 100644 --- a/src/SALOMESDS/CMakeLists.txt +++ b/src/SALOMESDS/CMakeLists.txt @@ -56,6 +56,7 @@ ADD_EXECUTABLE(SALOME_DataScopeServer SALOME_DataScopeServer.cxx) TARGET_LINK_LIBRARIES(SALOME_DataScopeServer SalomeSDS) INSTALL(TARGETS SALOME_DataScopeServer DESTINATION ${SALOME_INSTALL_BINS}) INSTALL(FILES SalomeSDSClt.py DESTINATION ${SALOME_INSTALL_BINS}) +INSTALL(FILES TestSalomeSDS3.py DESTINATION ${SALOME_INSTALL_BINS}) FILE(GLOB COMMON_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") INSTALL(FILES ${COMMON_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx index 0c5c3506e..61dbf5156 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.cxx @@ -46,6 +46,7 @@ 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) @@ -159,6 +160,7 @@ void DataScopeServerBase::shutdownIfNotHostedByDSM() void DataScopeServerBase::initializePython(int argc, char *argv[]) { Py_Initialize(); + PyEval_InitThreads(); PySys_SetArgv(argc,argv); PyObject *mainmod(PyImport_AddModule("__main__")); _globals=PyModule_GetDict(mainmod); diff --git a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx index cd575defd..b7bd2a278 100644 --- a/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx +++ b/src/SALOMESDS/SALOMESDS_DataScopeServer.hxx @@ -30,6 +30,7 @@ #include "SALOMESDS_Defines.hxx" #include +#include #include #include @@ -70,6 +71,7 @@ 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: @@ -80,6 +82,7 @@ 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; static std::size_t COUNTER; }; diff --git a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx index ecc3a9148..3a2ec7561 100644 --- a/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx +++ b/src/SALOMESDS/SALOMESDS_KeyWaiter.cxx @@ -26,6 +26,15 @@ 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 @@ -83,8 +92,12 @@ 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())); + std::string st; + { + MutexLocker ml(_var->getFather()); + Py_XINCREF(_ze_value); + st=PickelizedPyObjServer::Pickelize(_ze_value,_var->getFather()); + } SALOME::ByteVec *ret(PickelizedPyObjServer::FromCppToByteSeq(st)); enforcedRelease(); return ret; diff --git a/src/SALOMESDS/TestSalomeSDS2.py b/src/SALOMESDS/TestSalomeSDS2.py index eb1c1ce59..21fe1671f 100644 --- a/src/SALOMESDS/TestSalomeSDS2.py +++ b/src/SALOMESDS/TestSalomeSDS2.py @@ -23,7 +23,37 @@ import SalomeSDSClt import SALOME import salome import unittest +import cPickle import gc +import time +import multiprocessing as mp + +def obj2Str(obj): + return cPickle.dumps(obj,cPickle.HIGHEST_PROTOCOL) +def str2Obj(strr): + return cPickle.loads(strr) +def generateKey(varName,scopeName): + dsm=salome.naming_service.Resolve("/DataServerManager") + dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName) + assert(not isCreated) + t=dss.addKeyValueInVarHard(varName,obj2Str("ef"),obj2Str([11,14,100])) + time.sleep(3) + dss.atomicApply([t]) +def work(t): + i,varName,scopeName=t + if i==0: + generateKey(varName,scopeName) + return 0 + else: + import TestSalomeSDS3 + import os,subprocess + fname=os.path.splitext(TestSalomeSDS3.__file__)[0]+".py" + proc=subprocess.Popen(["python",fname],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + out,err=proc.communicate() + if proc.returncode!=0: + print out + print err + return proc.returncode class SalomeSDS2Test(unittest.TestCase): @@ -73,6 +103,32 @@ class SalomeSDS2Test(unittest.TestCase): self.assertRaises(Exception,a.__getitem__,"ab") a.ptr().getMyDataScopeServer().deleteVar("a") + def testTransaction1(self): + scopeName="Scope1" + varName="a" + dsm=salome.naming_service.Resolve("/DataServerManager") + dsm.cleanScopesInNS() + if scopeName in dsm.listScopes(): + dsm.removeDataScope(scopeName) + dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName) + assert(isCreated) + # + t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]})) + dss.atomicApply([t0]) + # + t1=dss.addKeyValueInVarHard(varName,obj2Str("cd"),obj2Str([7,8,9,10])) + dss.atomicApply([t1]) + # + assert(str2Obj(dss.fetchSerializedContent(varName))=={'ab':[4,5,6],'cd':[7,8,9,10]}) + wk=dss.waitForKeyInVar(varName,obj2Str("cd")) + assert(str2Obj(wk.waitFor())==[7,8,9,10]) + # + nbProc=8 + pool=mp.Pool(processes=nbProc) + asyncResult=pool.map_async(work,[(i,varName,scopeName) for i in xrange(nbProc)]) + assert(asyncResult.get()==nbProc*[0]) + dsm.removeDataScope(scopeName) + def setUp(self): salome.salome_init() pass diff --git a/src/SALOMESDS/TestSalomeSDS3.py b/src/SALOMESDS/TestSalomeSDS3.py new file mode 100644 index 000000000..fc3fd0f3d --- /dev/null +++ b/src/SALOMESDS/TestSalomeSDS3.py @@ -0,0 +1,25 @@ +import SALOME +import cPickle +import salome +import sys + +salome.salome_init() + +scopeName="Scope1" +varName="a" + +def obj2Str(obj): + return cPickle.dumps(obj,cPickle.HIGHEST_PROTOCOL) + +def str2Obj(strr): + return cPickle.loads(strr) + +def waitKey(): + dsm=salome.naming_service.Resolve("/DataServerManager") + dss,isCreated=dsm.giveADataScopeTransactionCalled(scopeName) + assert(not isCreated) + wk=dss.waitForKeyInVar(varName,obj2Str("ef")) + return str2Obj(wk.waitFor())==[11,14,100] + +if __name__=="__main__": + sys.exit(not int(waitKey())) -- 2.39.2