//
// Author : Anthony GEAY (EDF R&D)
+#include "SALOME_GenericObj.idl"
+
module SALOME
{
typedef sequence<string> StringVec;
typedef sequence<octet> ByteVec;
- interface BasicDataServer
+ interface BasicDataServer : GenericObj
{
string getVarName();
+ string getScopeName();
void setReadOnlyStatus();
void setRWStatus();
};
- /*interface PythonDataServer : BasicDataServer
- {
- };*/
-
interface StringDataServer : BasicDataServer
{
void setSerializedContent(in ByteVec newValue);
ByteVec fetchSerializedContent();
- ByteVec invokePythonMethodOn(in string method, in ByteVec args);
+ StringDataServer invokePythonMethodOn(in string method, in ByteVec args);
};
interface DataServerManager;
StringVec listVars();
BasicDataServer retrieveVar(in string varName);
StringDataServer createGlobalStringVar(in string varName);
+ StringDataServer createGlobalTmpVar(in ByteVec newValue);
void shutdownIfNotHostedByDSM();
};
import SALOME
import cPickle
-class SALOMEGlobalVarMethodHelper:
- def __init__(self,varPtr,meth):
+class SALOMEGlobalVarHelper:
+ def __init__(self,varPtr,isTemporaryVar=False):
assert(isinstance(varPtr,SALOME._objref_StringDataServer))
self._var_ptr=varPtr
- self._meth=meth
+ if not isTemporaryVar:
+ self._var_ptr.Register()
+ self._is_temp=isTemporaryVar
pass
- def __call__(self,*args):
- #print "__call__ %s : %s"%(self._meth,str(args))
- ret=self._var_ptr.invokePythonMethodOn(self._meth,cPickle.dumps(args,cPickle.HIGHEST_PROTOCOL))
- return cPickle.loads(ret)
- pass
-
-class SALOMEGlobalVarHelper:
- def __init__(self,varPtr):
- assert(isinstance(varPtr,SALOME._objref_StringDataServer))
- self._var_ptr=varPtr
+ def __del__(self):
+ self._var_ptr.UnRegister()
pass
def assign(self,elt):
self._var_ptr.setSerializedContent(st)
pass
- def __getattr__(self,*args):
- #print "__getattr__,%s"%(str(args))
- return SALOMEGlobalVarMethodHelper(self._var_ptr,args[0])
+ def __getattr__(self,meth):
+ #print "__getattr__,%s"%(meth)
+ return SALOMEGlobalVarMethodHelper(self._var_ptr,meth)
def __str__(self):
return self.local_copy().__str__()
def local_copy(self):
return cPickle.loads(self._var_ptr.fetchSerializedContent())
pass
+
+class SALOMEGlobalVarMethodHelper:
+ def __init__(self,varPtr,meth):
+ assert(isinstance(varPtr,SALOME._objref_StringDataServer))
+ self._var_ptr=varPtr
+ self._var_ptr.Register()
+ self._meth=meth
+ pass
+
+ def __call__(self,*args):
+ #print "__call__ %s : %s"%(self._meth,str(args))
+ ret=self._var_ptr.invokePythonMethodOn(self._meth,cPickle.dumps(args,cPickle.HIGHEST_PROTOCOL))
+ ret=SALOMEGlobalVarHelper(ret,True)
+ if self._meth not in ["__len__","__coerce__"]:
+ return ret
+ else:
+ return ret.local_copy()
+
+ def __del__(self):
+ self._var_ptr.UnRegister()
+ pass
+ pass
// Author : Anthony GEAY (EDF R&D)
#include "SALOMESDS_BasicDataServer.hxx"
+#include "SALOMESDS_DataScopeServer.hxx"
#include "SALOMESDS_Exception.hxx"
#include <sstream>
return CORBA::string_dup(_var_name.c_str());
}
+char *BasicDataServer::getScopeName()
+{
+ return _father->getScopeName();
+}
+
/*!
* Called remotely -> to protect against throw
*/
_is_read_only=false;
}
+void BasicDataServer::Register()
+{
+ incrRef();
+}
+
+void BasicDataServer::UnRegister()
+{
+ decrRef();
+}
+
+void BasicDataServer::Destroy()
+{
+ enforcedRelease();
+}
+
void BasicDataServer::checkReadOnlyStatusRegardingConstness(const char *sender) const
{
if(isReadOnly())
public:
BasicDataServer(DataScopeServer *father, const std::string& varName);
char *getVarName();
+ char *getScopeName();
void setReadOnlyStatus();
void setRWStatus();
+ public:
+ void Register();
+ void UnRegister();
+ void Destroy();
+ public:
std::string getVarNameCpp() const { return _var_name; }
protected:
void checkReadOnlyStatusRegardingConstness(const char *sender) const;
using namespace SALOMESDS;
+std::size_t DataScopeServer::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)
{
}
return SALOME::StringDataServer::_narrow(ret);
}
+/*!
+ * Called remotely -> to protect against throw
+ */
+SALOME::StringDataServer_ptr DataScopeServer::createGlobalTmpVar(const SALOME::ByteVec& newValue)
+{
+ static const char TMP_VAR_NAME[]="TmP";
+ std::string vn(BuildTmpVarNameFrom(TMP_VAR_NAME));
+ StringDataServer *retCpp(new StringDataServer(this,vn));
+ retCpp->setPOA(_poa);
+ retCpp->setSerializedContent(newValue);
+ //
+ PortableServer::ObjectId_var id(_poa->activate_object(retCpp));
+ CORBA::Object_var ret(_poa->id_to_reference(id));
+ return SALOME::StringDataServer::_narrow(ret);
+}
+
void DataScopeServer::shutdownIfNotHostedByDSM()
{
SALOME_NamingService ns(_orb);
_locals=PyDict_New();
PyObject *tmp(PyList_New(0));
_pickler=PyImport_ImportModuleLevel(const_cast<char *>("cPickle"),_globals,_locals,tmp,-1);
- //Py_XDECREF(tmp);
- //if(PyRun_String("import cPickle\n",Py_single_input,_globals,_locals)!=0)
- // throw Exception("DataScopeServer::setPOAAndRegister : cPickle is not available !");
- /*_pickler=PyDict_GetItemString(_globals,"cPickle");*/
}
/*!
ns.Register(ptr,fullScopeName.c_str());
}
+std::string DataScopeServer::BuildTmpVarNameFrom(const std::string& varName)
+{
+ std::ostringstream oss;
+ oss << varName << "@" << COUNTER++;
+ return oss.str();
+}
+
std::vector< std::string > DataScopeServer::getAllVarNames() const
{
std::size_t sz(_vars.size());
SALOME::StringVec *listVars();
SALOME::BasicDataServer_ptr retrieveVar(const char *varName);
SALOME::StringDataServer_ptr createGlobalStringVar(const char *varName);
+ SALOME::StringDataServer_ptr createGlobalTmpVar(const SALOME::ByteVec& newValue);
void shutdownIfNotHostedByDSM();
~DataScopeServer();
public:
PyObject *getGlobals() const { return _globals; }
PyObject *getLocals() const { return _locals; }
PyObject *getPickler() const { return _pickler; }
+ PortableServer::POA_var getPOA() { return _poa; }
+ static std::string BuildTmpVarNameFrom(const std::string& varName);
private:
std::vector< std::string> getAllVarNames() const;
CORBA::Object_var activateWithDedicatedPOA(BasicDataServer *ds);
CORBA::ORB_var _orb;
std::string _name;
std::list< std::pair< SALOME::BasicDataServer_var, AutoRefCountPtr<BasicDataServer> > > _vars;
+ static std::size_t COUNTER;
};
}
bool ret((--_cnt)==0);
if(ret)
{
- PortableServer::ObjectId_var oid = (const_cast<RefCountServ *>(this))->_default_POA()->servant_to_id(const_cast<RefCountServ *>(this));
- (const_cast<RefCountServ *>(this))->_default_POA()->deactivate_object(oid);
- (const_cast<RefCountServ *>(this))->_remove_ref();
+ RefCountServ *thisNC(const_cast<RefCountServ *>(this));
+ thisNC->enforcedRelease();
}
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)
{
}
public:
void incrRef() const;
bool decrRef() const;
+ virtual PortableServer::POA_var getPOA() = 0;
protected:
+ void enforcedRelease();
RefCountServ();
RefCountServ(const RefCountServ& other);
virtual ~RefCountServ();
#include "SALOMESDS_DataScopeServer.hxx"
#include "SALOMESDS_Exception.hxx"
+#include <iostream>
#include <sstream>
using namespace SALOMESDS;
-StringDataServer::StringDataServer(DataScopeServer *father, const std::string& varName):BasicDataServer(father,varName)
+StringDataServer::StringDataServer(DataScopeServer *father, const std::string& varName):BasicDataServer(father,varName),_self(Py_None)
+{
+ Py_XINCREF(Py_None);
+}
+
+//! obj is consumed
+StringDataServer::StringDataServer(DataScopeServer *father, const std::string& varName, PyObject *obj):BasicDataServer(father,varName),_self(obj)
{
}
StringDataServer::~StringDataServer()
{
+ std::cerr << "~~~~~~~~~~ StringDataServer : " << getVarNameCpp() << std::endl;
+ Py_XDECREF(_self);
}
/*!
void StringDataServer::setSerializedContent(const SALOME::ByteVec& newValue)
{
checkReadOnlyStatusRegardingConstness("StringDataServer::setSerializedContent : read only var !");
- FromByteSeqToCpp(newValue,_data);
+ std::string data;
+ FromByteSeqToCpp(newValue,data);
+ setNewPyObj(getPyObjFromPickled(data));
}
/*!
*/
SALOME::ByteVec *StringDataServer::fetchSerializedContent()
{
- return FromCppToByteSeq(_data);
+ Py_XINCREF(_self);//because pickelize consume _self
+ return FromCppToByteSeq(pickelize(_self));
}
/*!
* Called remotely -> to protect against throw
*/
-SALOME::ByteVec *StringDataServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
+SALOME::StringDataServer_ptr StringDataServer::invokePythonMethodOn(const char *method, const SALOME::ByteVec& args)
{
- PyObject *self(getPyObjFromPickled(_data));
+ if(!_self)
+ throw Exception("StringDataServer::invokePythonMethodOn : self is NULL !");
std::string argsCpp;
FromByteSeqToCpp(args,argsCpp);
PyObject *argsPy(getPyObjFromPickled(argsCpp));
//
- PyObject *selfMeth(PyObject_GetAttrString(self,method));
+ PyObject *selfMeth(PyObject_GetAttrString(_self,method));
if(!selfMeth)
{
std::ostringstream oss; oss << "StringDataServer::invokePythonMethodOn : Method \"" << method << "\" is not available !";
throw Exception(oss.str());
}
- PyObject *res(PyObject_CallObject(selfMeth,argsPy));
+ PyObject *res(PyObject_CallObject(selfMeth,argsPy));// self can have been modified by this call !
+ Py_XDECREF(selfMeth);
+ Py_XDECREF(argsPy);
if(!res)
{
std::ostringstream oss; oss << "StringDataServer::invokePythonMethodOn : Problem during invokation serverside of Method \"" << method << "\" !";
throw Exception(oss.str());
}
- _data=pickelize(self);// if it is a non const method !
- std::string retCpp(pickelize(res));
- // to test : res and self
- Py_XDECREF(selfMeth);
- //
- Py_XDECREF(argsPy);
- return FromCppToByteSeq(retCpp);
+ StringDataServer *ret(new StringDataServer(_father,DataScopeServer::BuildTmpVarNameFrom(getVarNameCpp()),res));
+ PortableServer::POA_var poa(_father->getPOA());
+ ret->setPOA(poa);
+ PortableServer::ObjectId_var id(poa->activate_object(ret));
+ CORBA::Object_var obj(poa->id_to_reference(id));
+ return SALOME::StringDataServer::_narrow(obj);
+}
+
+PortableServer::POA_var StringDataServer::getPOA()
+{
+ return _poa;
}
void StringDataServer::FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret)
Py_XDECREF(retPy);
return ret;
}
+
+//! obj is consumed by this method.
+void StringDataServer::setNewPyObj(PyObject *obj)
+{
+ if(!obj)
+ throw Exception("StringDataServer::setNewPyObj : trying to assign a NULL pyobject in this !");
+ if(obj==_self)
+ return ;
+ Py_XDECREF(_self);
+ _self=obj;
+}
{
public:
StringDataServer(DataScopeServer *father, const std::string& varName);
+ StringDataServer(DataScopeServer *father, const std::string& varName, PyObject *obj);
~StringDataServer();
void setSerializedContent(const SALOME::ByteVec& newValue);
SALOME::ByteVec *fetchSerializedContent();
- SALOME::ByteVec *invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
+ SALOME::StringDataServer_ptr invokePythonMethodOn(const char *method, const SALOME::ByteVec& args);
+ public:
+ void setPOA(PortableServer::POA_var poa) { _poa=poa; }
private:
+ PortableServer::POA_var getPOA();
static void FromByteSeqToCpp(const SALOME::ByteVec& bsToBeConv, std::string& ret);
static SALOME::ByteVec *FromCppToByteSeq(const std::string& strToBeConv);
PyObject *getPyObjFromPickled(const std::string& pickledData);
std::string pickelize(PyObject *obj);
+ void setNewPyObj(PyObject *obj);
private:
static const char FAKE_VAR_NAME_FOR_WORK[];
- std::string _data;
+ PyObject *_self;
+ PortableServer::POA_var _poa;
};
}