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})
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)
void DataScopeServerBase::initializePython(int argc, char *argv[])
{
Py_Initialize();
+ PyEval_InitThreads();
PySys_SetArgv(argc,argv);
PyObject *mainmod(PyImport_AddModule("__main__"));
_globals=PyModule_GetDict(mainmod);
#include "SALOMESDS_Defines.hxx"
#include <Python.h>
+#include <pthread.h>
#include <string>
#include <vector>
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:
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;
};
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
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;
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):
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
--- /dev/null
+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()))