KernelHelpers
SALOMEDS
SALOMEDSImpl
+ SALOMESDS
Utils
UnitTests
connect
interface DataServerManager;
- interface DataScopeServer
+ interface DataScopeServerBase
{
void ping();
string getScopeName();
StringVec listVars();
- BasicDataServer retrieveVar(in string varName) raises (SALOME::SALOME_Exception);
+ boolean existVar(in string varName) raises (SALOME::SALOME_Exception);
void deleteVar(in string varName) raises (SALOME::SALOME_Exception);
+ void shutdownIfNotHostedByDSM();
+ };
+
+ interface DataScopeServer : DataScopeServerBase
+ {
+ BasicDataServer retrieveVar(in string varName) raises (SALOME::SALOME_Exception);
PickelizedPyObjRdOnlyServer createRdOnlyVar(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
PickelizedPyObjRdExtServer createRdExtVar(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
//PickelizedPyObjRdWrServer createRdWrVar(in string typeName, in string varName) raises (SALOME::SALOME_Exception);
- void shutdownIfNotHostedByDSM();
+ };
+
+ interface Transaction
+ {
+ };
+
+ typedef sequence<Transaction> ListOfTransaction;
+
+ interface KeyWaiter
+ {
+ ByteVec waitFor() raises (SALOME::SALOME_Exception);
+ };
+
+ interface DataScopeServerTransaction : DataScopeServerBase
+ {
+ ByteVec fetchSerializedContent(in string varName) raises (SALOME::SALOME_Exception);
+ Transaction createRdOnlyVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+ Transaction createRdExtVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+ Transaction createRdWrVarTransac(in string varName, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+ Transaction addKeyValueInVarHard(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+ Transaction addKeyValueInVarErrorIfAlreadyExisting(in string varName, in ByteVec keyValue, in ByteVec constValue) raises (SALOME::SALOME_Exception);
+ Transaction removeKeyInVarErrorIfNotAlreadyExisting(in string varName, in ByteVec keyValue) raises (SALOME::SALOME_Exception);
+ 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
StringVec listAliveAndKickingScopes() raises (SALOME::SALOME_Exception);
DataScopeServer getDefaultScope() raises (SALOME::SALOME_Exception);
boolean isAliveAndKicking(in string scopeName) raises (SALOME::SALOME_Exception);
+ //
DataScopeServer createDataScope(in string scopeName) raises (SALOME::SALOME_Exception);
- DataScopeServer retriveDataScope(in string scopeName) raises (SALOME::SALOME_Exception);
DataScopeServer giveADataScopeCalled(in string scopeName, out boolean isCreated);
+ //
+ DataScopeServerTransaction createDataScopeTransaction(in string scopeName) raises (SALOME::SALOME_Exception);
+ DataScopeServerTransaction giveADataScopeTransactionCalled(in string scopeName, out boolean isCreated);
+ //
+ DataScopeServerBase retriveDataScope(in string scopeName) raises (SALOME::SALOME_Exception);
void removeDataScope(in string scopeName) raises (SALOME::SALOME_Exception);
void cleanScopesInNS();
void shutdownScopes() raises (SALOME::SALOME_Exception);
SALOMESDS_PickelizedPyObjRdOnlyServer.cxx
SALOMESDS_PickelizedPyObjRdExtServer.cxx
SALOMESDS_PickelizedPyObjRdWrServer.cxx
+ SALOMESDS_Transaction.cxx
+ SALOMESDS_KeyWaiter.cxx
)
ADD_LIBRARY(SalomeSDS ${SalomeSDS_SOURCES})
TARGET_LINK_LIBRARIES(SALOME_DataScopeServer SalomeSDS)
INSTALL(TARGETS SALOME_DataScopeServer DESTINATION ${SALOME_INSTALL_BINS})
INSTALL(FILES SalomeSDSClt.py DESTINATION ${SALOME_INSTALL_BINS})
-
FILE(GLOB COMMON_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx")
INSTALL(FILES ${COMMON_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS})
+# tests part
+SET(LOCAL_TEST_DIR ${KERNEL_TEST_DIR}/SALOMESDS)
+INSTALL(FILES TestSalomeSDS.py TestSalomeSDSHelper0.py DESTINATION ${LOCAL_TEST_DIR})
+INSTALL(FILES CTestTestfileInstall.cmake DESTINATION ${LOCAL_TEST_DIR} RENAME CTestTestfile.cmake)
--- /dev/null
+# Copyright (C) 2015 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+IF(NOT WIN32)
+ ADD_TEST(TestSalomeSDS python ${SALOME_TEST_DRIVER} ${TIMEOUT} TestSalomeSDS.py)
+ SET_TESTS_PROPERTIES(TestSalomeSDS PROPERTIES LABELS "${COMPONENT_NAME}" ENVIRONMENT "PYTHONPATH=${KERNEL_TEST_LIB}:$ENV{PYTHONPATH}")
+ENDIF(NOT WIN32)
#include "SALOMESDS_Exception.hxx"
+#include "omniORB4/CORBA.h"
+
namespace SALOMESDS
{
+ class POAHolder : public virtual PortableServer::ServantBase
+ {
+ public:
+ virtual PortableServer::POA_var getPOA() const = 0;
+ CORBA::Object_var activate()
+ {
+ PortableServer::POA_var poa(getPOA());
+ PortableServer::ObjectId_var id(poa->activate_object(this));
+ CORBA::Object_var ret(poa->id_to_reference(id));
+ return ret;
+ }
+
+ void enforcedRelease()
+ {
+ PortableServer::POA_var poa(getPOA());
+ PortableServer::ObjectId_var oid(poa->servant_to_id(this));
+ poa->deactivate_object(oid);
+ _remove_ref();
+ }
+ };
+
template<class T>
class AutoRefCountPtr
{
ptr->incrRef();
return ret;
}
+
+ template<class T>// T is expected to be a POAHolder subclass
+ class AutoServantPtr
+ {
+ public:
+ AutoServantPtr(T *ptr=0):_ptr(ptr) { }
+ ~AutoServantPtr() { destroyPtr(); }
+ bool operator==(const AutoServantPtr& other) const { return _ptr==other._ptr; }
+ bool operator==(const T *other) const { return _ptr==other; }
+ AutoServantPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; }
+ T *operator->() { return _ptr ; }
+ const T *operator->() const { return _ptr; }
+ T& operator*() { return *_ptr; }
+ const T& operator*() const { return *_ptr; }
+ operator T *() { return _ptr; }
+ operator const T *() const { return _ptr; }
+ private:
+ void destroyPtr()
+ {
+ if(!_ptr)
+ return;
+ _ptr->enforcedRelease();
+ }
+ private:
+ T *_ptr;
+ };
}
#endif
using namespace SALOMESDS;
-BasicDataServer::BasicDataServer(DataScopeServer *father, const std::string& varName):_father(father),_var_name(varName)
+BasicDataServer::BasicDataServer(DataScopeServerBase *father, const std::string& varName):_father(father),_var_name(varName)
{
+ /*PortableServer::POA_var poa(_father->getPOA());
+ PortableServer::POAManager_var pman(poa->the_POAManager());
+ CORBA::Object_var obj(_father->getORB()->resolve_initial_references("RootPOA"));
+ PortableServer::POA_var rootPOA(PortableServer::POA::_narrow(obj));
+ CORBA::PolicyList policies;
+ policies.length(1);
+ PortableServer::ThreadPolicy_var threadPol(rootPOA->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
+ policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
+ std::ostringstream poaName; poaName << "POA_" << POA_CNT++ << "_" << _var_name;
+ _poa=rootPOA->create_POA(poaName.str().c_str(),pman,policies);
+ threadPol->destroy();*/
}
SALOME::DataScopeServer_ptr BasicDataServer::getMyDataScopeServer()
{
- CORBA::Object_var obj(getPOA()->servant_to_reference(_father));
+ CORBA::Object_var obj(_father->getPOA()->servant_to_reference(_father));
return SALOME::DataScopeServer::_narrow(obj);
}
enforcedRelease();
}
-PortableServer::POA_var BasicDataServer::getPOA()
+PortableServer::POA_var BasicDataServer::getPOA() const
{
return _father->getPOA();
}
namespace SALOMESDS
{
- class DataScopeServer;
+ class DataScopeServerBase;
class BasicDataServer : public RefCountServ, public virtual POA_SALOME::BasicDataServer
{
public:
- BasicDataServer(DataScopeServer *father, const std::string& varName);
+ BasicDataServer(DataScopeServerBase *father, const std::string& varName);
SALOME::DataScopeServer_ptr getMyDataScopeServer();
char *getVarName();
char *getScopeName();
void UnRegister();
void Destroy();
public:
+ DataScopeServerBase *getFather() const { return _father; }
std::string getVarNameCpp() const { return _var_name; }
protected:
- PortableServer::POA_var getPOA();
+ PortableServer::POA_var getPOA() const;
protected:
- DataScopeServer *_father;
+ DataScopeServerBase *_father;
private:
std::string _var_name;
};
#include "SALOMESDS_PickelizedPyObjRdOnlyServer.hxx"
#include "SALOMESDS_PickelizedPyObjRdExtServer.hxx"
#include "SALOMESDS_PickelizedPyObjRdWrServer.hxx"
+#include "SALOMESDS_KeyWaiter.hxx"
+#include "SALOMESDS_Transaction.hxx"
#include "SALOME_NamingService.hxx"
#include "SALOMESDS_Exception.hxx"
using namespace SALOMESDS;
-std::size_t DataScopeServer::COUNTER=0;
+std::size_t DataScopeServerBase::COUNTER=0;
-DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName)
+DataScopeServerBase::DataScopeServerBase(CORBA::ORB_ptr orb, const std::string& scopeName):_globals(0),_locals(0),_pickler(0),_orb(CORBA::ORB::_duplicate(orb)),_name(scopeName)
{
}
-DataScopeServer::DataScopeServer(const DataScopeServer& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars)
+DataScopeServerBase::DataScopeServerBase(const DataScopeServerBase& other):_globals(0),_locals(0),_pickler(0),_name(other._name),_vars(other._vars)
{
}
-DataScopeServer::~DataScopeServer()
+DataScopeServerBase::~DataScopeServerBase()
{
// _globals is borrowed ref -> do nothing
Py_XDECREF(_locals);
/*!
* Called remotely -> to protect against throw
*/
-void DataScopeServer::ping()
+void DataScopeServerBase::ping()
{
}
/*!
* Called remotely -> to protect against throw
*/
-char *DataScopeServer::getScopeName()
+char *DataScopeServerBase::getScopeName()
{
return CORBA::string_dup(_name.c_str());
}
/*!
* Called remotely -> to protect against throw
*/
-SALOME::StringVec *DataScopeServer::listVars()
+SALOME::StringVec *DataScopeServerBase::listVars()
{
SALOME::StringVec *ret(new SALOME::StringVec);
std::size_t sz(_vars.size());
return ret;
}
-SALOME::BasicDataServer_ptr DataScopeServer::retrieveVar(const char *varName)
+CORBA::Boolean DataScopeServerBase::existVar(const char *varName)
{
- std::string varNameCpp(varName);
- std::vector<std::string> allNames(getAllVarNames());
- std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
- if(it==allNames.end())
- {
- std::ostringstream oss; oss << "DataScopeServer::retrieveVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
- std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
- throw Exception(oss.str());
- }
- std::size_t pos(std::distance(allNames.begin(),it));
- std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::iterator it0(_vars.begin());
- for(std::size_t i=0;i<pos;i++,it0++);
+ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it(_vars.begin());
+ for(;it!=_vars.end();it++)
+ if((*it).second->getVarNameCpp()==varName)
+ return true;
+ return false;
+}
+
+SALOME::BasicDataServer_ptr DataScopeServerBase::retrieveVarInternal(const char *varName)
+{
+ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
return SALOME::BasicDataServer::_duplicate((*it0).first);
}
-void DataScopeServer::deleteVar(const char *varName)
+BasicDataServer *DataScopeServerBase::retrieveVarInternal2(const std::string& varName)
+{
+ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(retrieveVarInternal3(varName));
+ return (*it0).second;
+}
+
+void DataScopeServerBase::deleteVar(const char *varName)
{
std::string varNameCpp(varName);
std::vector<std::string> allNames(getAllVarNames());
std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varNameCpp));
if(it==allNames.end())
{
- std::ostringstream oss; oss << "DataScopeServer::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
+ std::ostringstream oss; oss << "DataScopeServerBase::deleteVar : name \"" << varNameCpp << "\" does not exists ! Possibilities are :";
std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
throw Exception(oss.str());
}
_vars.erase(it0);
}
-SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
-{
- std::string varNameCpp(varName);
- checkNotAlreadyExistingVar(varNameCpp);
- PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
- CORBA::Object_var ret(activateWithDedicatedPOA(tmp));
- std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
- _vars.push_back(p);
- return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
-}
-
-SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
-{
- std::string varNameCpp(varName);
- checkNotAlreadyExistingVar(varNameCpp);
- PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
- CORBA::Object_var ret(activateWithDedicatedPOA(tmp));
- std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
- _vars.push_back(p);
- return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
-}
-
-/*!
- * Called remotely -> to protect against throw
- */
-SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
-{
- std::string varNameCpp(varName),typeNameCpp(typeName);
- checkNotAlreadyExistingVar(varNameCpp);
- PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
- CORBA::Object_var ret(activateWithDedicatedPOA(tmp));
- std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
- _vars.push_back(p);
- return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
-}
-
-void DataScopeServer::shutdownIfNotHostedByDSM()
+void DataScopeServerBase::shutdownIfNotHostedByDSM()
{
SALOME_NamingService ns(_orb);
CORBA::Object_var obj(ns.Resolve(DataServerManager::NAME_IN_NS));
_orb->shutdown(0);
else
{
- PortableServer::ObjectId_var oid(_poa->servant_to_id(this));
- _poa->deactivate_object(oid);
- ret->_remove_ref();
+ enforcedRelease();
}
}
-void DataScopeServer::initializePython(int argc, char *argv[])
+void DataScopeServerBase::initializePython(int argc, char *argv[])
{
Py_Initialize();
+ PyEval_InitThreads();
PySys_SetArgv(argc,argv);
PyObject *mainmod(PyImport_AddModule("__main__"));
_globals=PyModule_GetDict(mainmod);
_pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
}
-void DataScopeServer::registerToSalomePiDict() const
+void DataScopeServerBase::registerToSalomePiDict() const
{
PyObject *mod(PyImport_ImportModule("addToKillList"));
if(!mod)
{ Py_XDECREF(mod); return ; }
PyObject *args(PyTuple_New(2));
PyTuple_SetItem(args,0,PyInt_FromLong(getpid()));
- PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServer"));
+ PyTuple_SetItem(args,1,PyString_FromString("SALOME_DataScopeServerBase"));
PyObject *res(PyObject_CallObject(meth,args));
Py_XDECREF(args);
Py_XDECREF(res);
Py_XDECREF(mod);
}
-/*!
- * \a ptr has been activated by the POA \a poa.
- */
-void DataScopeServer::setPOAAndRegister(PortableServer::POA_var poa, SALOME::DataScopeServer_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());
}
-std::string DataScopeServer::BuildTmpVarNameFrom(const std::string& varName)
+std::string DataScopeServerBase::BuildTmpVarNameFrom(const std::string& varName)
{
std::ostringstream oss;
oss << varName << "@" << COUNTER++;
return oss.str();
}
-std::vector< std::string > DataScopeServer::getAllVarNames() const
+std::vector< std::string > DataScopeServerBase::getAllVarNames() const
{
std::size_t sz(_vars.size());
std::vector<std::string> ret(sz);
return ret;
}
-CORBA::Object_var DataScopeServer::activateWithDedicatedPOA(BasicDataServer *ds)
+void DataScopeServerBase::checkNotAlreadyExistingVar(const std::string& varName) const
{
- PortableServer::ObjectId_var id(_poa->activate_object(ds));
- CORBA::Object_var ret(_poa->id_to_reference(id));
+ std::vector<std::string> allNames(getAllVarNames());
+ std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
+ if(it!=allNames.end())
+ {
+ std::ostringstream oss; oss << "DataScopeServerBase::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
+ throw Exception(oss.str());
+ }
+}
+
+void DataScopeServerBase::checkExistingVar(const std::string& varName) const
+{
+ std::vector<std::string> allNames(getAllVarNames());
+ std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
+ if(it==allNames.end())
+ {
+ std::ostringstream oss; oss << "DataScopeServerBase::checkExistingVar : name \"" << varName << "\" does not exist !";
+ throw Exception(oss.str());
+ }
+}
+
+PickelizedPyObjServer *DataScopeServerBase::checkVarExistingAndDict(const std::string& varName)
+{
+ checkExistingVar(varName);
+ BasicDataServer *var(retrieveVarInternal2(varName.c_str()));
+ PickelizedPyObjServer *ret(dynamic_cast<PickelizedPyObjServer *>(var));
+ if(!ret)
+ {
+ std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not serialized !";
+ throw Exception(oss.str());
+ }
+ if(!ret->isDict())
+ {
+ std::ostringstream oss; oss << "TransactionAddKeyValueHard::prepareRollBackInCaseOfFailure : var \"" << varName << "\"exists but it is not a Dict !";
+ throw Exception(oss.str());
+ }
return ret;
}
-void DataScopeServer::checkNotAlreadyExistingVar(const std::string& varName)
+std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator DataScopeServerBase::retrieveVarInternal3(const std::string& varName) const
{
std::vector<std::string> allNames(getAllVarNames());
std::vector<std::string>::iterator it(std::find(allNames.begin(),allNames.end(),varName));
- if(it!=allNames.end())
+ if(it==allNames.end())
{
- std::ostringstream oss; oss << "DataScopeServer::checkNotAlreadyExistingVar : name \"" << varName << "\" already exists !";
+ std::ostringstream oss; oss << "DataScopeServerBase::retrieveVarInternal : name \"" << varName << "\" does not exists ! Possibilities are :";
+ std::copy(allNames.begin(),allNames.end(),std::ostream_iterator<std::string>(oss,", "));
throw Exception(oss.str());
}
+ std::size_t pos(std::distance(allNames.begin(),it));
+ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator it0(_vars.begin());
+ for(std::size_t i=0;i<pos;i++,it0++);
+ return it0;
+}
+
+///////
+
+DataScopeServer::DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName):DataScopeServerBase(orb,scopeName)
+{
+}
+
+DataScopeServer::DataScopeServer(const DataScopeServer& other):DataScopeServerBase(other)
+{
+}
+
+SALOME::PickelizedPyObjRdOnlyServer_ptr DataScopeServer::createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue)
+{
+ std::string varNameCpp(varName);
+ checkNotAlreadyExistingVar(varNameCpp);
+ PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varNameCpp,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+ return SALOME::PickelizedPyObjRdOnlyServer::_narrow(ret);
+}
+
+SALOME::PickelizedPyObjRdExtServer_ptr DataScopeServer::createRdExtVar(const char *varName, const SALOME::ByteVec& constValue)
+{
+ std::string varNameCpp(varName);
+ checkNotAlreadyExistingVar(varNameCpp);
+ PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varNameCpp,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+ return SALOME::PickelizedPyObjRdExtServer::_narrow(ret);
}
+
+/*!
+ * Called remotely -> to protect against throw
+ */
+SALOME::PickelizedPyObjRdWrServer_ptr DataScopeServer::createRdWrVar(const char *typeName, const char *varName)
+{
+ std::string varNameCpp(varName),typeNameCpp(typeName);
+ checkNotAlreadyExistingVar(varNameCpp);
+ PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,typeNameCpp,varNameCpp));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+ return SALOME::PickelizedPyObjRdWrServer::_narrow(ret);
+}
+
+DataScopeServer::~DataScopeServer()
+{
+}
+
+////////
+
+DataScopeServerTransaction::DataScopeServerTransaction(CORBA::ORB_ptr orb, const std::string& scopeName):DataScopeServerBase(orb,scopeName)
+{
+ CORBA::Object_var obj(_orb->resolve_initial_references("RootPOA"));
+ PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
+ //
+ PortableServer::POAManager_var mgr(poa->the_POAManager());
+ CORBA::PolicyList policies;
+ policies.length(1);
+ PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::ORB_CTRL_MODEL));
+ policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
+ PortableServer::POA_var poa2(poa->create_POA("POAForWaiters",mgr,policies));
+ threadPol->destroy();
+ //
+ _poa_for_key_waiter=poa2;
+}
+
+DataScopeServerTransaction::DataScopeServerTransaction(const DataScopeServerTransaction& other):DataScopeServerBase(other),_poa_for_key_waiter(other.getPOA4KeyWaiter())
+{
+}
+
+void DataScopeServerTransaction::createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ PickelizedPyObjRdOnlyServer *tmp(new PickelizedPyObjRdOnlyServer(this,varName,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+}
+
+void DataScopeServerTransaction::createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ PickelizedPyObjRdExtServer *tmp(new PickelizedPyObjRdExtServer(this,varName,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+}
+
+void DataScopeServerTransaction::createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ PickelizedPyObjRdWrServer *tmp(new PickelizedPyObjRdWrServer(this,varName,constValue));
+ CORBA::Object_var ret(tmp->activate());
+ std::pair< SALOME::BasicDataServer_var, BasicDataServer * > p(SALOME::BasicDataServer::_narrow(ret),tmp);
+ _vars.push_back(p);
+}
+
+SALOME::ByteVec *DataScopeServerTransaction::fetchSerializedContent(const char *varName)
+{
+ BasicDataServer *var(retrieveVarInternal2(varName));
+ PickelizedPyObjServer *varc(dynamic_cast<PickelizedPyObjServer *>(var));
+ if(!varc)
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::fetchSerializedContent : var \"" << varName << "\"exists but it is not serialized !";
+ throw Exception(oss.str());
+ }
+ return varc->fetchSerializedContent();
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdOnlyVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ TransactionRdOnlyVarCreate *ret(new TransactionRdOnlyVarCreate(this,varName,constValue));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ TransactionRdExtVarCreate *ret(new TransactionRdExtVarCreate(this,varName,constValue));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue)
+{
+ checkNotAlreadyExistingVar(varName);
+ TransactionRdWrVarCreate *ret(new TransactionRdWrVarCreate(this,varName,constValue));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+void DataScopeServerTransaction::addWaitKey(KeyWaiter *kw)
+{
+ if(!kw)
+ throw Exception("DataScopeServerTransaction::addWaitKey : NULL input object !");
+ _waiting_keys.push_back(kw);
+}
+
+void DataScopeServerTransaction::pingKey(PyObject *keyObj)
+{
+ PyObject *cmpObj(getPyCmpFunc());
+ if(!keyObj)
+ 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());
+ PyTuple_SetItem(args,1,waitKey); Py_XINCREF(waitKey);
+ PyObject *res(PyObject_CallObject(cmpObj,args));
+ if(res==NULL)
+ {
+ 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)
+{
+ checkVarExistingAndDict(varName);
+ TransactionAddKeyValueHard *ret(new TransactionAddKeyValueHard(this,varName,key,value));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value)
+{
+ checkVarExistingAndDict(varName);
+ TransactionAddKeyValueErrorIfAlreadyExisting *ret(new TransactionAddKeyValueErrorIfAlreadyExisting(this,varName,key,value));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::Transaction_ptr DataScopeServerTransaction::removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key)
+{
+ checkVarExistingAndDict(varName);
+ TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,key));
+ CORBA::Object_var obj(ret->activate());
+ return SALOME::Transaction::_narrow(obj);
+}
+
+SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal)
+{
+ PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
+ KeyWaiter *ret(new KeyWaiter(pickelObj,keyVal));
+ CORBA::Object_var obj(ret->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
+ return SALOME::KeyWaiter::_narrow(obj);
+}
+
+SALOME::KeyWaiter_ptr DataScopeServerTransaction::waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac)
+{
+ PickelizedPyObjServer *pickelObj(checkVarExistingAndDict(varName));
+ KeyWaiter *ret0(new KeyWaiter(pickelObj,keyVal));
+ CORBA::Object_var obj(ret0->activate());//KeyWaiter instance activated inside a multithread POA contrary to all of objects in SALOMESDS in single thread !
+ //
+ TransactionRemoveKeyInVarErrorIfNotAlreadyExisting *ret1(new TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(this,varName,keyVal));
+ CORBA::Object_var obj2(ret1->activate());
+ transac=SALOME::Transaction::_narrow(obj2);
+ //
+ 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:
+ TrustTransaction():_must_rollback(0),_ptr(0) { }
+ void setTransaction(Transaction *t, bool *mustRollback) { if(!t || !mustRollback) throw Exception("TrustTransaction Error #1"); _ptr=t; _must_rollback=mustRollback; _ptr->prepareRollBackInCaseOfFailure(); }
+ void operate() { _ptr->perform(); }
+ ~TrustTransaction() { if(!_ptr) return ; if(*_must_rollback) _ptr->rollBack(); }
+private:
+ bool *_must_rollback;
+ Transaction *_ptr;
+};
+
+void DataScopeServerTransaction::atomicApply(const SALOME::ListOfTransaction& transactions)
+{
+ std::size_t sz(transactions.length());
+ if(sz==0)
+ return ;
+ std::vector< AutoServantPtr<Transaction> > transactionsCpp(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ PortableServer::ServantBase *eltBase(0);
+ Transaction *elt(0);
+ try
+ {
+ eltBase=_poa->reference_to_servant(transactions[i]);
+ elt=dynamic_cast<Transaction *>(eltBase);
+ }
+ catch(...)
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is invalid !";
+ throw Exception(oss.str());
+ }
+ if(!elt)
+ {
+ std::ostringstream oss; oss << "DataScopeServerTransaction::atomicApply : the elt #" << i << " is null ?";
+ throw Exception(oss.str());
+ }
+ elt->_remove_ref();
+ transactionsCpp[i]=elt;
+ }
+ {// important do not merge loops !
+ std::vector<TrustTransaction> transactions2(sz);
+ bool mustRollback(true);
+ for(std::size_t i=0;i<sz;i++)
+ transactions2[i].setTransaction(transactionsCpp[i],&mustRollback);
+ for(std::size_t i=0;i<sz;i++)
+ transactions2[i].operate();
+ mustRollback=false;
+ }
+ for(std::size_t i=0;i<sz;i++)
+ transactionsCpp[i]->notify();
+}
+
+/*!
+ * Returns borrowed reference.
+ */
+PyObject *DataScopeServerTransaction::getPyCmpFunc()
+{
+ PyObject *builtins(PyDict_GetItemString(_globals,"__builtins__"));//borrowed
+ if(builtins==NULL)
+ throw Exception("Fail to find reference to builtins !");
+ PyObject *builtins2(PyModule_GetDict(builtins));//borrowed
+ if(builtins2==NULL)
+ throw Exception("Fail to invoke __dict__ on builtins !");
+ PyObject *cmpObj(PyDict_GetItemString(builtins2,"cmp"));
+ if(cmpObj==NULL)
+ throw Exception("Fail to find cmp in __builtins__ !");
+ return cmpObj;
+}
+
+DataScopeServerTransaction::~DataScopeServerTransaction()
+{
+}
+
namespace SALOMESDS
{
- class SALOMESDS_EXPORT DataScopeServer : public virtual POA_SALOME::DataScopeServer
+ class KeyWaiter;
+ class PickelizedPyObjServer;
+
+ class SALOMESDS_EXPORT DataScopeServerBase : public virtual POA_SALOME::DataScopeServerBase, public POAHolder
{
public:
- DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName);
- DataScopeServer(const DataScopeServer& other);
+ DataScopeServerBase(CORBA::ORB_ptr orb, const std::string& scopeName);
+ DataScopeServerBase(const DataScopeServerBase& other);
void ping();
char *getScopeName();
SALOME::StringVec *listVars();
- SALOME::BasicDataServer_ptr retrieveVar(const char *varName);
+ CORBA::Boolean existVar(const char *varName);
+ SALOME::BasicDataServer_ptr retrieveVarInternal(const char *varName);
+ BasicDataServer *retrieveVarInternal2(const std::string& varName);
void deleteVar(const char *varName);
- SALOME::PickelizedPyObjRdOnlyServer_ptr createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue);
- SALOME::PickelizedPyObjRdExtServer_ptr createRdExtVar(const char *varName, const SALOME::ByteVec& constValue);
- SALOME::PickelizedPyObjRdWrServer_ptr createRdWrVar(const char *typeName, const char *varName);
void shutdownIfNotHostedByDSM();
- ~DataScopeServer();
+ ~DataScopeServerBase();
public:
void initializePython(int argc, char *argv[]);
void registerToSalomePiDict() const;
- void setPOAAndRegister(PortableServer::POA_var poa, SALOME::DataScopeServer_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() { return _poa; }
+ PortableServer::POA_var getPOA() const { return _poa; }
+ CORBA::ORB_var getORB() { return _orb; }
+ std::string getScopeNameCpp() const { return _name; }
static std::string BuildTmpVarNameFrom(const std::string& varName);
- private:
+ public:
std::vector< std::string> getAllVarNames() const;
- CORBA::Object_var activateWithDedicatedPOA(BasicDataServer *ds);
- void checkNotAlreadyExistingVar(const std::string& varName);
- private:
+ void checkNotAlreadyExistingVar(const std::string& varName) const;
+ void checkExistingVar(const std::string& varName) const;
+ PickelizedPyObjServer *checkVarExistingAndDict(const std::string& varName);
+ protected:
+ std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > >::const_iterator retrieveVarInternal3(const std::string& varName) const;
+ protected:
PyObject *_globals;
PyObject *_locals;
PyObject *_pickler;
std::list< std::pair< SALOME::BasicDataServer_var, BasicDataServer * > > _vars;
static std::size_t COUNTER;
};
+
+ class SALOMESDS_EXPORT DataScopeServer : public DataScopeServerBase, public virtual POA_SALOME::DataScopeServer
+ {
+ public:
+ DataScopeServer(CORBA::ORB_ptr orb, const std::string& scopeName);
+ DataScopeServer(const DataScopeServer& other);
+ SALOME::BasicDataServer_ptr retrieveVar(const char *varName) { return retrieveVarInternal(varName); }
+ SALOME::PickelizedPyObjRdOnlyServer_ptr createRdOnlyVar(const char *varName, const SALOME::ByteVec& constValue);
+ SALOME::PickelizedPyObjRdExtServer_ptr createRdExtVar(const char *varName, const SALOME::ByteVec& constValue);
+ SALOME::PickelizedPyObjRdWrServer_ptr createRdWrVar(const char *typeName, const char *varName);
+ ~DataScopeServer();
+ };
+
+ class SALOMESDS_EXPORT DataScopeServerTransaction : public DataScopeServerBase, public virtual POA_SALOME::DataScopeServerTransaction
+ {
+ public://not remotely callable
+ DataScopeServerTransaction(CORBA::ORB_ptr orb, const std::string& scopeName);
+ DataScopeServerTransaction(const DataScopeServerTransaction& other);
+ ~DataScopeServerTransaction();
+ void createRdOnlyVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
+ void createRdExtVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
+ void createRdWrVarInternal(const std::string& varName, const SALOME::ByteVec& constValue);
+ PortableServer::POA_var getPOA4KeyWaiter() const { return _poa_for_key_waiter; }
+ 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);
+ SALOME::Transaction_ptr createRdExtVarTransac(const char *varName, const SALOME::ByteVec& constValue);
+ SALOME::Transaction_ptr createRdWrVarTransac(const char *varName, const SALOME::ByteVec& constValue);
+ SALOME::Transaction_ptr addKeyValueInVarHard(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+ SALOME::Transaction_ptr addKeyValueInVarErrorIfAlreadyExisting(const char *varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+ SALOME::Transaction_ptr removeKeyInVarErrorIfNotAlreadyExisting(const char *varName, const SALOME::ByteVec& key);
+ SALOME::KeyWaiter_ptr waitForKeyInVar(const char *varName, const SALOME::ByteVec& keyVal);
+ SALOME::KeyWaiter_ptr waitForKeyInVarAndKillIt(const char *varName, const SALOME::ByteVec& keyVal, SALOME::Transaction_out transac);
+ void atomicApply(const SALOME::ListOfTransaction& transactions);
+ private:
+ PyObject *getPyCmpFunc();
+ private:
+ PortableServer::POA_var _poa_for_key_waiter;
+ std::list< KeyWaiter * > _waiting_keys;
+ };
}
#endif
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()
SALOME::DataScopeServer_ptr DataServerManager::getDefaultScope()
{
- return retriveDataScope(DFT_SCOPE_NAME_IN_NS);
+ SALOME::DataScopeServerBase_var ret(retriveDataScope(DFT_SCOPE_NAME_IN_NS));
+ if(CORBA::is_nil(ret))
+ return SALOME::DataScopeServer::_narrow(ret);
+ SALOME::DataScopeServer_ptr ret2(SALOME::DataScopeServer::_narrow(ret));
+ if(CORBA::is_nil(ret2))
+ throw Exception("DataServerManager::getDefaultScope : exists but has not expected sub type !");
+ return ret2;
}
CORBA::Boolean DataServerManager::isAliveAndKicking(const char *scopeName)
{
- SALOME::DataScopeServer_var scopePtr(getScopePtrGivenName(scopeName));
- CORBA::Boolean ret(true);
- try
- {
- scopePtr->ping();
- }
- catch(...)
- { ret=false; }
- return ret;
+ SALOME::DataScopeServerBase_var scopePtr(getScopePtrGivenName(scopeName));
+ return IsAliveAndKicking(scopePtr);
}
-SALOME::DataScopeServer_ptr DataServerManager::createDataScope(const char *scopeName)
+template<class T>
+typename T::PtrType CreateDataScope(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns)
{
- std::string scopeNameCpp(scopeName);
- std::vector<std::string> scopes(listOfScopesCpp());
- if(std::find(scopes.begin(),scopes.end(),scopeNameCpp)!=scopes.end())
+ int isTransactionInt(T::IsTransaction);
+ if(std::find(scopes.begin(),scopes.end(),scopeName)!=scopes.end())
{
std::ostringstream oss; oss << "DataServerManager::createDataScope : scope name \"" << scopeName << "\" already exists !";
throw Exception(oss.str());
}
//
- SALOME_NamingService ns(_orb);
- std::string fullScopeName(CreateAbsNameInNSFromScopeName(scopeName));
- std::ostringstream oss; oss << "SALOME_DataScopeServer" << " " << scopeName << " ";
+ std::string fullScopeName(DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
+ std::ostringstream oss; oss << "SALOME_DataScopeServer" << " " << scopeName << " " << isTransactionInt << " ";
SALOME_ContainerManager::AddOmninamesParams(oss,&ns);
std::string command(oss.str());
SALOME_ContainerManager::MakeTheCommandToBeLaunchedASync(command);
int status(SALOME_ContainerManager::SystemThreadSafe(command.c_str()));
int count(SALOME_ContainerManager::GetTimeOutToLoaunchServer());
- SALOME::DataScopeServer_var ret(SALOME::DataScopeServer::_nil());
+ typename T::VarType ret(T::nil());
while (CORBA::is_nil(ret) && count)
{
SALOME_ContainerManager::SleepInSecond(1);
count--;
CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
- ret=SALOME::DataScopeServer::_narrow(obj);
+ ret=T::narrow(obj);
}
- return SALOME::DataScopeServer::_duplicate(ret);
+ return T::duplicate(ret);
}
-SALOME::DataScopeServer_ptr DataServerManager::giveADataScopeCalled(const char *scopeName, CORBA::Boolean& isCreated)
+template<class T>
+typename T::PtrType GiveADataScopeCalled(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns, CORBA::Boolean& isCreated)
{
- std::string scopeNameCpp(scopeName);
- std::vector<std::string> scopes(listOfScopesCpp());
- if(std::find(scopes.begin(),scopes.end(),scopeNameCpp)==scopes.end())
+ if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
{
isCreated=true;
- return createDataScope(scopeName);
+ return CreateDataScope<T>(scopeName,scopes,ns);
}
else
{
- if(isAliveAndKicking(scopeName))
+ SALOME::DataScopeServerBase_var ret(SALOMESDS::DataServerManager::GetScopePtrGivenName(scopeName,scopes,ns));
+ if(SALOMESDS::DataServerManager::IsAliveAndKicking(ret))
{
isCreated=false;
- return retriveDataScope(scopeName);
+ typename T::PtrType ret2(T::narrow(ret));
+ if(CORBA::is_nil(ret))
+ return ret2;
+ if(CORBA::is_nil(ret2))
+ {
+ std::ostringstream oss; oss << "DataServerManager::giveADataScopeCalled : scope \"" << scopeName << "\" exists but with invalid type !";
+ throw Exception(oss.str());
+ }
+ return ret2;
}
else
{
- SALOME_NamingService ns(_orb);
- std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(scopeNameCpp));
+ std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
ns.Destroy_Name(fullScopeName.c_str());
isCreated=true;
- return createDataScope(scopeName);
+ return CreateDataScope<T>(scopeName,scopes,ns);
}
}
}
-SALOME::DataScopeServer_ptr DataServerManager::retriveDataScope(const char *scopeName)
+class NormalFunctor
+{
+public:
+ typedef SALOME::DataScopeServer_ptr PtrType;
+ typedef SALOME::DataScopeServer_var VarType;
+ typedef SALOME::DataScopeServer TheType;
+ static const bool IsTransaction=false;
+ static PtrType nil() { return SALOME::DataScopeServer::_nil(); }
+ static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServer::_narrow(obj); }
+ static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServer::_duplicate(obj); }
+};
+
+class TransactionFunctor
+{
+public:
+ typedef SALOME::DataScopeServerTransaction_ptr PtrType;
+ typedef SALOME::DataScopeServerTransaction_var VarType;
+ typedef SALOME::DataScopeServerTransaction TheType;
+ static const bool IsTransaction=true;
+ static PtrType nil() { return SALOME::DataScopeServerTransaction::_nil(); }
+ static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServerTransaction::_narrow(obj); }
+ static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServerTransaction::_duplicate(obj); }
+};
+
+SALOME::DataScopeServer_ptr DataServerManager::createDataScope(const char *scopeName)
+{
+ SALOME_NamingService ns(_orb);
+ return CreateDataScope<NormalFunctor>(scopeName,listOfScopesCpp(),ns);
+}
+
+SALOME::DataScopeServer_ptr DataServerManager::giveADataScopeCalled(const char *scopeName, CORBA::Boolean& isCreated)
+{
+ SALOME_NamingService ns(_orb);
+ return GiveADataScopeCalled<NormalFunctor>(scopeName,listOfScopesCpp(),ns,isCreated);
+}
+
+SALOME::DataScopeServerTransaction_ptr DataServerManager::createDataScopeTransaction(const char *scopeName)
+{
+ SALOME_NamingService ns(_orb);
+ return CreateDataScope<TransactionFunctor>(scopeName,listOfScopesCpp(),ns);
+}
+
+SALOME::DataScopeServerTransaction_ptr DataServerManager::giveADataScopeTransactionCalled(const char *scopeName, CORBA::Boolean& isCreated)
+{
+ SALOME_NamingService ns(_orb);
+ return GiveADataScopeCalled<TransactionFunctor>(scopeName,listOfScopesCpp(),ns,isCreated);
+}
+
+SALOME::DataScopeServerBase_ptr DataServerManager::retriveDataScope(const char *scopeName)
{
- SALOME::DataScopeServer_var ret(getScopePtrGivenName(scopeName));
- return SALOME::DataScopeServer::_duplicate(ret);
+ SALOME::DataScopeServerBase_var ret(getScopePtrGivenName(scopeName));
+ return SALOME::DataScopeServerBase::_duplicate(ret);
}
void DataServerManager::removeDataScope(const char *scopeName)
{
- SALOME::DataScopeServer_var scs(getScopePtrGivenName(scopeName));
+ SALOME::DataScopeServerBase_var scs(getScopePtrGivenName(scopeName));
scs->shutdownIfNotHostedByDSM();
}
return oss.str();
}
+CORBA::Boolean DataServerManager::IsAliveAndKicking(SALOME::DataScopeServerBase_ptr scopePtr)
+{
+ CORBA::Boolean ret(true);
+ try
+ {
+ scopePtr->ping();
+ }
+ catch(...)
+ { ret=false; }
+ return ret;
+}
+
std::vector<std::string> DataServerManager::listOfScopesCpp()
{
SALOME_NamingService ns(_orb);
return ret;
}
-SALOME::DataScopeServer_var DataServerManager::getScopePtrGivenName(const std::string& scopeName)
+SALOME::DataScopeServerBase_var DataServerManager::GetScopePtrGivenName(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns)
{
- std::vector<std::string> scopes(listOfScopesCpp());
std::size_t sz(scopes.size());
if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
{
std::ostringstream oss; oss << "DataServerManager::getScopePtrGivenName : scope name \"" << scopeName << "\" does not exist !";
throw Exception(oss.str());
}
- SALOME_NamingService ns(_orb);
std::string fullScopeName(CreateAbsNameInNSFromScopeName(scopeName));
CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
- SALOME::DataScopeServer_var ret(SALOME::DataScopeServer::_narrow(obj));
+ SALOME::DataScopeServerBase_var ret(SALOME::DataScopeServerBase::_narrow(obj));
return ret;
}
+
+SALOME::DataScopeServerBase_var DataServerManager::getScopePtrGivenName(const std::string& scopeName)
+{
+ SALOME_NamingService ns(_orb);
+ return GetScopePtrGivenName(scopeName,listOfScopesCpp(),ns);
+}
#include <string>
+class SALOME_NamingService;
+
namespace SALOMESDS
{
class DataScopeServer;
-
+
class SALOMESDS_EXPORT DataServerManager : public virtual POA_SALOME::DataServerManager
{
public:
SALOME::StringVec *listAliveAndKickingScopes();
SALOME::DataScopeServer_ptr getDefaultScope();
CORBA::Boolean isAliveAndKicking(const char *scopeName);
+ SALOME::DataScopeServerBase_ptr retriveDataScope(const char *scopeName);
+ //
SALOME::DataScopeServer_ptr createDataScope(const char *scopeName);
- SALOME::DataScopeServer_ptr retriveDataScope(const char *scopeName);
SALOME::DataScopeServer_ptr giveADataScopeCalled(const char *scopeName, CORBA::Boolean& isCreated);
+ //
+ SALOME::DataScopeServerTransaction_ptr createDataScopeTransaction(const char *scopeName);
+ SALOME::DataScopeServerTransaction_ptr giveADataScopeTransactionCalled(const char *scopeName, CORBA::Boolean& isCreated);
+ //
void removeDataScope(const char *scopeName);
void cleanScopesInNS();
void shutdownScopes();
+ public:
+ CORBA::ORB_var getORB() { return _orb; }
static std::string CreateAbsNameInNSFromScopeName(const std::string& scopeName);
+ static CORBA::Boolean IsAliveAndKicking(SALOME::DataScopeServerBase_ptr scopePtr);
+ static SALOME::DataScopeServerBase_var GetScopePtrGivenName(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns);
public:
static const char NAME_IN_NS[];
static const char DFT_SCOPE_NAME_IN_NS[];
private:
std::vector<std::string> listOfScopesCpp();
- SALOME::DataScopeServer_var getScopePtrGivenName(const std::string& scopeName);
+ SALOME::DataScopeServerBase_var getScopePtrGivenName(const std::string& scopeName);
private:
CORBA::ORB_var _orb;
//! single thread poa
--- /dev/null
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOMESDS_KeyWaiter.hxx"
+#include "SALOMESDS_DataScopeServer.hxx"
+#include "SALOMESDS_PickelizedPyObjServer.hxx"
+
+#include <sstream>
+
+using namespace SALOMESDS;
+
+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
+ 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(_var->getPyObj(),"__contains__"));//new ref
+ 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));
+ Py_XDECREF(args);
+ Py_XDECREF(selfMeth);
+ //
+ if(retPy!=Py_False && retPy!=Py_True)
+ throw Exception("KeyWaiter constructor : unexpected return of dict.__contains__ !");
+ if(retPy==Py_True)
+ {
+ PyObject *retPy2(PyDict_GetItem(_var->getPyObj(),_ze_key));
+ if(retPy2==NULL)
+ throw Exception("KeyWaiter constructor : dict.getitem fails !");
+ Py_XINCREF(retPy2);
+ _ze_value=retPy2;
+ go();//notify that value already arrives -> unlock
+ }
+ else
+ {
+ getDSS()->addWaitKey(this);// key not present let the DataScope managing it !
+ }
+ Py_XDECREF(retPy);
+}
+
+KeyWaiter::~KeyWaiter()
+{
+ Py_XDECREF(_ze_key);
+ if(_ze_value)
+ Py_XDECREF(_ze_value);
+}
+
+PortableServer::POA_var KeyWaiter::getPOA() const
+{
+ return getDSS()->getPOA4KeyWaiter();
+}
+
+/*!
+ * WARNING : here it is the single method that can be invoked in non SINGLE_THREAD POA.
+ * So take care to do avoid collapses (especially in python).
+ */
+SALOME::ByteVec *KeyWaiter::waitFor()
+{
+ sem_wait(&_sem);
+ if(!_ze_value)
+ throw Exception("KeyWaiter::waitFor : internal error 1 !");
+ SALOME::ByteVec *ret(0);
+ {// this section is to guarantee that no concurrent threads are doing python stuff at the same time
+ // Here a pickelization is needed so to guarantee to be alone doing python action the idea is to invoke using monothread POA.
+ DataScopeServerTransaction *dss(getDSS());
+ PortableServer::POA_var poa(dss->getPOA());
+ CORBA::Object_var dssPtr(poa->servant_to_reference(dss));
+ SALOME::DataScopeServerTransaction_var dssPtr2(SALOME::DataScopeServerTransaction::_narrow(dssPtr));
+ if(CORBA::is_nil(dssPtr2))
+ throw Exception("KeyWaiter::waitFor : internal error 2 !");
+ CORBA::Object_var thisPtr(getPOA()->servant_to_reference(this));
+ SALOME::KeyWaiter_var thisPtr2(SALOME::KeyWaiter::_narrow(thisPtr));
+ if(CORBA::is_nil(thisPtr2))
+ throw Exception("KeyWaiter::waitFor : internal error 3 !");
+ ret=dssPtr2->waitForMonoThrRev(thisPtr2);//<- this invokation through SINGLE_THREAD POA here will guarantee thread safety
+ }
+ enforcedRelease();
+ return ret;
+}
+
+/*!
+ * this method is supposed to be performed in alone.
+ */
+SALOME::ByteVec *KeyWaiter::waitForMonoThr()
+{
+ if(!_ze_value)
+ throw Exception("KeyWaiter::waitForMonoThr : no value ! invalid call of this method !");
+ 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==val)
+ return ;
+ if(_ze_value)
+ Py_XDECREF(_ze_value);
+ _ze_value=val;
+ Py_XINCREF(_ze_value);
+}
+
+void KeyWaiter::go()
+{
+ if(sem_post(&_sem)!=0)
+ {
+ std::ostringstream oss; oss << "KeyWaiter::go : error on post of semaphore ! ";
+ throw Exception(oss.str());
+ }
+}
--- /dev/null
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOMESDS_KEYWAITER_HXX__
+#define __SALOMESDS_KEYWAITER_HXX__
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOME_SDS)
+
+#include "SALOMESDS_Defines.hxx"
+#include "SALOMESDS_AutoRefCountPtr.hxx"
+#include "SALOMESDS_DataScopeServer.hxx"
+#include "SALOMESDS_PickelizedPyObjServer.hxx"
+
+#include <Python.h>
+
+#include <semaphore.h>
+
+namespace SALOMESDS
+{
+ class DataScopeServerTransaction;
+
+ class SALOMESDS_EXPORT KeyWaiter : public virtual POA_SALOME::KeyWaiter, public POAHolder
+ {
+ public:
+ 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();
+ SALOME::ByteVec *waitForMonoThr();
+ private:
+ DataScopeServerTransaction *getDSS() const { return static_cast<DataScopeServerTransaction *>(_var->getFather()); }//thanks to dynamic_cast in constructor
+ private:
+ PickelizedPyObjServer *_var;
+ PyObject *_ze_key;
+ PyObject *_ze_value;
+ sem_t _sem;
+ };
+}
+
+#endif
using namespace SALOMESDS;
-PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
+PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
{
}
//! obj is consumed
-PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServer *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
+PickelizedPyObjRdExtServer::PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
{
}
class PickelizedPyObjRdExtServer : public PickelizedPyObjServer, public virtual POA_SALOME::PickelizedPyObjRdExtServer
{
public:
- PickelizedPyObjRdExtServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value);
- PickelizedPyObjRdExtServer(DataScopeServer *father, const std::string& varName, PyObject *obj);
+ PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
+ PickelizedPyObjRdExtServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
~PickelizedPyObjRdExtServer();
SALOME::PickelizedPyObjRdExtServer_ptr invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
private:
using namespace SALOMESDS;
-PickelizedPyObjRdOnlyServer::PickelizedPyObjRdOnlyServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
+PickelizedPyObjRdOnlyServer::PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
{
}
-PickelizedPyObjRdOnlyServer::PickelizedPyObjRdOnlyServer(DataScopeServer *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
+PickelizedPyObjRdOnlyServer::PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
{
}
class PickelizedPyObjRdOnlyServer : public PickelizedPyObjServer, public virtual POA_SALOME::PickelizedPyObjRdOnlyServer
{
public:
- PickelizedPyObjRdOnlyServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value);
- PickelizedPyObjRdOnlyServer(DataScopeServer *father, const std::string& varName, PyObject *obj);
+ PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
+ PickelizedPyObjRdOnlyServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
~PickelizedPyObjRdOnlyServer();
};
}
using namespace SALOMESDS;
-PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServer *father, const std::string& typeName, const std::string& varName):PickelizedPyObjServer(father,varName,CreateDftObjFromType(father->getGlobals(),typeName))
+PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& typeName, const std::string& varName):PickelizedPyObjServer(father,varName,CreateDftObjFromType(father->getGlobals(),typeName))
{
}
-PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
+PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):PickelizedPyObjServer(father,varName,value)
{
}
//! obj is consumed
-PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServer *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
+PickelizedPyObjRdWrServer::PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):PickelizedPyObjServer(father,varName,obj)
{
}
class PickelizedPyObjRdWrServer : public PickelizedPyObjServer, public virtual POA_SALOME::PickelizedPyObjRdWrServer
{
public:
- PickelizedPyObjRdWrServer(DataScopeServer *father, const std::string& typeName, const std::string& varName);
- PickelizedPyObjRdWrServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value);
- PickelizedPyObjRdWrServer(DataScopeServer *father, const std::string& varName, PyObject *obj);
+ PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& typeName, const std::string& varName);
+ PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
+ PickelizedPyObjRdWrServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
~PickelizedPyObjRdWrServer();
void setSerializedContent(const SALOME::ByteVec& newValue);
SALOME::PickelizedPyObjRdWrServer_ptr invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
using namespace SALOMESDS;
-PickelizedPyObjServer::PickelizedPyObjServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value):BasicDataServer(father,varName),_self(0)
+PickelizedPyObjServer::PickelizedPyObjServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value):BasicDataServer(father,varName),_self(0)
{
setSerializedContentInternal(value);
}
//! obj is consumed
-PickelizedPyObjServer::PickelizedPyObjServer(DataScopeServer *father, const std::string& varName, PyObject *obj):BasicDataServer(father,varName),_self(0)
+PickelizedPyObjServer::PickelizedPyObjServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj):BasicDataServer(father,varName),_self(0)
{
setNewPyObj(obj);
}
return FromCppToByteSeq(pickelize(_self));
}
+bool PickelizedPyObjServer::isDict()
+{
+ if(PyDict_Check(_self))
+ return true;
+ else
+ return false;
+}
+
+void PickelizedPyObjServer::checkKeyNotAlreadyPresent(PyObject *key)
+{
+ checkKeyPresence(key,false);
+}
+
+void PickelizedPyObjServer::checkKeyPresent(PyObject *key)
+{
+ checkKeyPresence(key,true);
+}
+
+void PickelizedPyObjServer::addKeyValueHard(PyObject *key, PyObject *value)
+{
+ bool isOK(PyDict_SetItem(_self,key,value)==0);
+ if(!isOK)
+ throw Exception("PickelizedPyObjServer::addKeyValueHard : error when trying to add key,value to dict !");
+}
+
+void PickelizedPyObjServer::addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value)
+{
+ checkKeyNotAlreadyPresent(key);
+ bool isOK(PyDict_SetItem(_self,key,value)==0);
+ if(!isOK)
+ throw Exception("PickelizedPyObjServer::addKeyValueErrorIfAlreadyExisting : error when trying to add key,value to dict !");
+}
+
+void PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key)
+{
+ checkKeyPresent(key);
+ if(PyDict_DelItem(_self,key)!=0)
+ throw Exception("PickelizedPyObjServer::removeKeyInVarErrorIfNotAlreadyExisting : error during deletion of key in dict !");
+}
+
void PickelizedPyObjServer::FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret)
{
std::size_t sz(bsToBeConv.length());
}
//! New reference returned
-PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::string& pickledData)
+PyObject *PickelizedPyObjServer::GetPyObjFromPickled(const std::string& pickledData, DataScopeServerBase *dsb)
{
std::size_t sz(pickledData.size());
PyObject *pickledDataPy(PyString_FromStringAndSize(NULL,sz));// agy : do not use PyString_FromString because std::string hides a vector of byte.
char *buf(PyString_AsString(pickledDataPy));// this buf can be used thanks to python documentation.
const char *inBuf(pickledData.c_str());
std::copy(inBuf,inBuf+sz,buf);
- PyObject *selfMeth(PyObject_GetAttrString(_father->getPickler(),"loads"));
+ PyObject *selfMeth(PyObject_GetAttrString(dsb->getPickler(),"loads"));
+ PyObject *args(PyTuple_New(1)); PyTuple_SetItem(args,0,pickledDataPy);
+ PyObject *ret(PyObject_CallObject(selfMeth,args));
+ Py_XDECREF(args);
+ Py_XDECREF(selfMeth);
+ return ret;
+}
+
+//! New reference returned
+PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::string& pickledData)
+{
+ return GetPyObjFromPickled(pickledData,_father);
+}
+
+//! New reference returned
+PyObject *PickelizedPyObjServer::GetPyObjFromPickled(const std::vector<unsigned char>& pickledData, DataScopeServerBase *dsb)
+{
+ std::size_t sz(pickledData.size());
+ PyObject *pickledDataPy(PyString_FromStringAndSize(NULL,sz));// agy : do not use PyString_FromString because std::string hides a vector of byte.
+ char *buf(PyString_AsString(pickledDataPy));// this buf can be used thanks to python documentation.
+ const unsigned char *inBuf(&pickledData[0]);
+ std::copy(inBuf,inBuf+sz,buf);
+ PyObject *selfMeth(PyObject_GetAttrString(dsb->getPickler(),"loads"));
PyObject *args(PyTuple_New(1)); PyTuple_SetItem(args,0,pickledDataPy);
PyObject *ret(PyObject_CallObject(selfMeth,args));
Py_XDECREF(args);
return ret;
}
+//! New reference returned
+PyObject *PickelizedPyObjServer::getPyObjFromPickled(const std::vector<unsigned char>& pickledData)
+{
+ return GetPyObjFromPickled(pickledData,_father);
+}
+
//! obj is consumed by this method.
-std::string PickelizedPyObjServer::pickelize(PyObject *obj)
+std::string PickelizedPyObjServer::Pickelize(PyObject *obj, DataScopeServerBase *dsb)
{
PyObject *args(PyTuple_New(2));
PyTuple_SetItem(args,0,obj);
PyTuple_SetItem(args,1,PyInt_FromLong(2));// because "assert(cPickle.HIGHEST_PROTOCOL is 2)"
- PyObject *selfMeth(PyObject_GetAttrString(_father->getPickler(),"dumps"));
+ PyObject *selfMeth(PyObject_GetAttrString(dsb->getPickler(),"dumps"));
PyObject *retPy(PyObject_CallObject(selfMeth,args));
Py_XDECREF(selfMeth);
Py_XDECREF(args);
return ret;
}
+//! obj is consumed by this method.
+std::string PickelizedPyObjServer::pickelize(PyObject *obj)
+{
+ return Pickelize(obj,_father);
+}
+
//! obj is consumed by this method.
void PickelizedPyObjServer::setNewPyObj(PyObject *obj)
{
Py_XDECREF(args);
return ret;
}
+
+void PickelizedPyObjServer::checkKeyPresence(PyObject *key, bool presence)
+{
+ if(!isDict())
+ throw Exception("PickelizedPyObjServer::checkKeyPresence : not a dict !");
+ PyObject *selfMeth(PyObject_GetAttrString(_self,"__contains__"));//new ref
+ PyObject *args(PyTuple_New(1));
+ PyTuple_SetItem(args,0,key); Py_XINCREF(key);// key is stolen by PyTuple_SetItem
+ PyObject *retPy(PyObject_CallObject(selfMeth,args));
+ Py_XDECREF(args);
+ Py_XDECREF(selfMeth);
+ //
+ if(retPy!=Py_False && retPy!=Py_True)
+ throw Exception("PickelizedPyObjServer::checkKeyPresence : unexpected return of dict.__contains__ !");
+ if(!presence)
+ {
+ if(retPy==Py_True)
+ throw Exception("PickelizedPyObjServer::checkKeyPresence : key is already present and it should not !");
+ }
+ else
+ {
+ if(retPy==Py_False)
+ throw Exception("PickelizedPyObjServer::checkKeyPresence : key is not present and it should !");
+ }
+ Py_XDECREF(retPy);
+}
#include "SALOMESDS_BasicDataServer.hxx"
+#include <vector>
+
namespace SALOMESDS
{
class PickelizedPyObjServer : public BasicDataServer, public virtual POA_SALOME::PickelizedPyObjServer
{
public:
- PickelizedPyObjServer(DataScopeServer *father, const std::string& varName, const SALOME::ByteVec& value);
- PickelizedPyObjServer(DataScopeServer *father, const std::string& varName, PyObject *obj);
+ PickelizedPyObjServer(DataScopeServerBase *father, const std::string& varName, const SALOME::ByteVec& value);
+ PickelizedPyObjServer(DataScopeServerBase *father, const std::string& varName, PyObject *obj);
~PickelizedPyObjServer();
void setSerializedContent(const SALOME::ByteVec& newValue);
SALOME::ByteVec *fetchSerializedContent();
- protected:
+ public:
+ bool isDict();
+ void checkKeyNotAlreadyPresent(PyObject *key);
+ void checkKeyPresent(PyObject *key);
+ void addKeyValueHard(PyObject *key, PyObject *value);
+ void addKeyValueErrorIfAlreadyExisting(PyObject *key, PyObject *value);
+ void removeKeyInVarErrorIfNotAlreadyExisting(PyObject *key);
+ PyObject *getPyObj() const { return _self; }
+ public:
static void FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret);
static SALOME::ByteVec *FromCppToByteSeq(const std::string& strToBeConv);
+ static PyObject *GetPyObjFromPickled(const std::string& pickledData, DataScopeServerBase *dsb);
+ static PyObject *GetPyObjFromPickled(const std::vector<unsigned char>& pickledData, DataScopeServerBase *dsb);
+ static std::string Pickelize(PyObject *obj, DataScopeServerBase *dsb);
PyObject *getPyObjFromPickled(const std::string& pickledData);
+ PyObject *getPyObjFromPickled(const std::vector<unsigned char>& pickledData);
std::string pickelize(PyObject *obj);
void setNewPyObj(PyObject *obj);
void setSerializedContentInternal(const SALOME::ByteVec& newValue);
static PyObject *CreateDftObjFromType(PyObject *globals, const std::string& typeName);
+ private:
+ void checkKeyPresence(PyObject *key, bool presence);
protected:
static const char FAKE_VAR_NAME_FOR_WORK[];
PyObject *_self;
return ret;
}
-void RefCountServ::enforcedRelease()
-{
- PortableServer::POA_var poa(getPOA());
- PortableServer::ObjectId_var oid(poa->servant_to_id(this));
- poa->deactivate_object(oid);
- _remove_ref();
-}
-
RefCountServ::RefCountServ():_cnt(1)
{
}
#ifndef __SALOMESDS_REFCOUNTSERV_HXX__
#define __SALOMESDS_REFCOUNTSERV_HXX__
-#include <omniORB4/CORBA.h>
+#include "SALOMESDS_AutoRefCountPtr.hxx"
namespace SALOMESDS
{
- class RefCountServ : public virtual PortableServer::ServantBase
+ class RefCountServ : public virtual PortableServer::ServantBase, public POAHolder
{
public:
void incrRef() const;
bool decrRef() const;
- virtual PortableServer::POA_var getPOA() = 0;
protected:
- void enforcedRelease();
RefCountServ();
RefCountServ(const RefCountServ& other);
virtual ~RefCountServ();
--- /dev/null
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "SALOMESDS_Transaction.hxx"
+#include "SALOMESDS_Exception.hxx"
+#include "SALOMESDS_PickelizedPyObjServer.hxx"
+
+#include <sstream>
+
+using namespace SALOMESDS;
+
+void Transaction::FromByteSeqToVB(const SALOME::ByteVec& bsToBeConv, std::vector<unsigned char>& ret)
+{
+ std::size_t sz(bsToBeConv.length());
+ ret.resize(sz);
+ unsigned char *buf(const_cast<unsigned char *>(&ret[0]));
+ for(std::size_t i=0;i<sz;i++)
+ buf[i]=bsToBeConv[i];
+}
+
+void Transaction::FromVBToByteSeq(const std::vector<unsigned char>& bsToBeConv, SALOME::ByteVec& ret)
+{
+ std::size_t sz(bsToBeConv.size());
+ ret.length(sz);
+ for(std::size_t i=0;i<sz;i++)
+ ret[i]=bsToBeConv[i];
+}
+
+Transaction::~Transaction()
+{
+}
+
+TransactionVarCreate::TransactionVarCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue):Transaction(dsct,varName)
+{
+ FromByteSeqToVB(constValue,_data);
+}
+
+void TransactionVarCreate::prepareRollBackInCaseOfFailure()
+{//nothing it is not a bug
+ checkNotAlreadyExisting();
+}
+
+void TransactionVarCreate::rollBack()
+{
+ if(_dsct->existVar(_var_name.c_str()))
+ _dsct->deleteVar(_var_name.c_str());
+}
+
+/*!
+ TODO : To be implemented.
+ */
+void TransactionVarCreate::notify()
+{
+}
+
+void TransactionRdOnlyVarCreate::perform()
+{
+ SALOME::ByteVec data2;
+ FromVBToByteSeq(_data,data2);
+ _dsct->createRdOnlyVarInternal(_var_name,data2);
+}
+
+void TransactionRdExtVarCreate::perform()
+{
+ SALOME::ByteVec data2;
+ FromVBToByteSeq(_data,data2);
+ _dsct->createRdExtVarInternal(_var_name,data2);
+}
+
+void TransactionRdWrVarCreate::perform()
+{
+ SALOME::ByteVec data2;
+ FromVBToByteSeq(_data,data2);
+ _dsct->createRdWrVarInternal(_var_name,data2);
+}
+
+TransactionDictModify::TransactionDictModify(DataScopeServerTransaction *dsct, const std::string& varName):Transaction(dsct,varName),_varc(0)
+{
+ _varc=checkVarExistingAndDict();
+}
+
+void TransactionDictModify::prepareRollBackInCaseOfFailure()
+{
+ _zeDataBefore.clear();
+ PyObject *zeDictPy(_varc->getPyObj());
+ Py_XINCREF(zeDictPy);
+ _zeDataBefore=_varc->pickelize(zeDictPy);
+}
+
+void TransactionDictModify::rollBack()
+{
+ PyObject *obj(_varc->getPyObjFromPickled(_zeDataBefore));
+ _varc->setNewPyObj(obj);
+ _zeDataBefore.clear();
+}
+
+TransactionAddKeyValue::TransactionAddKeyValue(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionDictModify(dsct,varName)
+{
+ std::vector<unsigned char> key2,value2;
+ FromByteSeqToVB(key,key2);
+ FromByteSeqToVB(value,value2);
+ _key=PickelizedPyObjServer::GetPyObjFromPickled(key2,_dsct);
+ _value=PickelizedPyObjServer::GetPyObjFromPickled(value2,_dsct);
+}
+
+void TransactionAddKeyValue::prepareRollBackInCaseOfFailure()
+{
+ TransactionDictModify::prepareRollBackInCaseOfFailure();
+ _dsct->pingKey(_key);// check that key is OK with all waiting keys
+}
+
+void TransactionAddKeyValue::notify()
+{
+ _dsct->notifyKey(_key,_value);
+}
+
+TransactionAddKeyValue::~TransactionAddKeyValue()
+{
+ Py_XDECREF(_key);
+ Py_XDECREF(_value);
+}
+
+TransactionAddKeyValueHard::TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionAddKeyValue(dsct,varName,key,value)
+{
+}
+
+void TransactionAddKeyValueHard::perform()
+{
+ _varc->addKeyValueHard(_key,_value);
+}
+
+TransactionAddKeyValueErrorIfAlreadyExisting::TransactionAddKeyValueErrorIfAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value):TransactionAddKeyValue(dsct,varName,key,value)
+{
+ _varc->checkKeyNotAlreadyPresent(_key);
+}
+
+void TransactionAddKeyValueErrorIfAlreadyExisting::perform()
+{
+ _varc->addKeyValueErrorIfAlreadyExisting(_key,_value);
+}
+
+TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key):TransactionDictModify(dsct,varName),_key(0)
+{
+ std::vector<unsigned char> key2;
+ FromByteSeqToVB(key,key2);
+ _key=PickelizedPyObjServer::GetPyObjFromPickled(key2,_dsct);
+}
+
+void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::perform()
+{
+ _varc->removeKeyInVarErrorIfNotAlreadyExisting(_key);
+}
+
+/*!
+ * not implementation it is not a bug !
+ */
+void TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::notify()
+{
+}
+
+TransactionRemoveKeyInVarErrorIfNotAlreadyExisting::~TransactionRemoveKeyInVarErrorIfNotAlreadyExisting()
+{
+ Py_XDECREF(_key);
+}
--- /dev/null
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#ifndef __SALOMESDS_TRANSACTION_HXX__
+#define __SALOMESDS_TRANSACTION_HXX__
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SALOME_SDS)
+
+#include "SALOMESDS_Defines.hxx"
+#include "SALOMESDS_Exception.hxx"
+#include "SALOMESDS_DataServerManager.hxx"
+
+#include <string>
+#include <vector>
+
+namespace SALOMESDS
+{
+ class PickelizedPyObjServer;
+
+ class SALOMESDS_EXPORT Transaction : public virtual POA_SALOME::Transaction, public POAHolder
+ {
+ public:
+ Transaction(DataScopeServerTransaction *dsct, const std::string& varName):_dsct(dsct),_var_name(varName) { if(!_dsct) throw Exception("Transaction constructor error !"); }
+ std::string getVarName() const { return _var_name; }
+ void checkVarExisting() { _dsct->checkExistingVar(_var_name); }
+ void checkNotAlreadyExisting() { _dsct->checkNotAlreadyExistingVar(_var_name); }
+ PortableServer::POA_var getPOA() const { return _dsct->getPOA(); }
+ virtual void prepareRollBackInCaseOfFailure() = 0;
+ virtual void perform() = 0;
+ virtual void rollBack() = 0;
+ virtual void notify() = 0;
+ virtual ~Transaction();
+ public:
+ static void FromByteSeqToVB(const SALOME::ByteVec& bsToBeConv, std::vector<unsigned char>& ret);
+ static void FromVBToByteSeq(const std::vector<unsigned char>& bsToBeConv, SALOME::ByteVec& ret);
+ protected:
+ DataScopeServerTransaction *_dsct;
+ std::string _var_name;
+ };
+
+ class TransactionVarCreate : public Transaction
+ {
+ public:
+ TransactionVarCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue);
+ void prepareRollBackInCaseOfFailure();
+ void rollBack();
+ void notify();
+ protected:
+ std::vector<unsigned char> _data;
+ };
+
+ class TransactionRdOnlyVarCreate : public TransactionVarCreate
+ {
+ public:
+ TransactionRdOnlyVarCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue):TransactionVarCreate(dsct,varName,constValue) { }
+ void perform();
+ };
+
+ class TransactionRdExtVarCreate : public TransactionVarCreate
+ {
+ public:
+ TransactionRdExtVarCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue):TransactionVarCreate(dsct,varName,constValue) { }
+ void perform();
+ };
+
+ class TransactionRdWrVarCreate : public TransactionVarCreate
+ {
+ public:
+ TransactionRdWrVarCreate(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& constValue):TransactionVarCreate(dsct,varName,constValue) { }
+ void perform();
+ };
+
+ class PickelizedPyObjServer;
+
+ class TransactionDictModify : public Transaction
+ {
+ public:
+ TransactionDictModify(DataScopeServerTransaction *dsct, const std::string& varName);
+ PickelizedPyObjServer *checkVarExistingAndDict() { return _dsct->checkVarExistingAndDict(_var_name); }
+ void prepareRollBackInCaseOfFailure();
+ void rollBack();
+ protected:
+ std::string _zeDataBefore;
+ PickelizedPyObjServer *_varc;
+ };
+
+ class TransactionAddKeyValue : public TransactionDictModify
+ {
+ public:
+ TransactionAddKeyValue(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+ void prepareRollBackInCaseOfFailure();
+ void notify();
+ ~TransactionAddKeyValue();
+ protected:
+ PyObject *_key;
+ PyObject *_value;
+ };
+
+ class TransactionAddKeyValueHard : public TransactionAddKeyValue
+ {
+ public:
+ TransactionAddKeyValueHard(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+ void perform();
+ };
+
+ class TransactionAddKeyValueErrorIfAlreadyExisting : public TransactionAddKeyValue
+ {
+ public:
+ TransactionAddKeyValueErrorIfAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key, const SALOME::ByteVec& value);
+ void perform();
+ };
+
+ class TransactionRemoveKeyInVarErrorIfNotAlreadyExisting : public TransactionDictModify
+ {
+ public:
+ TransactionRemoveKeyInVarErrorIfNotAlreadyExisting(DataScopeServerTransaction *dsct, const std::string& varName, const SALOME::ByteVec& key);
+ void perform();
+ void notify();
+ ~TransactionRemoveKeyInVarErrorIfNotAlreadyExisting();
+ private:
+ PyObject *_key;
+ };
+}
+
+#endif
if(argc<=1)
throw SALOMESDS::Exception("In the main of SALOME_DataScopeServer.cxx !");
scopeName=argv[1];
+ std::istringstream isTransacSS(argv[2]);
+ int isTransac(0);
+ isTransacSS >> isTransac;
CORBA::ORB_var orb(CORBA::ORB_init(argc,argv));
CORBA::Object_var obj(orb->resolve_initial_references("RootPOA"));
PortableServer::POA_var poa(PortableServer::POA::_narrow(obj));
PortableServer::POAManager_var mgr(poa->the_POAManager());
mgr->activate();
- SALOMESDS::DataScopeServer *server(new SALOMESDS::DataScopeServer(orb,scopeName));
+ SALOMESDS::DataScopeServerBase *server(0);
+ if(!isTransac)
+ server=new SALOMESDS::DataScopeServer(orb,scopeName);
+ else
+ server=new SALOMESDS::DataScopeServerTransaction(orb,scopeName);
//
CORBA::PolicyList policies;
policies.length(1);
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);
- SALOME::DataScopeServer_var serverPtr(SALOME::DataScopeServer::_narrow(obj));
- server->setPOAAndRegister(poa2,serverPtr);
+ //
+ server->setPOA(poa2);
+ obj=server->activate();
+ SALOME::DataScopeServerBase_var serverPtr(SALOME::DataScopeServerBase::_narrow(obj));
+ server->registerInNS(serverPtr);
//
orb->run();
server->_remove_ref();
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Anthony Geay
+
+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 TestSalomeSDSHelper0
+ import os,subprocess
+ fname=os.path.splitext(TestSalomeSDSHelper0.__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 SalomeSDSTest(unittest.TestCase):
+
+ def testList1(self):
+ a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
+ self.assertEqual(a.local_copy(),[])
+ a.append(5)
+ self.assertEqual(a.local_copy(),[5])
+ self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
+ a.append(["rt"])
+ self.assertEqual(a.local_copy(),[5,["rt"]])
+ a[1].append(8)
+ self.assertEqual(a.local_copy(),[5,["rt",8]])
+ a.extend(a)
+ self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
+ a.extend(a[3:])
+ self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
+ a[4].append(7)
+ self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
+ a.ptr().getMyDataScopeServer().deleteVar("a")
+ pass
+
+ def testDict1(self):
+ a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
+ a["ab"]=4
+ self.assertEqual(a.local_copy(),{"ab":4})
+ a["cd"]=[5]
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
+ a["cd"].append(77)
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
+ a.__setitem__("ef",["a","bb"])
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
+ self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb"])
+ self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb","ccc"])
+ a["ef"].append("ccc")
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
+ a["gh"]=a
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
+ a["gh"]["cd"].append(99) ; a["cd"].append(88)
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77,99],"ef":["a","bb","ccc"]}})
+ a.ptr().getMyDataScopeServer().deleteVar("a")
+ pass
+
+ def testReadOnly1(self):
+ a=SalomeSDSClt.CreateRdOnlyGlobalVar({"ab":4,"cd":[5,77]},"a","Scope0")
+ self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
+ 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)
+ self.assertTrue(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])
+ #
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
+ wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
+ self.assertEqual(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)])
+ self.assertEqual(asyncResult.get(),nbProc*[0]) # <- the big test is here !
+ dsm.removeDataScope(scopeName)
+
+ def testTransaction2(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)
+ self.assertTrue(isCreated)
+ #
+ t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
+ dss.atomicApply([t0])
+ #
+ self.assertRaises(SALOME.SALOME_Exception,dss.addKeyValueInVarErrorIfAlreadyExisting,varName,obj2Str("ab"),obj2Str([7,8,9,10]))#raises because ab is already a key !
+ t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
+ dss.atomicApply([t1])
+ #
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
+ wk=dss.waitForKeyInVar(varName,obj2Str("cd"))
+ self.assertEqual(str2Obj(wk.waitFor()),[7,8,9,10])
+
+ def testTransaction3(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)
+ self.assertTrue(isCreated)
+ #
+ t0=dss.createRdExtVarTransac(varName,obj2Str({"ab":[4,5,6]}))
+ dss.atomicApply([t0])
+ #
+ t1=dss.addKeyValueInVarErrorIfAlreadyExisting(varName,obj2Str("cd"),obj2Str([7,8,9,10]))
+ dss.atomicApply([t1])
+ #
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
+ #
+ t2=dss.removeKeyInVarErrorIfNotAlreadyExisting(varName,obj2Str("ab"))
+ dss.atomicApply([t2])
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'cd':[7,8,9,10]})
+
+ def testTransaction4(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)
+ self.assertTrue(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])
+ #
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
+ wk,t2=dss.waitForKeyInVarAndKillIt(varName,obj2Str("cd"))
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6],'cd':[7,8,9,10]})
+ self.assertEqual(str2Obj(wk.waitFor()),[7,8,9,10])
+ dss.atomicApply([t2])
+ self.assertEqual(str2Obj(dss.fetchSerializedContent(varName)),{'ab':[4,5,6]})
+
+ def setUp(self):
+ salome.salome_init()
+ pass
+
+ pass
+
+unittest.main()
+
import gc
import SalomeSDSClt
+salome.salome_init()
st="jjj"
dsm=salome.naming_service.Resolve("/DataServerManager")
assert(dsm.isAliveAndKicking("Default"))
+++ /dev/null
-# -*- coding: utf-8 -*-
-# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-# Author : Anthony Geay
-
-import SalomeSDSClt
-import SALOME
-import salome
-import unittest
-import gc
-
-class SalomeSDS2Test(unittest.TestCase):
-
- def testList1(self):
- a=SalomeSDSClt.CreateRdExtGlobalVar([],"a","Scope0")
- self.assertEqual(a.local_copy(),[])
- a.append(5)
- self.assertEqual(a.local_copy(),[5])
- self.assertRaises(SALOME.SALOME_Exception,a.__delitem__,0)
- a.append(["rt"])
- self.assertEqual(a.local_copy(),[5,["rt"]])
- a[1].append(8)
- self.assertEqual(a.local_copy(),[5,["rt",8]])
- a.extend(a)
- self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8]])
- a.extend(a[3:])
- self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8]])
- a[4].append(7)
- self.assertEqual(a.local_copy(),[5,["rt",8],5,["rt",8],["rt",8,7]])
- a.ptr().getMyDataScopeServer().deleteVar("a")
- pass
-
- def testDict1(self):
- a=SalomeSDSClt.CreateRdExtGlobalVar({},"a","Scope0")
- a["ab"]=4
- self.assertEqual(a.local_copy(),{"ab":4})
- a["cd"]=[5]
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5]})
- a["cd"].append(77)
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
- a.__setitem__("ef",["a","bb"])
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb"]})
- self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb"])
- self.assertRaises(SALOME.SALOME_Exception,a.__setitem__,"ef",["a","bb","ccc"])
- a["ef"].append("ccc")
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]})
- a["gh"]=a
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77],"ef":["a","bb","ccc"]}})
- a["gh"]["cd"].append(99) ; a["cd"].append(88)
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77,88],"ef":["a","bb","ccc"],"gh":{"ab":4,"cd":[5,77,99],"ef":["a","bb","ccc"]}})
- a.ptr().getMyDataScopeServer().deleteVar("a")
- pass
-
- def testReadOnly1(self):
- a=SalomeSDSClt.CreateRdOnlyGlobalVar({"ab":4,"cd":[5,77]},"a","Scope0")
- self.assertEqual(a.local_copy(),{"ab":4,"cd":[5,77]})
- self.assertRaises(Exception,a.__getitem__,"ab")
- a.ptr().getMyDataScopeServer().deleteVar("a")
-
- def setUp(self):
- salome.salome_init()
- pass
-
- pass
-
-unittest.main()
-
--- /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()))